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  }