github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/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 // +build execgen_template 13 // 14 // This file is the execgen template for vec.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 coldata 21 22 import ( 23 "fmt" 24 25 "github.com/cockroachdb/cockroach/pkg/sql/colexec/execgen" 26 "github.com/cockroachdb/cockroach/pkg/sql/types" 27 ) 28 29 // {{/* 30 31 // _GOTYPESLICE is the template variable. 32 type _GOTYPESLICE interface{} 33 34 // _CANONICAL_TYPE_FAMILY is the template variable. 35 const _CANONICAL_TYPE_FAMILY = types.UnknownFamily 36 37 // _TYPE_WIDTH is the template variable. 38 const _TYPE_WIDTH = 0 39 40 // */}} 41 42 func (m *memColumn) Append(args SliceArgs) { 43 switch m.CanonicalTypeFamily() { 44 // {{range .}} 45 case _CANONICAL_TYPE_FAMILY: 46 switch m.t.Width() { 47 // {{range .WidthOverloads}} 48 case _TYPE_WIDTH: 49 fromCol := args.Src.TemplateType() 50 toCol := m.TemplateType() 51 // NOTE: it is unfortunate that we always append whole slice without paying 52 // attention to whether the values are NULL. However, if we do start paying 53 // attention, the performance suffers dramatically, so we choose to copy 54 // over "actual" as well as "garbage" values. 55 if args.Sel == nil { 56 execgen.APPENDSLICE(toCol, fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) 57 } else { 58 sel := args.Sel[args.SrcStartIdx:args.SrcEndIdx] 59 // {{if eq .VecMethod "Bytes"}} 60 // We need to truncate toCol before appending to it, so in case of Bytes, 61 // we append an empty slice. 62 execgen.APPENDSLICE(toCol, toCol, args.DestIdx, 0, 0) 63 // We will be getting all values below to be appended, regardless of 64 // whether the value is NULL. It is possible that Bytes' invariant of 65 // non-decreasing offsets on the source is currently not maintained, so 66 // we explicitly enforce it. 67 maxIdx := 0 68 for _, selIdx := range sel { 69 if selIdx > maxIdx { 70 maxIdx = selIdx 71 } 72 } 73 fromCol.UpdateOffsetsToBeNonDecreasing(maxIdx + 1) 74 // {{else}} 75 toCol = execgen.SLICE(toCol, 0, args.DestIdx) 76 // {{end}} 77 for _, selIdx := range sel { 78 val := execgen.UNSAFEGET(fromCol, selIdx) 79 execgen.APPENDVAL(toCol, val) 80 } 81 } 82 m.nulls.set(args) 83 m.col = toCol 84 // {{end}} 85 } 86 // {{end}} 87 default: 88 panic(fmt.Sprintf("unhandled type %s", m.t)) 89 } 90 } 91 92 // {{/* 93 func _COPY_WITH_SEL( 94 m *memColumn, args CopySliceArgs, fromCol, toCol _GOTYPESLICE, sel interface{}, _SEL_ON_DEST bool, 95 ) { // */}} 96 // {{define "copyWithSel" -}} 97 if args.Src.MaybeHasNulls() { 98 nulls := args.Src.Nulls() 99 for i, selIdx := range sel[args.SrcStartIdx:args.SrcEndIdx] { 100 if nulls.NullAt(selIdx) { 101 // {{if .SelOnDest}} 102 // Remove an unused warning in some cases. 103 _ = i 104 m.nulls.SetNull(selIdx) 105 // {{else}} 106 m.nulls.SetNull(i + args.DestIdx) 107 // {{end}} 108 } else { 109 // {{with .Global}} 110 v := execgen.UNSAFEGET(fromCol, selIdx) 111 // {{end}} 112 // {{if .SelOnDest}} 113 m.nulls.UnsetNull(selIdx) 114 // {{with .Global}} 115 execgen.SET(toCol, selIdx, v) 116 // {{end}} 117 // {{else}} 118 // {{with .Global}} 119 execgen.SET(toCol, i+args.DestIdx, v) 120 // {{end}} 121 // {{end}} 122 } 123 } 124 return 125 } 126 // No Nulls. 127 for i := range sel[args.SrcStartIdx:args.SrcEndIdx] { 128 selIdx := sel[args.SrcStartIdx+i] 129 // {{with .Global}} 130 v := execgen.UNSAFEGET(fromCol, selIdx) 131 // {{end}} 132 // {{if .SelOnDest}} 133 // {{with .Global}} 134 execgen.SET(toCol, selIdx, v) 135 // {{end}} 136 // {{else}} 137 // {{with .Global}} 138 execgen.SET(toCol, i+args.DestIdx, v) 139 // {{end}} 140 // {{end}} 141 } 142 // {{end}} 143 // {{/* 144 } 145 146 // */}} 147 148 func (m *memColumn) Copy(args CopySliceArgs) { 149 if !args.SelOnDest { 150 // We're about to overwrite this entire range, so unset all the nulls. 151 m.Nulls().UnsetNullRange(args.DestIdx, args.DestIdx+(args.SrcEndIdx-args.SrcStartIdx)) 152 } 153 // } else { 154 // SelOnDest indicates that we're applying the input selection vector as a lens 155 // into the output vector as well. We'll set the non-nulls by hand below. 156 // } 157 158 switch m.CanonicalTypeFamily() { 159 // {{range .}} 160 case _CANONICAL_TYPE_FAMILY: 161 switch m.t.Width() { 162 // {{range .WidthOverloads}} 163 case _TYPE_WIDTH: 164 fromCol := args.Src.TemplateType() 165 toCol := m.TemplateType() 166 if args.Sel != nil { 167 sel := args.Sel 168 if args.SelOnDest { 169 _COPY_WITH_SEL(m, args, sel, toCol, fromCol, true) 170 } else { 171 _COPY_WITH_SEL(m, args, sel, toCol, fromCol, false) 172 } 173 return 174 } 175 // No Sel. 176 execgen.COPYSLICE(toCol, fromCol, args.DestIdx, args.SrcStartIdx, args.SrcEndIdx) 177 m.nulls.set(args.SliceArgs) 178 // {{end}} 179 } 180 // {{end}} 181 default: 182 panic(fmt.Sprintf("unhandled type %s", m.t)) 183 } 184 } 185 186 func (m *memColumn) Window(start int, end int) Vec { 187 switch m.CanonicalTypeFamily() { 188 // {{range .}} 189 case _CANONICAL_TYPE_FAMILY: 190 switch m.t.Width() { 191 // {{range .WidthOverloads}} 192 case _TYPE_WIDTH: 193 col := m.TemplateType() 194 return &memColumn{ 195 t: m.t, 196 canonicalTypeFamily: m.canonicalTypeFamily, 197 col: execgen.WINDOW(col, start, end), 198 nulls: m.nulls.Slice(start, end), 199 } 200 // {{end}} 201 } 202 // {{end}} 203 } 204 panic(fmt.Sprintf("unhandled type %s", m.t)) 205 } 206 207 // SetValueAt is an inefficient helper to set the value in a Vec when the type 208 // is unknown. 209 func SetValueAt(v Vec, elem interface{}, rowIdx int) { 210 switch t := v.Type(); v.CanonicalTypeFamily() { 211 // {{range .}} 212 case _CANONICAL_TYPE_FAMILY: 213 switch t.Width() { 214 // {{range .WidthOverloads}} 215 case _TYPE_WIDTH: 216 target := v.TemplateType() 217 newVal := elem.(_GOTYPE) 218 execgen.SET(target, rowIdx, newVal) 219 // {{end}} 220 } 221 // {{end}} 222 default: 223 panic(fmt.Sprintf("unhandled type %s", t)) 224 } 225 } 226 227 // GetValueAt is an inefficient helper to get the value in a Vec when the type 228 // is unknown. 229 func GetValueAt(v Vec, rowIdx int) interface{} { 230 t := v.Type() 231 switch v.CanonicalTypeFamily() { 232 // {{range .}} 233 case _CANONICAL_TYPE_FAMILY: 234 switch t.Width() { 235 // {{range .WidthOverloads}} 236 case _TYPE_WIDTH: 237 target := v.TemplateType() 238 return execgen.UNSAFEGET(target, rowIdx) 239 // {{end}} 240 } 241 // {{end}} 242 } 243 panic(fmt.Sprintf("unhandled type %s", t)) 244 }