github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/colexec/hash_utils_tmpl.go (about) 1 // Copyright 2020 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 hash_utils.eg.go. It's formatted in a 15 // special way, so it's both valid Go and a valid text/template input. This 16 // permits editing this file with editor support. 17 // 18 // */}} 19 20 package colexec 21 22 import ( 23 "context" 24 "fmt" 25 26 "github.com/cockroachdb/cockroach/pkg/col/coldata" 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/sqlbase" 30 "github.com/cockroachdb/cockroach/pkg/sql/types" 31 ) 32 33 // Remove unused warning. 34 var _ = execgen.UNSAFEGET 35 36 // {{/* 37 38 // _GOTYPESLICE is a template Go type slice variable. 39 type _GOTYPESLICE interface{} 40 41 // _CANONICAL_TYPE_FAMILY is the template variable. 42 const _CANONICAL_TYPE_FAMILY = types.UnknownFamily 43 44 // _TYPE_WIDTH is the template variable. 45 const _TYPE_WIDTH = 0 46 47 // _ASSIGN_HASH is the template equality function for assigning the first input 48 // to the result of the hash value of the second input. 49 func _ASSIGN_HASH(_, _, _, _ interface{}) uint64 { 50 colexecerror.InternalError("") 51 } 52 53 // */}} 54 55 // {{/* 56 func _REHASH_BODY( 57 ctx context.Context, 58 buckets []uint64, 59 keys _GOTYPESLICE, 60 nulls *coldata.Nulls, 61 nKeys int, 62 sel []int, 63 _HAS_SEL bool, 64 _HAS_NULLS bool, 65 ) { // */}} 66 // {{define "rehashBody" -}} 67 // Early bounds checks. 68 _ = buckets[nKeys-1] 69 // {{if .HasSel}} 70 _ = sel[nKeys-1] 71 // {{else}} 72 _ = execgen.UNSAFEGET(keys, nKeys-1) 73 // {{end}} 74 var selIdx int 75 for i := 0; i < nKeys; i++ { 76 cancelChecker.check(ctx) 77 // {{if .HasSel}} 78 selIdx = sel[i] 79 // {{else}} 80 selIdx = i 81 // {{end}} 82 // {{if .HasNulls}} 83 if nulls.NullAt(selIdx) { 84 continue 85 } 86 // {{end}} 87 v := execgen.UNSAFEGET(keys, selIdx) 88 p := uintptr(buckets[i]) 89 _ASSIGN_HASH(p, v, _, keys) 90 buckets[i] = uint64(p) 91 } 92 // {{end}} 93 94 // {{/* 95 } 96 97 // */}} 98 99 // rehash takes an element of a key (tuple representing a row of equality 100 // column values) at a given column and computes a new hash by applying a 101 // transformation to the existing hash. 102 func rehash( 103 ctx context.Context, 104 buckets []uint64, 105 col coldata.Vec, 106 nKeys int, 107 sel []int, 108 cancelChecker CancelChecker, 109 overloadHelper overloadHelper, 110 datumAlloc *sqlbase.DatumAlloc, 111 ) { 112 // In order to inline the templated code of overloads, we need to have a 113 // "_overloadHelper" local variable of type "overloadHelper". 114 _overloadHelper := overloadHelper 115 switch col.CanonicalTypeFamily() { 116 // {{range .}} 117 case _CANONICAL_TYPE_FAMILY: 118 switch col.Type().Width() { 119 // {{range .WidthOverloads}} 120 case _TYPE_WIDTH: 121 keys, nulls := col.TemplateType(), col.Nulls() 122 if col.MaybeHasNulls() { 123 if sel != nil { 124 _REHASH_BODY(ctx, buckets, keys, nulls, nKeys, sel, true, true) 125 } else { 126 _REHASH_BODY(ctx, buckets, keys, nulls, nKeys, sel, false, true) 127 } 128 } else { 129 if sel != nil { 130 _REHASH_BODY(ctx, buckets, keys, nulls, nKeys, sel, true, false) 131 } else { 132 _REHASH_BODY(ctx, buckets, keys, nulls, nKeys, sel, false, false) 133 } 134 } 135 // {{end}} 136 } 137 // {{end}} 138 default: 139 colexecerror.InternalError(fmt.Sprintf("unhandled type %s", col.Type())) 140 } 141 }