diff --git a/pkg/sql/distsql/base.go b/pkg/sql/distsql/base.go index 54e5fdd1ea8a..7e80fb5872b2 100644 --- a/pkg/sql/distsql/base.go +++ b/pkg/sql/distsql/base.go @@ -29,6 +29,15 @@ import ( opentracing "github.com/opentracing/opentracing-go" ) +type joinType int + +const ( + innerJoin joinType = iota + leftOuter + rightOuter + fullOuter +) + const rowChannelBufSize = 16 type columns []uint32 diff --git a/pkg/sql/distsql/flow.go b/pkg/sql/distsql/flow.go index a7ad37f037da..2fba78f4fc68 100644 --- a/pkg/sql/distsql/flow.go +++ b/pkg/sql/distsql/flow.go @@ -240,6 +240,12 @@ func (f *Flow) makeProcessor(ps *ProcessorSpec, inputs []RowSource) (processor, } return newMergeJoiner(&f.FlowCtx, ps.Core.MergeJoiner, inputs, outputs[0]) } + if ps.Core.HashJoiner != nil { + if err := checkNumInOut(inputs, outputs, 2, 1); err != nil { + return nil, err + } + return newHashJoiner(&f.FlowCtx, ps.Core.HashJoiner, inputs, outputs[0]) + } return nil, errors.Errorf("unsupported processor %s", ps) } diff --git a/pkg/sql/distsql/hashjoiner.go b/pkg/sql/distsql/hashjoiner.go new file mode 100644 index 000000000000..5455e27158ee --- /dev/null +++ b/pkg/sql/distsql/hashjoiner.go @@ -0,0 +1,200 @@ +// Copyright 2016 The Cockroach Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. See the License for the specific language governing +// permissions and limitations under the License. +// +// Author: Irfan Sharif (irfansharif@cockroachlabs.com) + +package distsql + +import ( + "sync" + + "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" + "github.com/cockroachdb/cockroach/pkg/util/log" + "github.com/cockroachdb/cockroach/pkg/util/tracing" +) + +// bucket here is the set of rows for a given group key (comprised of +// columns specified by the join constraints), 'seen' is used to determine if +// there was a matching group (with the same group key) in the opposite stream. +type bucket struct { + rows sqlbase.EncDatumRows + seen bool +} + +// HashJoiner performs hash join, it has two input streams and one output. +// +// It works by reading the entire left stream and putting it in a hash +// table. Thus, there is no guarantee on the ordering of results that stem only +// from the left input (in the case of LEFT OUTER, FULL OUTER). However, it is +// guaranteed that results that involve the right stream preserve the ordering; +// i.e. all results that stem from right row (i) precede results that stem from +// right row (i+1). +type hashJoiner struct { + joinerBase + + leftEqCols columns + rightEqCols columns + buckets map[string]bucket + datumAlloc sqlbase.DatumAlloc +} + +var _ processor = &hashJoiner{} + +func newHashJoiner( + flowCtx *FlowCtx, spec *HashJoinerSpec, inputs []RowSource, output RowReceiver, +) (*hashJoiner, error) { + h := &hashJoiner{ + leftEqCols: columns(spec.LeftEqColumns), + rightEqCols: columns(spec.RightEqColumns), + buckets: make(map[string]bucket), + } + + err := h.joinerBase.init(flowCtx, inputs, output, spec.OutputColumns, + spec.Type, spec.LeftTypes, spec.RightTypes, spec.Expr) + if err != nil { + return nil, err + } + + return h, nil +} + +// Run is part of the processor interface. +func (h *hashJoiner) Run(wg *sync.WaitGroup) { + if wg != nil { + defer wg.Done() + } + + ctx, span := tracing.ChildSpan(h.ctx, "hash joiner") + defer tracing.FinishSpan(span) + + if log.V(2) { + log.Infof(ctx, "starting hash joiner run") + defer log.Infof(ctx, "exiting hash joiner run") + } + + if err := h.buildPhase(); err != nil { + h.output.Close(err) + return + } + if err := h.probePhase(); err != nil { + h.output.Close(err) + return + } +} + +// buildPhase constructs our internal hash map of rows seen, this is done +// entirely from the left stream with the encoding/group key generated using the +// left equality columns. +func (h *hashJoiner) buildPhase() error { + var scratch []byte + for { + lrow, err := h.inputs[0].NextRow() + if err != nil || lrow == nil { + return err + } + + encoded, err := h.encode(scratch, lrow, h.leftEqCols) + if err != nil { + return err + } + + b, _ := h.buckets[string(encoded)] + b.rows = append(b.rows, lrow) + h.buckets[string(encoded)] = b + + scratch = encoded[:0] + } +} + +// probePhase uses our constructed hash map of rows seen from the left stream, +// we probe the map for each row retrieved from the right stream outputting the +// merging of the two rows if matched. Behaviour for outer joins also behave as +// expected, i.e. for RIGHT OUTER joins if no corresponding left row is seen an +// empty DNull row is emitted instead. +func (h *hashJoiner) probePhase() error { + var scratch []byte + for { + rrow, err := h.inputs[1].NextRow() + if err != nil { + return err + } + if rrow == nil { + break + } + + encoded, err := h.encode(scratch, rrow, h.rightEqCols) + if err != nil { + return err + } + + b, ok := h.buckets[string(encoded)] + if !ok { + row, err := h.render(nil, rrow) + if err != nil { + return err + } + if !h.output.PushRow(row) { + return nil + } + } else { + b.seen = true + h.buckets[string(encoded)] = b + for _, lrow := range b.rows { + row, err := h.render(lrow, rrow) + if err != nil { + return err + } + if row != nil && !h.output.PushRow(row) { + return nil + } + } + } + scratch = encoded[:0] + } + + if h.joinType == innerJoin || h.joinType == rightOuter { + return nil + } + + for _, b := range h.buckets { + if !b.seen { + for _, lrow := range b.rows { + row, err := h.render(lrow, nil) + if err != nil { + return err + } + if row != nil && !h.output.PushRow(row) { + return nil + } + } + + } + } + + return nil +} + +// encode returns the encoding for the grouping columns, this is then used as +// our group key to determine which bucket to add to. +func (h *hashJoiner) encode( + appendTo []byte, row sqlbase.EncDatumRow, cols columns, +) (encoding []byte, err error) { + for _, colIdx := range cols { + appendTo, err = row[colIdx].Encode(&h.datumAlloc, sqlbase.DatumEncoding_VALUE, appendTo) + if err != nil { + return appendTo, err + } + } + return appendTo, nil +} diff --git a/pkg/sql/distsql/hashjoiner_test.go b/pkg/sql/distsql/hashjoiner_test.go new file mode 100644 index 000000000000..ac17d452d973 --- /dev/null +++ b/pkg/sql/distsql/hashjoiner_test.go @@ -0,0 +1,342 @@ +// Copyright 2016 The Cockroach Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. See the License for the specific language governing +// permissions and limitations under the License. +// +// Author: Irfan Sharif (irfansharif@cockroachlabs.com) + +package distsql + +import ( + "sort" + "strings" + "testing" + + "golang.org/x/net/context" + + "github.com/cockroachdb/cockroach/pkg/sql/parser" + "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" + "github.com/cockroachdb/cockroach/pkg/util/leaktest" +) + +func TestHashJoiner(t *testing.T) { + defer leaktest.AfterTest(t)() + v := [6]sqlbase.EncDatum{} + for i := range v { + v[i].SetDatum(sqlbase.ColumnType_INT, parser.NewDInt(parser.DInt(i))) + } + null := sqlbase.EncDatum{Datum: parser.DNull} + + testCases := []struct { + spec HashJoinerSpec + inputs []sqlbase.EncDatumRows + expected sqlbase.EncDatumRows + }{ + { + spec: HashJoinerSpec{ + LeftEqColumns: []uint32{0}, + LeftTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + RightEqColumns: []uint32{0}, + RightTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + Type: JoinType_INNER, + OutputColumns: []uint32{0, 3, 4}, + // Implicit $0 = $2 constraint. + }, + inputs: []sqlbase.EncDatumRows{ + { + {v[0], v[0]}, + {v[1], v[4]}, + {v[2], v[4]}, + {v[3], v[1]}, + {v[4], v[5]}, + {v[5], v[5]}, + }, + { + {v[1], v[0], v[4]}, + {v[3], v[4], v[1]}, + {v[4], v[4], v[5]}, + }, + }, + expected: sqlbase.EncDatumRows{ + {v[1], v[0], v[4]}, + {v[3], v[4], v[1]}, + {v[4], v[4], v[5]}, + }, + }, + { + spec: HashJoinerSpec{ + LeftEqColumns: []uint32{0}, + LeftTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + RightEqColumns: []uint32{0}, + RightTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + Type: JoinType_INNER, + OutputColumns: []uint32{0, 1, 3}, + // Implicit $0 = $2 constraint. + }, + inputs: []sqlbase.EncDatumRows{ + { + {v[0], v[0]}, + {v[0], v[1]}, + }, + { + {v[0], v[4]}, + {v[0], v[1]}, + {v[0], v[0]}, + {v[0], v[5]}, + {v[0], v[4]}, + }, + }, + expected: sqlbase.EncDatumRows{ + {v[0], v[0], v[4]}, + {v[0], v[0], v[1]}, + {v[0], v[0], v[0]}, + {v[0], v[0], v[5]}, + {v[0], v[0], v[4]}, + {v[0], v[1], v[4]}, + {v[0], v[1], v[1]}, + {v[0], v[1], v[0]}, + {v[0], v[1], v[5]}, + {v[0], v[1], v[4]}, + }, + }, + { + spec: HashJoinerSpec{ + LeftEqColumns: []uint32{0}, + LeftTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + RightEqColumns: []uint32{0}, + RightTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + Type: JoinType_INNER, + OutputColumns: []uint32{0, 1, 3}, + Expr: Expression{Expr: "$3 >= 4"}, + // Implicit AND $0 = $2 constraint. + }, + inputs: []sqlbase.EncDatumRows{ + { + {v[0], v[0]}, + {v[0], v[1]}, + {v[1], v[0]}, + {v[1], v[1]}, + }, + { + {v[0], v[4]}, + {v[0], v[1]}, + {v[0], v[0]}, + {v[0], v[5]}, + {v[0], v[4]}, + {v[1], v[4]}, + {v[1], v[1]}, + {v[1], v[0]}, + {v[1], v[5]}, + {v[1], v[4]}, + }, + }, + expected: sqlbase.EncDatumRows{ + {v[0], v[0], v[4]}, + {v[0], v[0], v[5]}, + {v[0], v[0], v[4]}, + {v[0], v[1], v[4]}, + {v[0], v[1], v[5]}, + {v[0], v[1], v[4]}, + {v[1], v[0], v[4]}, + {v[1], v[0], v[5]}, + {v[1], v[0], v[4]}, + {v[1], v[1], v[4]}, + {v[1], v[1], v[5]}, + {v[1], v[1], v[4]}, + }, + }, + { + spec: HashJoinerSpec{ + LeftEqColumns: []uint32{0}, + LeftTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + RightEqColumns: []uint32{0}, + RightTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + Type: JoinType_LEFT_OUTER, + OutputColumns: []uint32{0, 3, 4}, + // Implicit $0 = $2 constraint. + }, + inputs: []sqlbase.EncDatumRows{ + { + {v[0], v[0]}, + {v[1], v[4]}, + {v[2], v[4]}, + {v[3], v[1]}, + {v[4], v[5]}, + {v[5], v[5]}, + }, + { + {v[1], v[0], v[4]}, + {v[3], v[4], v[1]}, + {v[4], v[4], v[5]}, + }, + }, + expected: sqlbase.EncDatumRows{ + {v[0], null, null}, + {v[1], v[0], v[4]}, + {v[2], null, null}, + {v[3], v[4], v[1]}, + {v[4], v[4], v[5]}, + {v[5], null, null}, + }, + }, + { + spec: HashJoinerSpec{ + LeftEqColumns: []uint32{0}, + LeftTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + RightEqColumns: []uint32{0}, + RightTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + Type: JoinType_RIGHT_OUTER, + OutputColumns: []uint32{3, 1, 2}, + // Implicit $0 = $2 constraint. + }, + inputs: []sqlbase.EncDatumRows{ + { + {v[1], v[0], v[4]}, + {v[3], v[4], v[1]}, + {v[4], v[4], v[5]}, + }, + { + {v[0], v[0]}, + {v[1], v[4]}, + {v[2], v[4]}, + {v[3], v[1]}, + {v[4], v[5]}, + {v[5], v[5]}, + }, + }, + expected: sqlbase.EncDatumRows{ + {v[0], null, null}, + {v[1], v[0], v[4]}, + {v[2], null, null}, + {v[3], v[4], v[1]}, + {v[4], v[4], v[5]}, + {v[5], null, null}, + }, + }, + { + spec: HashJoinerSpec{ + LeftEqColumns: []uint32{0}, + LeftTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + RightEqColumns: []uint32{0}, + RightTypes: []sqlbase.ColumnType_Kind{ + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + sqlbase.ColumnType_INT, + }, + Type: JoinType_FULL_OUTER, + OutputColumns: []uint32{0, 3, 4}, + // Implicit $0 = $2 constraint. + }, + inputs: []sqlbase.EncDatumRows{ + { + {v[0], v[0]}, + {v[1], v[4]}, + {v[2], v[4]}, + {v[3], v[1]}, + {v[4], v[5]}, + }, + { + {v[1], v[0], v[4]}, + {v[3], v[4], v[1]}, + {v[4], v[4], v[5]}, + {v[5], v[5], v[1]}, + }, + }, + expected: sqlbase.EncDatumRows{ + {v[0], null, null}, + {v[1], v[0], v[4]}, + {v[2], null, null}, + {v[3], v[4], v[1]}, + {v[4], v[4], v[5]}, + {null, v[5], v[1]}, + }, + }, + } + + for _, c := range testCases { + hs := c.spec + inputs := []RowSource{&RowBuffer{rows: c.inputs[0]}, &RowBuffer{rows: c.inputs[1]}} + out := &RowBuffer{} + flowCtx := FlowCtx{Context: context.Background()} + + h, err := newHashJoiner(&flowCtx, &hs, inputs, out) + if err != nil { + t.Fatal(err) + } + + h.Run(nil) + + var expected []string + for _, row := range c.expected { + expected = append(expected, row.String()) + } + sort.Strings(expected) + expStr := strings.Join(expected, "") + + var rets []string + for { + row, err := out.NextRow() + if err != nil { + t.Fatal(err) + } + if row == nil { + break + } + rets = append(rets, row.String()) + } + sort.Strings(rets) + retStr := strings.Join(rets, "") + + if expStr != retStr { + t.Errorf("invalid results; expected:\n %s\ngot:\n %s", + expStr, retStr) + } + } +} diff --git a/pkg/sql/distsql/joinerbase.go b/pkg/sql/distsql/joinerbase.go new file mode 100644 index 000000000000..a76f5cb66016 --- /dev/null +++ b/pkg/sql/distsql/joinerbase.go @@ -0,0 +1,108 @@ +// Copyright 2016 The Cockroach Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied. See the License for the specific language governing +// permissions and limitations under the License. +// +// Author: Irfan Sharif (irfansharif@cockroachlabs.com) + +package distsql + +import ( + "golang.org/x/net/context" + + "github.com/cockroachdb/cockroach/pkg/sql/parser" + "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" + "github.com/cockroachdb/cockroach/pkg/util/log" +) + +type joinerBase struct { + inputs []RowSource + output RowReceiver + ctx context.Context + + joinType joinType + outputCols columns + filter exprHelper + rowAlloc sqlbase.EncDatumRowAlloc + emptyLeft sqlbase.EncDatumRow + emptyRight sqlbase.EncDatumRow + combinedRow sqlbase.EncDatumRow +} + +// err := init(flowCtx, inputs, output, spec.OutputColumns, +// spec.Type, spec.LeftTypes, spec.RightTypes, spec.Expr) +func (jb *joinerBase) init( + flowCtx *FlowCtx, + inputs []RowSource, + output RowReceiver, + outputCols []uint32, + jType JoinType, + leftTypes []sqlbase.ColumnType_Kind, + rightTypes []sqlbase.ColumnType_Kind, + expr Expression, +) error { + jb.inputs = inputs + jb.output = output + jb.ctx = log.WithLogTag(flowCtx.Context, "Joiner", nil) + jb.outputCols = columns(outputCols) + jb.joinType = joinType(jType) + jb.emptyLeft = make(sqlbase.EncDatumRow, len(leftTypes)) + for i := range jb.emptyLeft { + jb.emptyLeft[i].Datum = parser.DNull + } + + jb.emptyRight = make(sqlbase.EncDatumRow, len(rightTypes)) + for i := range jb.emptyRight { + jb.emptyRight[i].Datum = parser.DNull + } + + return jb.filter.init(expr, append(leftTypes, rightTypes...), flowCtx.evalCtx) +} + +// render evaluates the provided filter and constructs a row with columns from +// both rows as specified by the provided output columns. We expect left or +// right to be nil if there was no explicit "join" match, the filter is then +// evaluated on a combinedRow with null values for the columns of the nil row. +func (jb *joinerBase) render(lrow, rrow sqlbase.EncDatumRow) (sqlbase.EncDatumRow, error) { + switch jb.joinType { + case innerJoin: + if lrow == nil || rrow == nil { + return nil, nil + } + case fullOuter: + if lrow == nil { + lrow = jb.emptyLeft + } else if rrow == nil { + rrow = jb.emptyRight + } + case leftOuter: + if rrow == nil { + rrow = jb.emptyRight + } + case rightOuter: + if lrow == nil { + lrow = jb.emptyLeft + } + } + jb.combinedRow = append(jb.combinedRow[:0], lrow...) + jb.combinedRow = append(jb.combinedRow, rrow...) + res, err := jb.filter.evalFilter(jb.combinedRow) + if !res || err != nil { + return nil, err + } + + row := jb.rowAlloc.AllocRow(len(jb.outputCols)) + for i, col := range jb.outputCols { + row[i] = jb.combinedRow[col] + } + return row, nil +} diff --git a/pkg/sql/distsql/mergejoiner.go b/pkg/sql/distsql/mergejoiner.go index 8943a5246a5c..12f5bca23603 100644 --- a/pkg/sql/distsql/mergejoiner.go +++ b/pkg/sql/distsql/mergejoiner.go @@ -20,40 +20,19 @@ import ( "errors" "sync" - "golang.org/x/net/context" - - "github.com/cockroachdb/cockroach/pkg/sql/parser" "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/tracing" ) -type joinType int - -const ( - innerJoin joinType = iota - leftOuter - rightOuter - fullOuter -) - // mergeJoiner performs merge join, it has two input row sources with the same // ordering on the columns that have equality constraints. // // It is guaranteed that the results preserve this ordering. type mergeJoiner struct { - inputs []RowSource - output RowReceiver - joinType joinType - filter exprHelper - outputCols columns + joinerBase - ctx context.Context - combinedRow sqlbase.EncDatumRow - rowAlloc sqlbase.EncDatumRowAlloc streamMerger streamMerger - emptyRight sqlbase.EncDatumRow - emptyLeft sqlbase.EncDatumRow } var _ processor = &mergeJoiner{} @@ -67,25 +46,13 @@ func newMergeJoiner( } } - m := &mergeJoiner{ - inputs: inputs, - output: output, - ctx: log.WithLogTag(flowCtx.Context, "Merge Joiner", nil), - outputCols: columns(spec.OutputColumns), - joinType: joinType(spec.Type), - filter: exprHelper{}, - emptyLeft: make(sqlbase.EncDatumRow, len(spec.LeftTypes)), - emptyRight: make(sqlbase.EncDatumRow, len(spec.RightTypes)), - } - - for i := range m.emptyLeft { - m.emptyLeft[i].Datum = parser.DNull - } - for i := range m.emptyRight { - m.emptyRight[i].Datum = parser.DNull + m := &mergeJoiner{} + err := m.joinerBase.init(flowCtx, nil, output, spec.OutputColumns, + spec.Type, spec.LeftTypes, spec.RightTypes, spec.Expr) + if err != nil { + return nil, err } - var err error m.streamMerger, err = makeStreamMerger( []sqlbase.ColumnOrdering{ convertToColumnOrdering(spec.LeftOrdering), @@ -95,11 +62,6 @@ func newMergeJoiner( return nil, err } - err = m.filter.init(spec.Expr, append(spec.LeftTypes, spec.RightTypes...), flowCtx.evalCtx) - if err != nil { - return nil, err - } - return m, nil } @@ -139,42 +101,3 @@ func (m *mergeJoiner) Run(wg *sync.WaitGroup) { } } } - -// render evaluates the provided filter and constructs a row with columns from -// both rows as specified by the provided output columns. We expect left or -// right to be nil if there was no explicit "join" match, the filter is then -// evaluated on a combinedRow with null values for the columns of the nil row. -func (m *mergeJoiner) render(left, right sqlbase.EncDatumRow) (sqlbase.EncDatumRow, error) { - switch m.joinType { - case innerJoin: - if left == nil || right == nil { - return nil, nil - } - case fullOuter: - if left == nil { - left = m.emptyLeft - } else if right == nil { - right = m.emptyRight - } - case leftOuter: - if right == nil { - right = m.emptyRight - } - case rightOuter: - if left == nil { - left = m.emptyLeft - } - } - m.combinedRow = append(m.combinedRow[:0], left...) - m.combinedRow = append(m.combinedRow, right...) - res, err := m.filter.evalFilter(m.combinedRow) - if !res || err != nil { - return nil, err - } - - row := m.rowAlloc.AllocRow(len(m.outputCols)) - for i, col := range m.outputCols { - row[i] = m.combinedRow[col] - } - return row, nil -} diff --git a/pkg/sql/distsql/processors.pb.go b/pkg/sql/distsql/processors.pb.go index 361c7515a04b..a38dfcdfc749 100644 --- a/pkg/sql/distsql/processors.pb.go +++ b/pkg/sql/distsql/processors.pb.go @@ -271,8 +271,8 @@ type MergeJoinerSpec struct { // In the example above, left ordering describes C1+,C2- and right ordering // describes C5+,C4-. LeftOrdering Ordering `protobuf:"bytes,1,opt,name=left_ordering,json=leftOrdering" json:"left_ordering"` - LeftTypes []cockroach_sql_sqlbase1.ColumnType_Kind `protobuf:"varint,2,rep,name=left_types,json=leftTypes,enum=cockroach.sql.sqlbase.ColumnType_Kind" json:"left_types,omitempty"` - RightOrdering Ordering `protobuf:"bytes,3,opt,name=right_ordering,json=rightOrdering" json:"right_ordering"` + RightOrdering Ordering `protobuf:"bytes,2,opt,name=right_ordering,json=rightOrdering" json:"right_ordering"` + LeftTypes []cockroach_sql_sqlbase1.ColumnType_Kind `protobuf:"varint,3,rep,name=left_types,json=leftTypes,enum=cockroach.sql.sqlbase.ColumnType_Kind" json:"left_types,omitempty"` RightTypes []cockroach_sql_sqlbase1.ColumnType_Kind `protobuf:"varint,4,rep,name=right_types,json=rightTypes,enum=cockroach.sql.sqlbase.ColumnType_Kind" json:"right_types,omitempty"` // "ON" expression (in addition to the equality constraints captured by the // orderings). Assuming that the left stream has N columns and the right @@ -304,19 +304,21 @@ func (*MergeJoinerSpec) Descriptor() ([]byte, []int) { return fileDescriptorProc type HashJoinerSpec struct { // The join constraints certain columns from the left stream to equal // corresponding columns on the right stream. These must have the same length. - LeftEqColumns []uint32 `protobuf:"varint,1,rep,packed,name=left_eq_columns,json=leftEqColumns" json:"left_eq_columns,omitempty"` - RightEqColumns []uint32 `protobuf:"varint,2,rep,packed,name=right_eq_columns,json=rightEqColumns" json:"right_eq_columns,omitempty"` + LeftEqColumns []uint32 `protobuf:"varint,1,rep,packed,name=left_eq_columns,json=leftEqColumns" json:"left_eq_columns,omitempty"` + RightEqColumns []uint32 `protobuf:"varint,2,rep,packed,name=right_eq_columns,json=rightEqColumns" json:"right_eq_columns,omitempty"` + LeftTypes []cockroach_sql_sqlbase1.ColumnType_Kind `protobuf:"varint,3,rep,name=left_types,json=leftTypes,enum=cockroach.sql.sqlbase.ColumnType_Kind" json:"left_types,omitempty"` + RightTypes []cockroach_sql_sqlbase1.ColumnType_Kind `protobuf:"varint,4,rep,name=right_types,json=rightTypes,enum=cockroach.sql.sqlbase.ColumnType_Kind" json:"right_types,omitempty"` // "ON" expression (in addition to the equality constraints captured by the // orderings). Assuming that the left stream has N columns and the right // stream has M columns, in this expression variables $0 to $(N-1) refer to // columns of the left stream and variables $N to $(N+M-1) refer to columns in // the right stream. - Expr Expression `protobuf:"bytes,3,opt,name=expr" json:"expr"` - Type JoinType `protobuf:"varint,4,opt,name=type,enum=cockroach.sql.distsql.JoinType" json:"type"` + Expr Expression `protobuf:"bytes,5,opt,name=expr" json:"expr"` + Type JoinType `protobuf:"varint,6,opt,name=type,enum=cockroach.sql.distsql.JoinType" json:"type"` // Columns for the output stream. Assuming that the left stream has N columns // and the right stream has M columns, column indices 0 to (N-1) refer to left // stream columns and indices N to (N+M-1) refer to right stream columns. - OutputColumns []uint32 `protobuf:"varint,5,rep,packed,name=output_columns,json=outputColumns" json:"output_columns,omitempty"` + OutputColumns []uint32 `protobuf:"varint,7,rep,packed,name=output_columns,json=outputColumns" json:"output_columns,omitempty"` } func (m *HashJoinerSpec) Reset() { *m = HashJoinerSpec{} } @@ -723,14 +725,7 @@ func (m *MergeJoinerSpec) MarshalTo(data []byte) (int, error) { return 0, err } i += n12 - if len(m.LeftTypes) > 0 { - for _, num := range m.LeftTypes { - data[i] = 0x10 - i++ - i = encodeVarintProcessors(data, i, uint64(num)) - } - } - data[i] = 0x1a + data[i] = 0x12 i++ i = encodeVarintProcessors(data, i, uint64(m.RightOrdering.Size())) n13, err := m.RightOrdering.MarshalTo(data[i:]) @@ -738,6 +733,13 @@ func (m *MergeJoinerSpec) MarshalTo(data []byte) (int, error) { return 0, err } i += n13 + if len(m.LeftTypes) > 0 { + for _, num := range m.LeftTypes { + data[i] = 0x18 + i++ + i = encodeVarintProcessors(data, i, uint64(num)) + } + } if len(m.RightTypes) > 0 { for _, num := range m.RightTypes { data[i] = 0x20 @@ -825,7 +827,21 @@ func (m *HashJoinerSpec) MarshalTo(data []byte) (int, error) { i = encodeVarintProcessors(data, i, uint64(j19)) i += copy(data[i:], data20[:j19]) } - data[i] = 0x1a + if len(m.LeftTypes) > 0 { + for _, num := range m.LeftTypes { + data[i] = 0x18 + i++ + i = encodeVarintProcessors(data, i, uint64(num)) + } + } + if len(m.RightTypes) > 0 { + for _, num := range m.RightTypes { + data[i] = 0x20 + i++ + i = encodeVarintProcessors(data, i, uint64(num)) + } + } + data[i] = 0x2a i++ i = encodeVarintProcessors(data, i, uint64(m.Expr.Size())) n21, err := m.Expr.MarshalTo(data[i:]) @@ -833,7 +849,7 @@ func (m *HashJoinerSpec) MarshalTo(data []byte) (int, error) { return 0, err } i += n21 - data[i] = 0x20 + data[i] = 0x30 i++ i = encodeVarintProcessors(data, i, uint64(m.Type)) if len(m.OutputColumns) > 0 { @@ -848,7 +864,7 @@ func (m *HashJoinerSpec) MarshalTo(data []byte) (int, error) { data23[j22] = uint8(num) j22++ } - data[i] = 0x2a + data[i] = 0x3a i++ i = encodeVarintProcessors(data, i, uint64(j22)) i += copy(data[i:], data23[:j22]) @@ -1254,13 +1270,13 @@ func (m *MergeJoinerSpec) Size() (n int) { _ = l l = m.LeftOrdering.Size() n += 1 + l + sovProcessors(uint64(l)) + l = m.RightOrdering.Size() + n += 1 + l + sovProcessors(uint64(l)) if len(m.LeftTypes) > 0 { for _, e := range m.LeftTypes { n += 1 + sovProcessors(uint64(e)) } } - l = m.RightOrdering.Size() - n += 1 + l + sovProcessors(uint64(l)) if len(m.RightTypes) > 0 { for _, e := range m.RightTypes { n += 1 + sovProcessors(uint64(e)) @@ -1296,6 +1312,16 @@ func (m *HashJoinerSpec) Size() (n int) { } n += 1 + sovProcessors(uint64(l)) + l } + if len(m.LeftTypes) > 0 { + for _, e := range m.LeftTypes { + n += 1 + sovProcessors(uint64(e)) + } + } + if len(m.RightTypes) > 0 { + for _, e := range m.RightTypes { + n += 1 + sovProcessors(uint64(e)) + } + } l = m.Expr.Size() n += 1 + l + sovProcessors(uint64(l)) n += 1 + sovProcessors(uint64(m.Type)) @@ -2445,26 +2471,6 @@ func (m *MergeJoinerSpec) Unmarshal(data []byte) error { } iNdEx = postIndex case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LeftTypes", wireType) - } - var v cockroach_sql_sqlbase1.ColumnType_Kind - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowProcessors - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - v |= (cockroach_sql_sqlbase1.ColumnType_Kind(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.LeftTypes = append(m.LeftTypes, v) - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field RightOrdering", wireType) } @@ -2494,6 +2500,26 @@ func (m *MergeJoinerSpec) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LeftTypes", wireType) + } + var v cockroach_sql_sqlbase1.ColumnType_Kind + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProcessors + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (cockroach_sql_sqlbase1.ColumnType_Kind(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.LeftTypes = append(m.LeftTypes, v) case 4: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field RightTypes", wireType) @@ -2800,6 +2826,46 @@ func (m *HashJoinerSpec) Unmarshal(data []byte) error { return fmt.Errorf("proto: wrong wireType = %d for field RightEqColumns", wireType) } case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LeftTypes", wireType) + } + var v cockroach_sql_sqlbase1.ColumnType_Kind + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProcessors + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (cockroach_sql_sqlbase1.ColumnType_Kind(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.LeftTypes = append(m.LeftTypes, v) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RightTypes", wireType) + } + var v cockroach_sql_sqlbase1.ColumnType_Kind + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProcessors + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (cockroach_sql_sqlbase1.ColumnType_Kind(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.RightTypes = append(m.RightTypes, v) + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Expr", wireType) } @@ -2829,7 +2895,7 @@ func (m *HashJoinerSpec) Unmarshal(data []byte) error { return err } iNdEx = postIndex - case 4: + case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) } @@ -2848,7 +2914,7 @@ func (m *HashJoinerSpec) Unmarshal(data []byte) error { break } } - case 5: + case 7: if wireType == 2 { var packedLen int for shift := uint(0); ; shift += 7 { @@ -3870,88 +3936,88 @@ func init() { } var fileDescriptorProcessors = []byte{ - // 1323 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x57, 0xdb, 0x6e, 0xdb, 0x46, - 0x13, 0x36, 0x45, 0xea, 0x34, 0xb2, 0x64, 0x62, 0xf1, 0xff, 0xa8, 0x60, 0x20, 0xb2, 0xc2, 0x24, - 0xad, 0x62, 0xb4, 0x32, 0x92, 0x9b, 0x22, 0x3d, 0x20, 0xd5, 0xc9, 0xb6, 0x52, 0x59, 0x6a, 0x69, - 0x39, 0x28, 0x7a, 0x23, 0x30, 0xe4, 0x5a, 0x66, 0x43, 0x73, 0xe9, 0x25, 0x99, 0x38, 0x0f, 0xd0, - 0x8b, 0x02, 0x0d, 0x50, 0xf4, 0x09, 0xfa, 0x00, 0x7d, 0x10, 0xdf, 0x14, 0xe8, 0x65, 0x51, 0xa0, - 0x41, 0xeb, 0xbc, 0x46, 0x2f, 0x8a, 0x5d, 0x2e, 0x29, 0x3a, 0x35, 0x53, 0x3b, 0x35, 0x7a, 0x65, - 0x6a, 0xf8, 0x7d, 0xc3, 0x99, 0x6f, 0x76, 0x66, 0xd6, 0xb0, 0x6e, 0x12, 0xf3, 0x31, 0x25, 0x86, - 0x79, 0xb0, 0xe1, 0x3d, 0x9e, 0x6f, 0xf8, 0x47, 0xce, 0x86, 0x65, 0xfb, 0x01, 0xfb, 0xeb, 0x51, - 0x62, 0x62, 0xdf, 0x27, 0xd4, 0x6f, 0x7b, 0x94, 0x04, 0x04, 0xfd, 0x3f, 0xc1, 0xb6, 0xfd, 0x23, - 0xa7, 0x2d, 0x70, 0xab, 0xcd, 0xb3, 0x2e, 0xf8, 0x93, 0xf7, 0x68, 0xc3, 0x32, 0x02, 0x23, 0x22, - 0xae, 0x6a, 0xe7, 0x23, 0x30, 0xa5, 0x89, 0xf3, 0xd5, 0x73, 0x02, 0xf1, 0x8f, 0x9c, 0x47, 0x86, - 0x8f, 0x37, 0xfc, 0x80, 0x86, 0x66, 0x10, 0x52, 0x6c, 0x09, 0xec, 0x7b, 0xd9, 0x58, 0xec, 0x9a, - 0xc4, 0xc2, 0xd6, 0xcc, 0x32, 0x82, 0xf0, 0x50, 0xc0, 0x6f, 0x66, 0xe7, 0x98, 0x0a, 0xf2, 0x7f, - 0x73, 0x32, 0x27, 0xfc, 0x71, 0x83, 0x3d, 0x45, 0x56, 0xad, 0x06, 0xcb, 0x63, 0x42, 0xbc, 0x1e, - 0xa1, 0x78, 0xd7, 0xc3, 0xa6, 0xd6, 0x87, 0x95, 0xa9, 0xf1, 0xc8, 0xc1, 0x3a, 0x36, 0x2c, 0x4c, - 0x77, 0x3d, 0xc3, 0x45, 0x77, 0x40, 0xf1, 0x3d, 0xc3, 0xad, 0x4b, 0x4d, 0xa9, 0x55, 0xb9, 0xfb, - 0x56, 0x7b, 0xa1, 0x92, 0x48, 0xb4, 0xcd, 0x60, 0x5d, 0xe5, 0xe4, 0xc5, 0xda, 0x92, 0xce, 0xa1, - 0xda, 0xf7, 0xf2, 0x2b, 0x6e, 0xb0, 0x89, 0xba, 0x90, 0x0f, 0x98, 0x49, 0xf8, 0x79, 0xbb, 0x7d, - 0x56, 0x6d, 0x91, 0x60, 0x9b, 0xd3, 0xfa, 0xd8, 0x37, 0xa9, 0xed, 0x05, 0x84, 0x0a, 0xb7, 0x11, - 0x15, 0x5d, 0x87, 0xb2, 0xed, 0x5a, 0xf8, 0x78, 0x66, 0x5b, 0xc7, 0xf5, 0x5c, 0x53, 0x6a, 0x55, - 0xc5, 0xfb, 0x12, 0x37, 0x0f, 0xad, 0x63, 0xd4, 0x80, 0x22, 0xc5, 0x4f, 0x30, 0xf5, 0x71, 0x5d, - 0x6e, 0x4a, 0xad, 0x92, 0x00, 0xc4, 0x46, 0x16, 0x06, 0x0b, 0xd1, 0xaf, 0x2b, 0x4d, 0xf9, 0x9c, - 0x30, 0x84, 0x70, 0xed, 0x57, 0x44, 0x88, 0xc3, 0xe0, 0x54, 0x74, 0x1f, 0x0a, 0xfb, 0xb6, 0x13, - 0x60, 0x5a, 0xcf, 0xf3, 0x5c, 0xae, 0x67, 0x38, 0x19, 0x1c, 0x7b, 0x14, 0xfb, 0xbe, 0x4d, 0x62, - 0xbe, 0xa0, 0xa1, 0xdb, 0x50, 0x23, 0x61, 0xe0, 0x85, 0xc1, 0xcc, 0x24, 0x4e, 0x78, 0xe8, 0xfa, - 0xf5, 0x42, 0x53, 0x6e, 0x55, 0xbb, 0x39, 0x55, 0xd2, 0xab, 0xd1, 0x9b, 0x5e, 0xf4, 0x02, 0xdd, - 0x00, 0xf0, 0xc9, 0x7e, 0x30, 0x73, 0xec, 0x43, 0x3b, 0xa8, 0x17, 0x9b, 0x52, 0x4b, 0x16, 0xce, - 0xca, 0xcc, 0x3e, 0x62, 0x66, 0x06, 0x3a, 0x30, 0xa8, 0x25, 0x40, 0xa5, 0x34, 0x88, 0xd9, 0x39, - 0x48, 0x7b, 0x29, 0x41, 0xed, 0x01, 0xb1, 0xdd, 0xff, 0xbe, 0x26, 0x0b, 0xbd, 0xe4, 0xab, 0xd2, - 0x4b, 0xc9, 0xd0, 0x4b, 0xfb, 0x51, 0x02, 0xd8, 0x25, 0x34, 0x10, 0x19, 0x8e, 0x61, 0x45, 0x30, - 0x09, 0xb5, 0x30, 0xb5, 0xdd, 0xb9, 0xc8, 0x75, 0x2d, 0x23, 0x86, 0x89, 0x80, 0x89, 0x08, 0xc4, - 0x77, 0x63, 0x2b, 0xba, 0x0b, 0x28, 0x76, 0x34, 0x3b, 0x34, 0x02, 0xf3, 0x60, 0xe6, 0x60, 0xf7, - 0x4c, 0xda, 0x6a, 0xfc, 0x7e, 0x87, 0xbd, 0x1e, 0x61, 0x17, 0xad, 0x42, 0x3e, 0x2a, 0x8c, 0x9c, - 0x2a, 0x4c, 0x64, 0xd2, 0xbe, 0x95, 0xa0, 0x3a, 0x78, 0x62, 0x38, 0xa1, 0x11, 0x90, 0x28, 0xe2, - 0x8f, 0x20, 0x1f, 0x3c, 0xf3, 0xb0, 0x5f, 0x97, 0x9a, 0x72, 0xab, 0x96, 0x59, 0x93, 0x28, 0xdf, - 0xe9, 0x33, 0x0f, 0xb7, 0x3f, 0xb5, 0x5d, 0x4b, 0x8f, 0x48, 0xe8, 0x63, 0xc8, 0xe3, 0x63, 0x8f, - 0xfa, 0xf5, 0x1c, 0x3f, 0xde, 0x17, 0x56, 0x3a, 0x62, 0x69, 0x9f, 0xc3, 0x72, 0xdf, 0xf6, 0x03, - 0xdb, 0x35, 0x03, 0x1e, 0x4c, 0x07, 0x4a, 0x6f, 0xa6, 0x5b, 0x42, 0xd3, 0x5e, 0xc8, 0xb0, 0xb2, - 0x83, 0xe9, 0x1c, 0xb3, 0xb3, 0x27, 0xaa, 0xf2, 0x00, 0xaa, 0x0e, 0xde, 0x7f, 0xd3, 0x9a, 0x2c, - 0x33, 0x6e, 0x52, 0x91, 0x01, 0x00, 0xf7, 0x15, 0x89, 0x96, 0xbb, 0x94, 0x68, 0x65, 0xc6, 0x9c, - 0x72, 0xe1, 0x46, 0x50, 0xa3, 0xf6, 0xfc, 0x20, 0x15, 0x93, 0x7c, 0x99, 0x98, 0xaa, 0x9c, 0x9c, - 0x04, 0xb5, 0x05, 0x95, 0xc8, 0x5b, 0x14, 0x95, 0x72, 0xa9, 0xa8, 0x80, 0x53, 0xa3, 0xb0, 0x3e, - 0x04, 0x85, 0x55, 0xe6, 0xb2, 0x83, 0x86, 0x93, 0xd0, 0x3d, 0x50, 0xd8, 0xf7, 0xeb, 0x85, 0xa6, - 0xd4, 0xaa, 0x65, 0x66, 0xc2, 0xea, 0xc2, 0x3e, 0x16, 0x53, 0x19, 0xe5, 0x9c, 0x8e, 0x2b, 0x66, - 0x75, 0xdc, 0xf3, 0x1c, 0xd4, 0xb6, 0x0d, 0xff, 0x20, 0x55, 0xdf, 0x75, 0x58, 0xe1, 0x35, 0xc1, - 0x47, 0x09, 0x5d, 0x5a, 0xd0, 0xd9, 0xab, 0xc1, 0x51, 0x3c, 0xe0, 0xde, 0x05, 0x35, 0x92, 0x2a, - 0x05, 0xce, 0x25, 0xe0, 0xa8, 0x28, 0x0b, 0x74, 0xac, 0x87, 0xfc, 0x6f, 0xf4, 0x50, 0xae, 0x42, - 0x8f, 0x7c, 0x96, 0x1e, 0x3f, 0xc9, 0x50, 0xeb, 0xcc, 0xe7, 0x14, 0xcf, 0xaf, 0xa8, 0xa7, 0xaf, - 0x01, 0xcc, 0x29, 0x09, 0x3d, 0xf6, 0x69, 0xa1, 0x8d, 0x5e, 0xe6, 0x96, 0x1e, 0x71, 0x7c, 0xb4, - 0x19, 0xb7, 0xbc, 0xcc, 0x5b, 0x7e, 0x3d, 0x23, 0xad, 0xb3, 0x21, 0x71, 0x89, 0xce, 0xf4, 0xfe, - 0xea, 0x73, 0x09, 0x14, 0x66, 0x45, 0x7d, 0x50, 0xf6, 0x43, 0xd7, 0xe4, 0x4d, 0x59, 0xbb, 0xa8, - 0xbf, 0xcd, 0xd0, 0x35, 0x63, 0xc5, 0x18, 0x1b, 0x35, 0xa1, 0x64, 0x89, 0x51, 0xc2, 0xe7, 0x63, - 0xbc, 0x89, 0x13, 0x2b, 0xba, 0x06, 0x45, 0x93, 0x38, 0x7c, 0x6f, 0xc8, 0xa9, 0x01, 0x5a, 0x30, - 0x89, 0x33, 0xb4, 0x8e, 0xb5, 0xaf, 0x25, 0x50, 0x98, 0x57, 0x54, 0x86, 0xfc, 0xb0, 0x3f, 0x18, - 0x4f, 0xd5, 0x25, 0x54, 0x04, 0xb9, 0xf3, 0x70, 0x4b, 0x95, 0xd0, 0x32, 0x94, 0xba, 0x93, 0xc9, - 0x68, 0xd6, 0x19, 0xf7, 0xd5, 0x1c, 0xaa, 0x40, 0x91, 0xff, 0x9a, 0xe8, 0xaa, 0x8c, 0x6a, 0x00, - 0xbd, 0xc9, 0xb8, 0xd7, 0x99, 0xce, 0x3a, 0x5b, 0x5b, 0xaa, 0xc2, 0xe8, 0xbd, 0xc9, 0xde, 0x78, - 0xaa, 0xe6, 0x19, 0x7d, 0xa7, 0xf3, 0x85, 0x5a, 0xe4, 0x0f, 0xc3, 0xb1, 0x5a, 0x42, 0x00, 0x85, - 0xdd, 0x69, 0xbf, 0x3f, 0x78, 0xa8, 0x96, 0x99, 0x71, 0x77, 0x6f, 0x47, 0x05, 0xe6, 0xfc, 0x61, - 0x47, 0x1f, 0x76, 0xc6, 0xbd, 0x81, 0x5a, 0xd1, 0xfe, 0x54, 0x00, 0x7d, 0x16, 0xdf, 0x15, 0xd9, - 0x45, 0x69, 0xcf, 0xb5, 0x89, 0x8b, 0xde, 0x07, 0xc5, 0x25, 0xc4, 0x13, 0xa3, 0xeb, 0x46, 0x86, - 0x4a, 0xe9, 0xcb, 0x95, 0xce, 0x09, 0x68, 0x1b, 0x2a, 0xc1, 0xe2, 0x76, 0xc1, 0xb5, 0xb9, 0xe0, - 0x3d, 0x04, 0x9b, 0x7a, 0x9a, 0xca, 0x46, 0xdf, 0x57, 0xc9, 0x42, 0x17, 0x2d, 0x71, 0xeb, 0x35, - 0xa7, 0x3a, 0xe5, 0x27, 0x45, 0x44, 0xf7, 0xa0, 0xe0, 0xf3, 0x8d, 0xc9, 0x1b, 0x23, 0xbb, 0xab, - 0x16, 0x6b, 0x55, 0x17, 0x04, 0x16, 0x81, 0x91, 0x9c, 0x03, 0x31, 0xa4, 0x6e, 0x5d, 0xe8, 0xc0, - 0xe8, 0x29, 0x22, 0xea, 0x42, 0x19, 0xc7, 0x4b, 0x90, 0x4f, 0xab, 0xca, 0xdd, 0x9b, 0x59, 0xad, - 0x9d, 0x5e, 0x96, 0xfa, 0x82, 0x86, 0xee, 0xa7, 0xce, 0x5b, 0xf1, 0xb5, 0x35, 0x49, 0x6f, 0xb8, - 0xd4, 0x71, 0xdc, 0x86, 0xca, 0xe1, 0x62, 0x4f, 0xf1, 0x5b, 0x54, 0x76, 0x5d, 0x5e, 0xd9, 0x68, - 0x7a, 0x9a, 0xca, 0x54, 0x39, 0x48, 0x06, 0x62, 0xbd, 0xfc, 0x5a, 0x55, 0xce, 0x4e, 0x4e, 0x3d, - 0x45, 0xfc, 0x40, 0x39, 0xf9, 0x61, 0x4d, 0xd2, 0x7e, 0x93, 0xa0, 0x9a, 0x1c, 0x3f, 0x3e, 0x4d, - 0x3e, 0x81, 0xbc, 0xed, 0x7a, 0x61, 0xc0, 0xa7, 0x49, 0xb6, 0x52, 0x43, 0x86, 0xd9, 0x7d, 0xe6, - 0x9a, 0x8c, 0x14, 0xb7, 0x3a, 0x27, 0xa2, 0x1e, 0x28, 0x26, 0xa1, 0x58, 0x9c, 0xbd, 0xdb, 0x19, - 0x0e, 0xfe, 0x7e, 0xe8, 0xe3, 0x06, 0x67, 0x64, 0x34, 0x80, 0x42, 0x34, 0xf8, 0xc4, 0xe0, 0x79, - 0x27, 0x6b, 0x53, 0x72, 0x90, 0x4e, 0x42, 0x71, 0x78, 0xe2, 0x36, 0x8f, 0xc8, 0xda, 0x37, 0x12, - 0x94, 0x36, 0x1d, 0xf2, 0x94, 0xa7, 0x76, 0x07, 0x8a, 0xfb, 0x0e, 0x79, 0x3a, 0xb3, 0x2d, 0xde, - 0x57, 0xcb, 0xdd, 0x3a, 0xc3, 0xfe, 0xfa, 0x62, 0xad, 0xc0, 0x20, 0xc3, 0xfe, 0x69, 0xf2, 0xa4, - 0x17, 0x18, 0x70, 0x68, 0xa1, 0x07, 0x00, 0x8b, 0xff, 0xe4, 0xc4, 0xb5, 0xe7, 0xe6, 0x3f, 0x65, - 0x94, 0x8a, 0x23, 0xc5, 0x5e, 0xdf, 0x84, 0x52, 0x3c, 0xfd, 0xf9, 0xd4, 0x19, 0x8f, 0x07, 0xba, - 0xba, 0xc4, 0x26, 0xca, 0x68, 0xb0, 0x39, 0x9d, 0x4d, 0xf6, 0xa6, 0x03, 0x5d, 0x95, 0xd0, 0x0a, - 0x54, 0xf4, 0xe1, 0xd6, 0x76, 0x6c, 0xc8, 0x31, 0xc0, 0xe6, 0xde, 0x68, 0x24, 0x7e, 0xcb, 0xdd, - 0xeb, 0x27, 0x7f, 0x34, 0x96, 0x4e, 0x4e, 0x1b, 0xd2, 0xcf, 0xa7, 0x0d, 0xe9, 0x97, 0xd3, 0x86, - 0xf4, 0xfb, 0x69, 0x43, 0xfa, 0xee, 0x65, 0x63, 0xe9, 0xcb, 0xa2, 0x08, 0xe5, 0xaf, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xbd, 0x63, 0xcd, 0x71, 0x99, 0x0e, 0x00, 0x00, + // 1316 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xec, 0x57, 0x5d, 0x6f, 0xdb, 0xd4, + 0x1b, 0xaf, 0x63, 0xe7, 0xed, 0x49, 0x93, 0x5a, 0x47, 0xff, 0xbf, 0xb0, 0x2a, 0x2d, 0xcd, 0xbc, + 0x0d, 0xb2, 0x0a, 0x52, 0x6d, 0x37, 0x68, 0xbc, 0x68, 0xe4, 0xad, 0x6d, 0x46, 0x9a, 0x80, 0x9b, + 0x4e, 0x88, 0x9b, 0xc8, 0xb3, 0x4f, 0x53, 0x33, 0xd7, 0xc7, 0x3d, 0x76, 0xb6, 0xee, 0x03, 0x70, + 0x81, 0x04, 0x12, 0xe2, 0x1e, 0x89, 0x0f, 0xc0, 0x07, 0xe9, 0x0d, 0x12, 0x97, 0x08, 0x89, 0x09, + 0xba, 0xaf, 0xc1, 0x05, 0x3a, 0xc7, 0xc7, 0x8e, 0x3b, 0xea, 0xd2, 0x4e, 0x13, 0x57, 0x5c, 0xd5, + 0x79, 0xfc, 0xfb, 0x3d, 0x7e, 0x5e, 0x7f, 0xe7, 0x14, 0xd6, 0x2d, 0x62, 0x3d, 0xa6, 0xc4, 0xb4, + 0x0e, 0x36, 0xfc, 0xc7, 0xb3, 0x8d, 0xe0, 0xc8, 0xdd, 0xb0, 0x9d, 0x20, 0x64, 0x7f, 0x7d, 0x4a, + 0x2c, 0x1c, 0x04, 0x84, 0x06, 0x2d, 0x9f, 0x92, 0x90, 0xa0, 0xff, 0x27, 0xd8, 0x56, 0x70, 0xe4, + 0xb6, 0x04, 0x6e, 0xb5, 0x71, 0xd6, 0x05, 0x7f, 0xf2, 0x1f, 0x6d, 0xd8, 0x66, 0x68, 0x46, 0xc4, + 0x55, 0xfd, 0x7c, 0x04, 0xa6, 0x34, 0x71, 0xbe, 0x7a, 0x4e, 0x20, 0xc1, 0x91, 0xfb, 0xc8, 0x0c, + 0xf0, 0x46, 0x10, 0xd2, 0xb9, 0x15, 0xce, 0x29, 0xb6, 0x05, 0xf6, 0x9d, 0x6c, 0x2c, 0xf6, 0x2c, + 0x62, 0x63, 0x7b, 0x6a, 0x9b, 0xe1, 0xfc, 0x50, 0xc0, 0x6f, 0x66, 0xe7, 0x98, 0x0a, 0xf2, 0x7f, + 0x33, 0x32, 0x23, 0xfc, 0x71, 0x83, 0x3d, 0x45, 0x56, 0xbd, 0x06, 0xcb, 0x23, 0x42, 0xfc, 0x2e, + 0xa1, 0x78, 0xd7, 0xc7, 0x96, 0xde, 0x83, 0x95, 0x89, 0xf9, 0xc8, 0xc5, 0x06, 0x36, 0x6d, 0x4c, + 0x77, 0x7d, 0xd3, 0x43, 0x77, 0x40, 0x09, 0x7c, 0xd3, 0xd3, 0xa4, 0x86, 0xd4, 0xac, 0xdc, 0x7d, + 0xa3, 0xb5, 0xa8, 0x92, 0x48, 0xb4, 0xc5, 0x60, 0x1d, 0xe5, 0xe4, 0xf9, 0xda, 0x92, 0xc1, 0xa1, + 0xfa, 0x77, 0xf2, 0x4b, 0x6e, 0xb0, 0x85, 0x3a, 0x90, 0x0f, 0x99, 0x49, 0xf8, 0x79, 0xb3, 0x75, + 0xb6, 0xda, 0x22, 0xc1, 0x16, 0xa7, 0xf5, 0x70, 0x60, 0x51, 0xc7, 0x0f, 0x09, 0x15, 0x6e, 0x23, + 0x2a, 0xba, 0x0e, 0x65, 0xc7, 0xb3, 0xf1, 0xf1, 0xd4, 0xb1, 0x8f, 0xb5, 0x5c, 0x43, 0x6a, 0x56, + 0xc5, 0xfb, 0x12, 0x37, 0x0f, 0xec, 0x63, 0x54, 0x87, 0x22, 0xc5, 0x4f, 0x30, 0x0d, 0xb0, 0x26, + 0x37, 0xa4, 0x66, 0x49, 0x00, 0x62, 0x23, 0x0b, 0x83, 0x85, 0x18, 0x68, 0x4a, 0x43, 0x3e, 0x27, + 0x0c, 0x51, 0xb8, 0xd6, 0x4b, 0x45, 0x88, 0xc3, 0xe0, 0x54, 0x74, 0x1f, 0x0a, 0xfb, 0x8e, 0x1b, + 0x62, 0xaa, 0xe5, 0x79, 0x2e, 0xd7, 0x33, 0x9c, 0xf4, 0x8f, 0x7d, 0x8a, 0x83, 0xc0, 0x21, 0x31, + 0x5f, 0xd0, 0xd0, 0x6d, 0xa8, 0x91, 0x79, 0xe8, 0xcf, 0xc3, 0xa9, 0x45, 0xdc, 0xf9, 0xa1, 0x17, + 0x68, 0x85, 0x86, 0xdc, 0xac, 0x76, 0x72, 0xaa, 0x64, 0x54, 0xa3, 0x37, 0xdd, 0xe8, 0x05, 0xba, + 0x01, 0x10, 0x90, 0xfd, 0x70, 0xea, 0x3a, 0x87, 0x4e, 0xa8, 0x15, 0x1b, 0x52, 0x53, 0x16, 0xce, + 0xca, 0xcc, 0x3e, 0x64, 0x66, 0x06, 0x3a, 0x30, 0xa9, 0x2d, 0x40, 0xa5, 0x34, 0x88, 0xd9, 0x39, + 0x48, 0x7f, 0x21, 0x41, 0xed, 0x01, 0x71, 0xbc, 0x7f, 0xbf, 0x27, 0x8b, 0x7a, 0xc9, 0xaf, 0xab, + 0x5e, 0x4a, 0x46, 0xbd, 0xf4, 0x1f, 0x25, 0x80, 0x5d, 0x42, 0x43, 0x91, 0xe1, 0x08, 0x56, 0x04, + 0x93, 0x50, 0x1b, 0x53, 0xc7, 0x9b, 0x89, 0x5c, 0xd7, 0x32, 0x62, 0x18, 0x0b, 0x98, 0x88, 0x40, + 0x7c, 0x37, 0xb6, 0xa2, 0xbb, 0x80, 0x62, 0x47, 0xd3, 0x43, 0x33, 0xb4, 0x0e, 0xa6, 0x2e, 0xf6, + 0xce, 0xa4, 0xad, 0xc6, 0xef, 0x77, 0xd8, 0xeb, 0x21, 0xf6, 0xd0, 0x2a, 0xe4, 0xa3, 0xc6, 0xc8, + 0xa9, 0xc6, 0x44, 0x26, 0xfd, 0x6b, 0x09, 0xaa, 0xfd, 0x27, 0xa6, 0x3b, 0x37, 0x43, 0x12, 0x45, + 0xfc, 0x01, 0xe4, 0xc3, 0x67, 0x3e, 0x0e, 0x34, 0xa9, 0x21, 0x37, 0x6b, 0x99, 0x3d, 0x89, 0xf2, + 0x9d, 0x3c, 0xf3, 0x71, 0xeb, 0x63, 0xc7, 0xb3, 0x8d, 0x88, 0x84, 0x3e, 0x84, 0x3c, 0x3e, 0xf6, + 0x69, 0xa0, 0xe5, 0xf8, 0x78, 0x5f, 0xba, 0xd2, 0x11, 0x4b, 0xff, 0x14, 0x96, 0x7b, 0x4e, 0x10, + 0x3a, 0x9e, 0x15, 0xf2, 0x60, 0xda, 0x50, 0x7a, 0xb5, 0xba, 0x25, 0x34, 0xfd, 0xb9, 0x0c, 0x2b, + 0x3b, 0x98, 0xce, 0x30, 0x9b, 0x3d, 0xd1, 0x95, 0x07, 0x50, 0x75, 0xf1, 0xfe, 0xab, 0xf6, 0x64, + 0x99, 0x71, 0x93, 0x8e, 0x0c, 0xa1, 0x46, 0x9d, 0xd9, 0x41, 0xca, 0x59, 0xee, 0x2a, 0xce, 0xaa, + 0x9c, 0x9c, 0x78, 0xeb, 0x03, 0xf0, 0xc8, 0xa2, 0x16, 0xc8, 0x57, 0x6a, 0x41, 0x99, 0x31, 0x27, + 0xbc, 0x0d, 0x5b, 0x50, 0x89, 0x82, 0x8a, 0xfc, 0x28, 0x57, 0xf2, 0x03, 0x9c, 0x1a, 0x39, 0x7a, + 0x1f, 0x14, 0xd6, 0x99, 0xab, 0x0a, 0x0d, 0x27, 0xa1, 0x7b, 0xa0, 0xb0, 0xef, 0x6b, 0x85, 0x86, + 0xd4, 0xac, 0x65, 0x16, 0x84, 0xf5, 0x85, 0x7d, 0x2c, 0xa6, 0x32, 0xca, 0x39, 0x1b, 0x57, 0xcc, + 0xda, 0xb8, 0xef, 0x65, 0xa8, 0x6d, 0x9b, 0xc1, 0x41, 0xaa, 0xbf, 0xeb, 0xb0, 0xc2, 0xab, 0x88, + 0x8f, 0x12, 0xba, 0xb4, 0xa0, 0xb3, 0x57, 0xfd, 0xa3, 0x58, 0xe0, 0xde, 0x06, 0x35, 0x2a, 0x55, + 0x0a, 0x9c, 0x4b, 0xc0, 0x51, 0x6f, 0x17, 0xe8, 0xff, 0xfa, 0x73, 0xe5, 0xfe, 0xfc, 0x24, 0x43, + 0xad, 0x3d, 0x9b, 0x51, 0x3c, 0x7b, 0x4d, 0x1a, 0x73, 0x0d, 0x60, 0x46, 0xc9, 0xdc, 0x67, 0x9f, + 0x16, 0xbd, 0x32, 0xca, 0xdc, 0xd2, 0x25, 0x6e, 0x80, 0x36, 0x63, 0x09, 0x92, 0xb9, 0x04, 0xad, + 0x67, 0xa4, 0x75, 0x36, 0x24, 0x5e, 0xa2, 0x33, 0x5a, 0xb4, 0xfa, 0x8d, 0x04, 0x0a, 0xb3, 0xa2, + 0x1e, 0x28, 0xfb, 0x73, 0xcf, 0xe2, 0x22, 0x51, 0xbb, 0xac, 0xbf, 0xcd, 0xb9, 0x67, 0xc5, 0x15, + 0x63, 0x6c, 0xd4, 0x80, 0x92, 0x2d, 0xa4, 0x8d, 0x2b, 0x44, 0x7c, 0x33, 0x48, 0xac, 0xe8, 0x1a, + 0x14, 0x2d, 0xe2, 0xf2, 0x73, 0x4c, 0x4e, 0x09, 0x7a, 0xc1, 0x22, 0xee, 0xc0, 0x3e, 0xd6, 0xbf, + 0x94, 0x40, 0x61, 0x5e, 0x51, 0x19, 0xf2, 0x83, 0x5e, 0x7f, 0x34, 0x51, 0x97, 0x50, 0x11, 0xe4, + 0xf6, 0xc3, 0x2d, 0x55, 0x42, 0xcb, 0x50, 0xea, 0x8c, 0xc7, 0xc3, 0x69, 0x7b, 0xd4, 0x53, 0x73, + 0xa8, 0x02, 0x45, 0xfe, 0x6b, 0x6c, 0xa8, 0x32, 0xaa, 0x01, 0x74, 0xc7, 0xa3, 0x6e, 0x7b, 0x32, + 0x6d, 0x6f, 0x6d, 0xa9, 0x0a, 0xa3, 0x77, 0xc7, 0x7b, 0xa3, 0x89, 0x9a, 0x67, 0xf4, 0x9d, 0xf6, + 0x67, 0x6a, 0x91, 0x3f, 0x0c, 0x46, 0x6a, 0x09, 0x01, 0x14, 0x76, 0x27, 0xbd, 0x5e, 0xff, 0xa1, + 0x5a, 0x66, 0xc6, 0xdd, 0xbd, 0x1d, 0x15, 0x98, 0xf3, 0x87, 0x6d, 0x63, 0xd0, 0x1e, 0x75, 0xfb, + 0x6a, 0x45, 0xff, 0x53, 0x01, 0xf4, 0x49, 0x7c, 0x77, 0x65, 0x17, 0xb7, 0x3d, 0xcf, 0x21, 0x1e, + 0x7a, 0x17, 0x14, 0x8f, 0x10, 0x5f, 0x48, 0xe9, 0x8d, 0x8c, 0x2a, 0xa5, 0x2f, 0x7b, 0x06, 0x27, + 0xa0, 0x6d, 0xa8, 0x84, 0x8b, 0xdb, 0x8e, 0x50, 0xcf, 0x4b, 0xdd, 0x8b, 0xb0, 0x65, 0xa4, 0xa9, + 0x6c, 0x39, 0xbf, 0x48, 0x2e, 0x18, 0xe2, 0xac, 0xbf, 0x75, 0xc1, 0x54, 0xa7, 0xfc, 0xa4, 0x88, + 0xe8, 0x1e, 0x14, 0x02, 0x7e, 0x82, 0x6b, 0xca, 0x85, 0x5b, 0xb5, 0x38, 0xe6, 0x0d, 0x41, 0x60, + 0x11, 0x98, 0xc9, 0x1c, 0x88, 0xa5, 0xbc, 0x75, 0xa9, 0x81, 0x31, 0x52, 0x44, 0xd4, 0x81, 0x32, + 0x8e, 0x0f, 0x65, 0xbe, 0x9d, 0x95, 0xbb, 0x37, 0xb3, 0x56, 0x3b, 0x7d, 0x78, 0x1b, 0x0b, 0x1a, + 0xba, 0x9f, 0x9a, 0xb7, 0xe2, 0x85, 0x3d, 0x49, 0x9f, 0xb8, 0xa9, 0x71, 0xdc, 0x86, 0xca, 0xe1, + 0xe2, 0xdc, 0xe4, 0xb7, 0xba, 0xec, 0xbe, 0xbc, 0x74, 0xc2, 0x1a, 0x69, 0x2a, 0xab, 0xca, 0x41, + 0x22, 0xd0, 0x5a, 0xf9, 0xc2, 0xaa, 0x9c, 0x55, 0x72, 0x23, 0x45, 0x7c, 0x4f, 0x39, 0xf9, 0x61, + 0x4d, 0xd2, 0x7f, 0x93, 0xa0, 0x9a, 0x8c, 0x1f, 0x57, 0x93, 0x8f, 0x20, 0xef, 0x78, 0xfe, 0x3c, + 0xe4, 0x6a, 0x92, 0x5d, 0xa9, 0x01, 0xc3, 0xec, 0x3e, 0xf3, 0x2c, 0x46, 0x8a, 0x57, 0x9d, 0x13, + 0x51, 0x17, 0x14, 0x8b, 0x50, 0x2c, 0x66, 0xef, 0x76, 0x86, 0x83, 0xbf, 0x0f, 0x7d, 0xbc, 0xe0, + 0x8c, 0x8c, 0xfa, 0x50, 0x88, 0x84, 0x4f, 0x08, 0xcf, 0x5b, 0x59, 0x17, 0x00, 0x0e, 0x32, 0xc8, + 0x5c, 0x0c, 0x4f, 0xbc, 0xe6, 0x11, 0x59, 0xff, 0x4a, 0x82, 0xd2, 0xa6, 0x4b, 0x9e, 0xf2, 0xd4, + 0xee, 0x40, 0x71, 0xdf, 0x25, 0x4f, 0xa7, 0x8e, 0xcd, 0xf7, 0x6a, 0xb9, 0xa3, 0x31, 0xec, 0xaf, + 0xcf, 0xd7, 0x0a, 0x0c, 0x32, 0xe8, 0x9d, 0x26, 0x4f, 0x46, 0x81, 0x01, 0x07, 0x36, 0x7a, 0x00, + 0xb0, 0xf8, 0xcf, 0x52, 0x5c, 0xc3, 0x6e, 0xfe, 0x53, 0x46, 0xa9, 0x38, 0x52, 0xec, 0xf5, 0x4d, + 0x28, 0xc5, 0xea, 0xcf, 0x55, 0x67, 0x34, 0xea, 0x1b, 0xea, 0x12, 0x53, 0x94, 0x61, 0x7f, 0x73, + 0x32, 0x1d, 0xef, 0x4d, 0xfa, 0x86, 0x2a, 0xa1, 0x15, 0xa8, 0x18, 0x83, 0xad, 0xed, 0xd8, 0x90, + 0x63, 0x80, 0xcd, 0xbd, 0xe1, 0x50, 0xfc, 0x96, 0x3b, 0xd7, 0x4f, 0xfe, 0xa8, 0x2f, 0x9d, 0x9c, + 0xd6, 0xa5, 0x9f, 0x4f, 0xeb, 0xd2, 0x2f, 0xa7, 0x75, 0xe9, 0xf7, 0xd3, 0xba, 0xf4, 0xed, 0x8b, + 0xfa, 0xd2, 0xe7, 0x45, 0x11, 0xca, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9b, 0x1d, 0xc5, 0xbe, + 0x29, 0x0f, 0x00, 0x00, } diff --git a/pkg/sql/distsql/processors.proto b/pkg/sql/distsql/processors.proto index 7cb56198a51a..70269d8fb35b 100644 --- a/pkg/sql/distsql/processors.proto +++ b/pkg/sql/distsql/processors.proto @@ -159,9 +159,9 @@ message MergeJoinerSpec { // In the example above, left ordering describes C1+,C2- and right ordering // describes C5+,C4-. optional Ordering left_ordering = 1 [(gogoproto.nullable) = false]; - repeated sqlbase.ColumnType.Kind left_types = 2; + optional Ordering right_ordering = 2 [(gogoproto.nullable) = false]; - optional Ordering right_ordering = 3 [(gogoproto.nullable) = false]; + repeated sqlbase.ColumnType.Kind left_types = 3; repeated sqlbase.ColumnType.Kind right_types = 4; // "ON" expression (in addition to the equality constraints captured by the @@ -194,19 +194,22 @@ message HashJoinerSpec { repeated uint32 left_eq_columns = 1 [packed = true]; repeated uint32 right_eq_columns = 2 [packed = true]; + repeated sqlbase.ColumnType.Kind left_types = 3; + repeated sqlbase.ColumnType.Kind right_types = 4; + // "ON" expression (in addition to the equality constraints captured by the // orderings). Assuming that the left stream has N columns and the right // stream has M columns, in this expression variables $0 to $(N-1) refer to // columns of the left stream and variables $N to $(N+M-1) refer to columns in // the right stream. - optional Expression expr = 3 [(gogoproto.nullable) = false]; + optional Expression expr = 5 [(gogoproto.nullable) = false]; - optional JoinType type = 4 [(gogoproto.nullable) = false]; + optional JoinType type = 6 [(gogoproto.nullable) = false]; // Columns for the output stream. Assuming that the left stream has N columns // and the right stream has M columns, column indices 0 to (N-1) refer to left // stream columns and indices N to (N+M-1) refer to right stream columns. - repeated uint32 output_columns = 5 [packed = true]; + repeated uint32 output_columns = 7 [packed = true]; } // AggregatorSpec is the specification for an "aggregator" (processor core