github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/colexec/proj_const_ops_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 proj_const_{left,right}_ops.eg.go.
    15  // It's formatted in a special way, so it's both valid Go and a valid
    16  // text/template input. This permits editing this file with editor support.
    17  //
    18  // */}}
    19  
    20  package colexec
    21  
    22  import (
    23  	"context"
    24  
    25  	"github.com/cockroachdb/cockroach/pkg/col/coldata"
    26  	"github.com/cockroachdb/cockroach/pkg/col/typeconv"
    27  	"github.com/cockroachdb/cockroach/pkg/sql/colexec/execgen"
    28  	"github.com/cockroachdb/cockroach/pkg/sql/colexecbase"
    29  	"github.com/cockroachdb/cockroach/pkg/sql/colexecbase/colexecerror"
    30  	"github.com/cockroachdb/cockroach/pkg/sql/colmem"
    31  	"github.com/cockroachdb/cockroach/pkg/sql/sem/tree"
    32  	"github.com/cockroachdb/cockroach/pkg/sql/types"
    33  	"github.com/cockroachdb/errors"
    34  )
    35  
    36  // Remove unused warning.
    37  var _ = execgen.UNSAFEGET
    38  
    39  // {{/*
    40  // Declarations to make the template compile properly.
    41  
    42  // _LEFT_CANONICAL_TYPE_FAMILY is the template variable.
    43  const _LEFT_CANONICAL_TYPE_FAMILY = types.UnknownFamily
    44  
    45  // _LEFT_TYPE_WIDTH is the template variable.
    46  const _LEFT_TYPE_WIDTH = 0
    47  
    48  // _RIGHT_CANONICAL_TYPE_FAMILY is the template variable.
    49  const _RIGHT_CANONICAL_TYPE_FAMILY = types.UnknownFamily
    50  
    51  // _RIGHT_TYPE_WIDTH is the template variable.
    52  const _RIGHT_TYPE_WIDTH = 0
    53  
    54  // _NON_CONST_GOTYPESLICE is a template Go type slice variable.
    55  type _NON_CONST_GOTYPESLICE interface{}
    56  
    57  // _ASSIGN is the template function for assigning the first input to the result
    58  // of computation an operation on the second and the third inputs.
    59  func _ASSIGN(_, _, _, _, _, _ interface{}) {
    60  	colexecerror.InternalError("")
    61  }
    62  
    63  // _RETURN_UNSAFEGET is the template function that will be replaced by
    64  // "execgen.UNSAFEGET" which uses _RET_TYP.
    65  func _RETURN_UNSAFEGET(_, _ interface{}) interface{} {
    66  	colexecerror.InternalError("")
    67  }
    68  
    69  // */}}
    70  
    71  // {{define "projConstOp"}}
    72  
    73  type _OP_CONST_NAME struct {
    74  	projConstOpBase
    75  	// {{if _IS_CONST_LEFT}}
    76  	constArg _L_GO_TYPE
    77  	// {{else}}
    78  	constArg _R_GO_TYPE
    79  	// {{end}}
    80  }
    81  
    82  func (p _OP_CONST_NAME) Next(ctx context.Context) coldata.Batch {
    83  	// In order to inline the templated code of overloads, we need to have a
    84  	// `_overloadHelper` local variable of type `overloadHelper`.
    85  	_overloadHelper := p.overloadHelper
    86  	// However, the scratch is not used in all of the projection operators, so
    87  	// we add this to go around "unused" error.
    88  	_ = _overloadHelper
    89  	batch := p.input.Next(ctx)
    90  	n := batch.Length()
    91  	if n == 0 {
    92  		return coldata.ZeroBatch
    93  	}
    94  	vec := batch.ColVec(p.colIdx)
    95  	var col _NON_CONST_GOTYPESLICE
    96  	// {{if _IS_CONST_LEFT}}
    97  	col = vec._R_TYP()
    98  	// {{else}}
    99  	col = vec._L_TYP()
   100  	// {{end}}
   101  	projVec := batch.ColVec(p.outputIdx)
   102  	if projVec.MaybeHasNulls() {
   103  		// We need to make sure that there are no left over null values in the
   104  		// output vector.
   105  		projVec.Nulls().UnsetNulls()
   106  	}
   107  	projCol := projVec._RET_TYP()
   108  	if vec.Nulls().MaybeHasNulls() {
   109  		_SET_PROJECTION(true)
   110  	} else {
   111  		_SET_PROJECTION(false)
   112  	}
   113  	// Although we didn't change the length of the batch, it is necessary to set
   114  	// the length anyway (this helps maintaining the invariant of flat bytes).
   115  	batch.SetLength(n)
   116  	return batch
   117  }
   118  
   119  func (p _OP_CONST_NAME) Init() {
   120  	p.input.Init()
   121  }
   122  
   123  // {{end}}
   124  
   125  // {{/*
   126  func _SET_PROJECTION(_HAS_NULLS bool) {
   127  	// */}}
   128  	// {{define "setProjection" -}}
   129  	// {{$hasNulls := $.HasNulls}}
   130  	// {{with $.Overload}}
   131  	// {{if _HAS_NULLS}}
   132  	colNulls := vec.Nulls()
   133  	// {{end}}
   134  	if sel := batch.Selection(); sel != nil {
   135  		sel = sel[:n]
   136  		for _, i := range sel {
   137  			_SET_SINGLE_TUPLE_PROJECTION(_HAS_NULLS)
   138  		}
   139  	} else {
   140  		col = execgen.SLICE(col, 0, n)
   141  		_ = _RETURN_UNSAFEGET(projCol, n-1)
   142  		for execgen.RANGE(i, col, 0, n) {
   143  			_SET_SINGLE_TUPLE_PROJECTION(_HAS_NULLS)
   144  		}
   145  	}
   146  	// {{if _HAS_NULLS}}
   147  	colNullsCopy := colNulls.Copy()
   148  	projVec.SetNulls(&colNullsCopy)
   149  	// {{end}}
   150  	// {{end}}
   151  	// {{end}}
   152  	// {{/*
   153  }
   154  
   155  // */}}
   156  
   157  // {{/*
   158  func _SET_SINGLE_TUPLE_PROJECTION(_HAS_NULLS bool) { // */}}
   159  	// {{define "setSingleTupleProjection" -}}
   160  	// {{$hasNulls := $.HasNulls}}
   161  	// {{with $.Overload}}
   162  	// {{if _HAS_NULLS}}
   163  	if !colNulls.NullAt(i) {
   164  		// We only want to perform the projection operation if the value is not null.
   165  		// {{end}}
   166  		arg := execgen.UNSAFEGET(col, i)
   167  		// {{if _IS_CONST_LEFT}}
   168  		_ASSIGN(projCol[i], p.constArg, arg, projCol, _, col)
   169  		// {{else}}
   170  		_ASSIGN(projCol[i], arg, p.constArg, projCol, col, _)
   171  		// {{end}}
   172  		// {{if _HAS_NULLS}}
   173  	}
   174  	// {{end}}
   175  	// {{end}}
   176  	// {{end}}
   177  	// {{/*
   178  }
   179  
   180  // */}}
   181  
   182  // {{range .BinOps}}
   183  // {{range .LeftFamilies}}
   184  // {{range .LeftWidths}}
   185  // {{range .RightFamilies}}
   186  // {{range .RightWidths}}
   187  
   188  // {{template "projConstOp" .}}
   189  
   190  // {{end}}
   191  // {{end}}
   192  // {{end}}
   193  // {{end}}
   194  // {{end}}
   195  
   196  // {{range .CmpOps}}
   197  // {{range .LeftFamilies}}
   198  // {{range .LeftWidths}}
   199  // {{range .RightFamilies}}
   200  // {{range .RightWidths}}
   201  
   202  // {{template "projConstOp" .}}
   203  
   204  // {{end}}
   205  // {{end}}
   206  // {{end}}
   207  // {{end}}
   208  // {{end}}
   209  
   210  // GetProjection_CONST_SIDEConstOperator returns the appropriate constant
   211  // projection operator for the given left and right column types and operation.
   212  func GetProjection_CONST_SIDEConstOperator(
   213  	allocator *colmem.Allocator,
   214  	leftType *types.T,
   215  	rightType *types.T,
   216  	outputType *types.T,
   217  	op tree.Operator,
   218  	input colexecbase.Operator,
   219  	colIdx int,
   220  	constArg tree.Datum,
   221  	outputIdx int,
   222  	overloadHelper overloadHelper,
   223  ) (colexecbase.Operator, error) {
   224  	input = newVectorTypeEnforcer(allocator, input, outputType, outputIdx)
   225  	projConstOpBase := projConstOpBase{
   226  		OneInputNode:   NewOneInputNode(input),
   227  		allocator:      allocator,
   228  		colIdx:         colIdx,
   229  		outputIdx:      outputIdx,
   230  		overloadHelper: overloadHelper,
   231  	}
   232  	var (
   233  		c   interface{}
   234  		err error
   235  	)
   236  	// {{if _IS_CONST_LEFT}}
   237  	c, err = getDatumToPhysicalFn(leftType)(constArg)
   238  	// {{else}}
   239  	c, err = getDatumToPhysicalFn(rightType)(constArg)
   240  	// {{end}}
   241  	if err != nil {
   242  		return nil, err
   243  	}
   244  	switch op.(type) {
   245  	case tree.BinaryOperator:
   246  		switch op {
   247  		// {{range .BinOps}}
   248  		case tree._NAME:
   249  			switch typeconv.TypeFamilyToCanonicalTypeFamily(leftType.Family()) {
   250  			// {{range .LeftFamilies}}
   251  			case _LEFT_CANONICAL_TYPE_FAMILY:
   252  				switch leftType.Width() {
   253  				// {{range .LeftWidths}}
   254  				case _LEFT_TYPE_WIDTH:
   255  					switch typeconv.TypeFamilyToCanonicalTypeFamily(rightType.Family()) {
   256  					// {{range .RightFamilies}}
   257  					case _RIGHT_CANONICAL_TYPE_FAMILY:
   258  						switch rightType.Width() {
   259  						// {{range .RightWidths}}
   260  						case _RIGHT_TYPE_WIDTH:
   261  							return &_OP_CONST_NAME{
   262  								projConstOpBase: projConstOpBase,
   263  								// {{if _IS_CONST_LEFT}}
   264  								constArg: c.(_L_GO_TYPE),
   265  								// {{else}}
   266  								constArg: c.(_R_GO_TYPE),
   267  								// {{end}}
   268  							}, nil
   269  							// {{end}}
   270  						}
   271  						// {{end}}
   272  					}
   273  					// {{end}}
   274  				}
   275  				// {{end}}
   276  			}
   277  			// {{end}}
   278  		}
   279  	case tree.ComparisonOperator:
   280  		switch op {
   281  		// {{range .CmpOps}}
   282  		case tree._NAME:
   283  			switch typeconv.TypeFamilyToCanonicalTypeFamily(leftType.Family()) {
   284  			// {{range .LeftFamilies}}
   285  			case _LEFT_CANONICAL_TYPE_FAMILY:
   286  				switch leftType.Width() {
   287  				// {{range .LeftWidths}}
   288  				case _LEFT_TYPE_WIDTH:
   289  					switch typeconv.TypeFamilyToCanonicalTypeFamily(rightType.Family()) {
   290  					// {{range .RightFamilies}}
   291  					case _RIGHT_CANONICAL_TYPE_FAMILY:
   292  						switch rightType.Width() {
   293  						// {{range .RightWidths}}
   294  						case _RIGHT_TYPE_WIDTH:
   295  							return &_OP_CONST_NAME{
   296  								projConstOpBase: projConstOpBase,
   297  								// {{if _IS_CONST_LEFT}}
   298  								constArg: c.(_L_GO_TYPE),
   299  								// {{else}}
   300  								constArg: c.(_R_GO_TYPE),
   301  								// {{end}}
   302  							}, nil
   303  							// {{end}}
   304  						}
   305  						// {{end}}
   306  					}
   307  					// {{end}}
   308  				}
   309  				// {{end}}
   310  			}
   311  			// {{end}}
   312  		}
   313  	}
   314  	return nil, errors.Errorf("couldn't find overload for %s %s %s", leftType.Name(), op, rightType.Name())
   315  }