github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/col/coldata/vec_tmpl.go (about) 1 // Copyright 2018 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 //go:build execgen_template 13 // +build execgen_template 14 15 // 16 // This file is the execgen template for vec.eg.go. It's formatted in a 17 // special way, so it's both valid Go and a valid text/template input. This 18 // permits editing this file with editor support. 19 // 20 // */}} 21 22 package coldata 23 24 import ( 25 "fmt" 26 27 "github.com/cockroachdb/apd/v3" 28 "github.com/cockroachdb/cockroachdb-parser/pkg/col/typeconv" 29 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/colexec/execgen" 30 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/colexecerror" 31 "github.com/cockroachdb/cockroachdb-parser/pkg/sql/types" 32 "github.com/cockroachdb/cockroachdb-parser/pkg/util/duration" 33 "github.com/cockroachdb/cockroachdb-parser/pkg/util/json" 34 "github.com/cockroachdb/errors" 35 ) 36 37 // Workaround for bazel auto-generated code. goimports does not automatically 38 // pick up the right packages when run within the bazel sandbox. 39 var ( 40 _ = typeconv.DatumVecCanonicalTypeFamily 41 _ apd.Context 42 _ duration.Duration 43 _ json.JSON 44 _ = colexecerror.InternalError 45 _ = errors.AssertionFailedf 46 ) 47 48 // {{/* 49 50 // _GOTYPESLICE is the template variable. 51 type _GOTYPESLICE interface{} 52 53 // _CANONICAL_TYPE_FAMILY is the template variable. 54 const _CANONICAL_TYPE_FAMILY = types.UnknownFamily 55 56 // _TYPE_WIDTH is the template variable. 57 const _TYPE_WIDTH = 0 58 59 // */}} 60 61 // TypedVecs represents a slice of Vecs that have been converted into the typed 62 // columns. The idea is that every Vec is stored both in Vecs slice as well as 63 // in the typed slice, in order. Components that know the type of the vector 64 // they are working with can then access the typed column directly, avoiding 65 // expensive type casts. 66 type TypedVecs struct { 67 Vecs []Vec 68 Nulls []*Nulls 69 70 // Fields below need to be accessed by an index mapped via ColsMap. 71 // {{range .}} 72 // {{range .WidthOverloads}} 73 _TYPECols []_GOTYPESLICE 74 // {{end}} 75 // {{end}} 76 // ColsMap contains the positions of the corresponding vectors in the slice 77 // for the same types. For example, if we have a batch with 78 // types = [Int64, Int64, Bool, Bytes, Bool, Int64], 79 // then ColsMap will be 80 // [0, 1, 0, 0, 1, 2] 81 // ^ ^ ^ ^ ^ ^ 82 // | | | | | | 83 // | | | | | 3rd among all Int64's 84 // | | | | 2nd among all Bool's 85 // | | | 1st among all Bytes's 86 // | | 1st among all Bool's 87 // | 2nd among all Int64's 88 // 1st among all Int64's 89 ColsMap []int 90 } 91 92 // SetBatch updates TypedVecs to represent all vectors from batch. 93 func (v *TypedVecs) SetBatch(batch Batch) { 94 v.Vecs = batch.ColVecs() 95 if cap(v.Nulls) < len(v.Vecs) { 96 v.Nulls = make([]*Nulls, len(v.Vecs)) 97 v.ColsMap = make([]int, len(v.Vecs)) 98 } else { 99 v.Nulls = v.Nulls[:len(v.Vecs)] 100 v.ColsMap = v.ColsMap[:len(v.Vecs)] 101 } 102 // {{range .}} 103 // {{range .WidthOverloads}} 104 v._TYPECols = v._TYPECols[:0] 105 // {{end}} 106 // {{end}} 107 for i, vec := range v.Vecs { 108 v.Nulls[i] = vec.Nulls() 109 switch vec.CanonicalTypeFamily() { 110 // {{range .}} 111 case _CANONICAL_TYPE_FAMILY: 112 switch vec.Type().Width() { 113 // {{range .WidthOverloads}} 114 case _TYPE_WIDTH: 115 v.ColsMap[i] = len(v._TYPECols) 116 v._TYPECols = append(v._TYPECols, vec.TemplateType()) 117 // {{end}} 118 } 119 // {{end}} 120 default: 121 colexecerror.InternalError(errors.AssertionFailedf("unhandled type %s", vec.Type())) 122 } 123 } 124 } 125 126 // Reset performs a deep reset of v while keeping the references to the slices. 127 func (v *TypedVecs) Reset() { 128 v.Vecs = nil 129 for i := range v.Nulls { 130 v.Nulls[i] = nil 131 } 132 // {{range .}} 133 // {{range .WidthOverloads}} 134 for i := range v._TYPECols { 135 v._TYPECols[i] = nil 136 } 137 // {{end}} 138 // {{end}} 139 } 140 141 func (m *memColumn) Append(args SliceArgs) { 142 switch m.CanonicalTypeFamily() { 143 // {{range .}} 144 case _CANONICAL_TYPE_FAMILY: 145 switch m.t.Width() { 146 // {{range .WidthOverloads}} 147 case _TYPE_WIDTH: 148 fromCol := args.Src.TemplateType() 149 toCol := m.TemplateType() 150 // NOTE: it is unfortunate that we always append whole slice without paying 151 // attention to whether the values are NULL. However, if we do start paying 152 // attention, the performance suffers dramatically, so we choose to copy 153 // over "actual" as well as "garbage" values. 154 if args.Sel == nil { 155 execgen.APPENDSLICE(toCol, fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) 156 } else { 157 sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] 158 // {{if .IsBytesLike }} 159 toCol.appendSliceWithSel(fromCol, args.DestIdx, sel) 160 // {{else}} 161 // {{/* Here Window means slicing which allows us to use APPENDVAL below. */}} 162 toCol = toCol.Window(0, args.DestIdx) 163 for _, selIdx := range sel { 164 val := fromCol.Get(selIdx) 165 execgen.APPENDVAL(toCol, val) 166 } 167 // {{end}} 168 } 169 m.nulls.set(args) 170 m.col = toCol 171 // {{end}} 172 } 173 // {{end}} 174 default: 175 panic(fmt.Sprintf("unhandled type %s", m.t)) 176 } 177 } 178 179 func (m *memColumn) Copy(args SliceArgs) { 180 if args.SrcStartIdx == args.SrcEndIdx { 181 // Nothing to copy, so return early. 182 return 183 } 184 if m.Nulls().MaybeHasNulls() { 185 // We're about to overwrite this entire range, so unset all the nulls. 186 m.Nulls().UnsetNullRange(args.DestIdx, args.DestIdx+(args.SrcEndIdx-args.SrcStartIdx)) 187 } 188 189 switch m.CanonicalTypeFamily() { 190 // {{range .}} 191 case _CANONICAL_TYPE_FAMILY: 192 switch m.t.Width() { 193 // {{range .WidthOverloads}} 194 case _TYPE_WIDTH: 195 fromCol := args.Src.TemplateType() 196 toCol := m.TemplateType() 197 if args.Sel != nil { 198 sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] 199 n := len(sel) 200 // {{if .Sliceable}} 201 toCol = toCol[args.DestIdx:] 202 _ = toCol[n-1] 203 // {{end}} 204 if args.Src.MaybeHasNulls() { 205 nulls := args.Src.Nulls() 206 for i := 0; i < n; i++ { 207 //gcassert:bce 208 selIdx := sel[i] 209 if nulls.NullAt(selIdx) { 210 m.nulls.SetNull(i + args.DestIdx) 211 } else { 212 // {{if .IsBytesLike}} 213 toCol.Copy(fromCol, i+args.DestIdx, selIdx) 214 // {{else}} 215 v := fromCol.Get(selIdx) 216 // {{if .Sliceable}} 217 // {{/* 218 // For the sliceable types, we sliced toCol to start at 219 // args.DestIdx, so we use index i directly. 220 // */}} 221 //gcassert:bce 222 toCol.Set(i, v) 223 // {{else}} 224 // {{/* 225 // For the non-sliceable types, toCol vector is the original 226 // one (i.e. without an adjustment), so we need to add 227 // args.DestIdx to set the element at the correct index. 228 // */}} 229 toCol.Set(i+args.DestIdx, v) 230 // {{end}} 231 // {{end}} 232 } 233 } 234 return 235 } 236 // No Nulls. 237 for i := 0; i < n; i++ { 238 //gcassert:bce 239 selIdx := sel[i] 240 // {{if .IsBytesLike}} 241 toCol.Copy(fromCol, i+args.DestIdx, selIdx) 242 // {{else}} 243 v := fromCol.Get(selIdx) 244 // {{if .Sliceable}} 245 // {{/* 246 // For the sliceable types, we sliced toCol to start at 247 // args.DestIdx, so we use index i directly. 248 // */}} 249 //gcassert:bce 250 toCol.Set(i, v) 251 // {{else}} 252 // {{/* 253 // For the non-sliceable types, toCol vector is the original one 254 // (i.e. without an adjustment), so we need to add args.DestIdx to 255 // set the element at the correct index. 256 // */}} 257 toCol.Set(i+args.DestIdx, v) 258 // {{end}} 259 // {{end}} 260 } 261 return 262 } 263 // No Sel. 264 toCol.CopySlice(fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) 265 m.nulls.set(args) 266 // {{end}} 267 } 268 // {{end}} 269 default: 270 panic(fmt.Sprintf("unhandled type %s", m.t)) 271 } 272 } 273 274 // {{/* 275 func _COPY_WITH_REORDERED_SOURCE(_SRC_HAS_NULLS bool) { // */}} 276 // {{define "copyWithReorderedSource" -}} 277 for i := 0; i < n; i++ { 278 //gcassert:bce 279 destIdx := sel[i] 280 srcIdx := order[destIdx] 281 // {{if .SrcHasNulls}} 282 if nulls.NullAt(srcIdx) { 283 m.nulls.SetNull(destIdx) 284 } else 285 // {{end}} 286 { 287 // {{if .Global.IsBytesLike}} 288 toCol.Copy(fromCol, destIdx, srcIdx) 289 // {{else}} 290 v := fromCol.Get(srcIdx) 291 toCol.Set(destIdx, v) 292 // {{end}} 293 } 294 } 295 // {{end}} 296 // {{/* 297 } 298 299 // */}} 300 301 func (m *memColumn) CopyWithReorderedSource(src Vec, sel, order []int) { 302 if len(sel) == 0 { 303 return 304 } 305 if m.nulls.MaybeHasNulls() { 306 m.nulls.UnsetNulls() 307 } 308 switch m.CanonicalTypeFamily() { 309 // {{range .}} 310 case _CANONICAL_TYPE_FAMILY: 311 switch m.t.Width() { 312 // {{range .WidthOverloads}} 313 case _TYPE_WIDTH: 314 fromCol := src.TemplateType() 315 toCol := m.TemplateType() 316 n := len(sel) 317 _ = sel[n-1] 318 if src.MaybeHasNulls() { 319 nulls := src.Nulls() 320 _COPY_WITH_REORDERED_SOURCE(true) 321 } else { 322 _COPY_WITH_REORDERED_SOURCE(false) 323 } 324 // {{end}} 325 } 326 // {{end}} 327 default: 328 panic(fmt.Sprintf("unhandled type %s", m.t)) 329 } 330 } 331 332 func (m *memColumn) Window(start int, end int) Vec { 333 switch m.CanonicalTypeFamily() { 334 // {{range .}} 335 case _CANONICAL_TYPE_FAMILY: 336 switch m.t.Width() { 337 // {{range .WidthOverloads}} 338 case _TYPE_WIDTH: 339 col := m.TemplateType() 340 return &memColumn{ 341 t: m.t, 342 canonicalTypeFamily: m.canonicalTypeFamily, 343 col: col.Window(start, end), 344 nulls: m.nulls.Slice(start, end), 345 } 346 // {{end}} 347 } 348 // {{end}} 349 } 350 panic(fmt.Sprintf("unhandled type %s", m.t)) 351 } 352 353 // SetValueAt is an inefficient helper to set the value in a Vec when the type 354 // is unknown. 355 func SetValueAt(v Vec, elem interface{}, rowIdx int) { 356 switch t := v.Type(); v.CanonicalTypeFamily() { 357 // {{range .}} 358 case _CANONICAL_TYPE_FAMILY: 359 switch t.Width() { 360 // {{range .WidthOverloads}} 361 case _TYPE_WIDTH: 362 target := v.TemplateType() 363 newVal := elem.(_GOTYPE) 364 target.Set(rowIdx, newVal) 365 // {{end}} 366 } 367 // {{end}} 368 default: 369 panic(fmt.Sprintf("unhandled type %s", t)) 370 } 371 } 372 373 // GetValueAt is an inefficient helper to get the value in a Vec when the type 374 // is unknown. 375 func GetValueAt(v Vec, rowIdx int) interface{} { 376 if v.Nulls().NullAt(rowIdx) { 377 return nil 378 } 379 t := v.Type() 380 switch v.CanonicalTypeFamily() { 381 // {{range .}} 382 case _CANONICAL_TYPE_FAMILY: 383 switch t.Width() { 384 // {{range .WidthOverloads}} 385 case _TYPE_WIDTH: 386 target := v.TemplateType() 387 return target.Get(rowIdx) 388 // {{end}} 389 } 390 // {{end}} 391 } 392 panic(fmt.Sprintf("unhandled type %s", t)) 393 }