github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/colexec/vec_comparators_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 vec_comparators.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/col/typeconv" 27 "github.com/cockroachdb/cockroach/pkg/sql/colexec/execgen" 28 "github.com/cockroachdb/cockroach/pkg/sql/colexecbase/colexecerror" 29 "github.com/cockroachdb/cockroach/pkg/sql/types" 30 ) 31 32 // Remove unused warning. 33 var _ = execgen.UNSAFEGET 34 35 // {{/* 36 37 // Declarations to make the template compile properly. 38 39 // _GOTYPESLICE is the template variable. 40 type _GOTYPESLICE interface{} 41 42 // _CANONICAL_TYPE_FAMILY is the template variable. 43 const _CANONICAL_TYPE_FAMILY = types.UnknownFamily 44 45 // _TYPE_WIDTH is the template variable. 46 const _TYPE_WIDTH = 0 47 48 // _COMPARE is the template equality function for assigning the first input 49 // to the result of comparing second and third inputs. 50 func _COMPARE(_, _, _, _, _ string) bool { 51 colexecerror.InternalError("") 52 } 53 54 // */}} 55 56 // vecComparator is a helper for the ordered synchronizer. It stores multiple 57 // column vectors of a single type and facilitates comparing values between 58 // them. 59 type vecComparator interface { 60 // compare compares values from two vectors. vecIdx is the index of the vector 61 // and valIdx is the index of the value in that vector to compare. Returns -1, 62 // 0, or 1. 63 compare(vecIdx1, vecIdx2 int, valIdx1, valIdx2 int) int 64 65 // set sets the value of the vector at dstVecIdx at index dstValIdx to the value 66 // at the vector at srcVecIdx at index srcValIdx. 67 // NOTE: whenever set is used, the caller is responsible for updating the 68 // memory accounts. 69 set(srcVecIdx, dstVecIdx int, srcValIdx, dstValIdx int) 70 71 // setVec updates the vector at idx. 72 setVec(idx int, vec coldata.Vec) 73 } 74 75 // {{range .}} 76 // {{range .WidthOverloads}} 77 type _TYPEVecComparator struct { 78 vecs []_GOTYPESLICE 79 nulls []*coldata.Nulls 80 } 81 82 func (c *_TYPEVecComparator) compare(vecIdx1, vecIdx2 int, valIdx1, valIdx2 int) int { 83 n1 := c.nulls[vecIdx1].MaybeHasNulls() && c.nulls[vecIdx1].NullAt(valIdx1) 84 n2 := c.nulls[vecIdx2].MaybeHasNulls() && c.nulls[vecIdx2].NullAt(valIdx2) 85 if n1 && n2 { 86 return 0 87 } else if n1 { 88 return -1 89 } else if n2 { 90 return 1 91 } 92 left := execgen.UNSAFEGET(c.vecs[vecIdx1], valIdx1) 93 right := execgen.UNSAFEGET(c.vecs[vecIdx2], valIdx2) 94 var cmp int 95 _COMPARE(cmp, left, right, c.vecs[vecIdx1], c.vecs[vecIdx2]) 96 return cmp 97 } 98 99 func (c *_TYPEVecComparator) setVec(idx int, vec coldata.Vec) { 100 c.vecs[idx] = vec._TYPE() 101 c.nulls[idx] = vec.Nulls() 102 } 103 104 func (c *_TYPEVecComparator) set(srcVecIdx, dstVecIdx int, srcIdx, dstIdx int) { 105 if c.nulls[srcVecIdx].MaybeHasNulls() && c.nulls[srcVecIdx].NullAt(srcIdx) { 106 c.nulls[dstVecIdx].SetNull(dstIdx) 107 } else { 108 c.nulls[dstVecIdx].UnsetNull(dstIdx) 109 // {{if eq .VecMethod "Bytes"}} 110 // Since flat Bytes cannot be set at arbitrary indices (data needs to be 111 // moved around), we use CopySlice to accept the performance hit. 112 // Specifically, this is a performance hit because we are overwriting the 113 // variable number of bytes in `dstVecIdx`, so we will have to either shift 114 // the bytes after that element left or right, depending on how long the 115 // source bytes slice is. Refer to the CopySlice comment for an example. 116 execgen.COPYSLICE(c.vecs[dstVecIdx], c.vecs[srcVecIdx], dstIdx, srcIdx, srcIdx+1) 117 // {{else}} 118 v := execgen.UNSAFEGET(c.vecs[srcVecIdx], srcIdx) 119 execgen.SET(c.vecs[dstVecIdx], dstIdx, v) 120 // {{end}} 121 } 122 } 123 124 // {{end}} 125 // {{end}} 126 127 func GetVecComparator(t *types.T, numVecs int) vecComparator { 128 switch typeconv.TypeFamilyToCanonicalTypeFamily(t.Family()) { 129 // {{range .}} 130 case _CANONICAL_TYPE_FAMILY: 131 switch t.Width() { 132 // {{range .WidthOverloads}} 133 case _TYPE_WIDTH: 134 return &_TYPEVecComparator{ 135 vecs: make([]_GOTYPESLICE, numVecs), 136 nulls: make([]*coldata.Nulls, numVecs), 137 } 138 // {{end}} 139 } 140 // {{end}} 141 } 142 colexecerror.InternalError(fmt.Sprintf("unhandled type %s", t)) 143 // This code is unreachable, but the compiler cannot infer that. 144 return nil 145 }