github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/colexec/mergejoinbase_tmpl.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 // {{/* 12 // +build execgen_template 13 // 14 // This file is the execgen template for mergejoinbase.eg.go. It's formatted 15 // in a special way, so it's both valid Go and a valid text/template input. 16 // This permits editing this file with editor support. 17 // 18 // */}} 19 20 package colexec 21 22 import ( 23 "fmt" 24 25 "github.com/cockroachdb/cockroach/pkg/col/coldata" 26 "github.com/cockroachdb/cockroach/pkg/sql/colexec/execgen" 27 "github.com/cockroachdb/cockroach/pkg/sql/colexecbase/colexecerror" 28 "github.com/cockroachdb/cockroach/pkg/sql/types" 29 ) 30 31 // Remove unused warning. 32 var _ = execgen.UNSAFEGET 33 34 // {{/* 35 // Declarations to make the template compile properly. 36 37 // _CANONICAL_TYPE_FAMILY is the template variable. 38 const _CANONICAL_TYPE_FAMILY = types.UnknownFamily 39 40 // _TYPE_WIDTH is the template variable. 41 const _TYPE_WIDTH = 0 42 43 // _ASSIGN_EQ is the template equality function for assigning the first input 44 // to the result of the the second input == the third input. 45 func _ASSIGN_EQ(_, _, _, _, _, _ interface{}) int { 46 colexecerror.InternalError("") 47 } 48 49 // */}} 50 51 // isBufferedGroupFinished checks to see whether or not the buffered group 52 // corresponding to input continues in batch. 53 func (o *mergeJoinBase) isBufferedGroupFinished( 54 input *mergeJoinInput, batch coldata.Batch, rowIdx int, 55 ) bool { 56 if batch.Length() == 0 { 57 return true 58 } 59 bufferedGroup := o.proberState.lBufferedGroup 60 if input == &o.right { 61 bufferedGroup = o.proberState.rBufferedGroup 62 } 63 tupleToLookAtIdx := rowIdx 64 sel := batch.Selection() 65 if sel != nil { 66 tupleToLookAtIdx = sel[rowIdx] 67 } 68 69 // Check all equality columns in the first row of batch to make sure we're in 70 // the same group. 71 for _, colIdx := range input.eqCols[:len(input.eqCols)] { 72 switch input.canonicalTypeFamilies[colIdx] { 73 // {{range .}} 74 case _CANONICAL_TYPE_FAMILY: 75 switch input.sourceTypes[colIdx].Width() { 76 // {{range .WidthOverloads}} 77 case _TYPE_WIDTH: 78 // We perform this null check on every equality column of the first 79 // buffered tuple regardless of the join type since it is done only once 80 // per batch. In some cases (like INNER join, or LEFT OUTER join with the 81 // right side being an input) this check will always return false since 82 // nulls couldn't be buffered up though. 83 // TODO(yuzefovich): consider templating this. 84 bufferedNull := bufferedGroup.firstTuple[colIdx].MaybeHasNulls() && bufferedGroup.firstTuple[colIdx].Nulls().NullAt(0) 85 incomingNull := batch.ColVec(int(colIdx)).MaybeHasNulls() && batch.ColVec(int(colIdx)).Nulls().NullAt(tupleToLookAtIdx) 86 if o.joinType.IsSetOpJoin() { 87 if bufferedNull && incomingNull { 88 // We have a NULL match, so move onto the next column. 89 continue 90 } 91 } 92 if bufferedNull || incomingNull { 93 return true 94 } 95 bufferedCol := bufferedGroup.firstTuple[colIdx].TemplateType() 96 prevVal := execgen.UNSAFEGET(bufferedCol, 0) 97 col := batch.ColVec(int(colIdx)).TemplateType() 98 curVal := execgen.UNSAFEGET(col, tupleToLookAtIdx) 99 var match bool 100 _ASSIGN_EQ(match, prevVal, curVal, _, bufferedCol, col) 101 if !match { 102 return true 103 } 104 // {{end}} 105 } 106 // {{end}} 107 default: 108 colexecerror.InternalError(fmt.Sprintf("unhandled type %s", input.sourceTypes[colIdx])) 109 } 110 } 111 return false 112 }