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 }