github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/colexec/sum_agg_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 sum_agg.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 "unsafe" 24 25 "github.com/cockroachdb/cockroach/pkg/col/coldata" 26 "github.com/cockroachdb/cockroach/pkg/col/typeconv" 27 "github.com/cockroachdb/cockroach/pkg/sql/colexecbase/colexecerror" 28 "github.com/cockroachdb/cockroach/pkg/sql/colmem" 29 "github.com/cockroachdb/cockroach/pkg/sql/types" 30 "github.com/cockroachdb/errors" 31 ) 32 33 // {{/* 34 // Declarations to make the template compile properly 35 36 // _CANONICAL_TYPE_FAMILY is the template variable. 37 const _CANONICAL_TYPE_FAMILY = types.UnknownFamily 38 39 // _TYPE_WIDTH is the template variable. 40 const _TYPE_WIDTH = 0 41 42 // _ASSIGN_ADD is the template addition function for assigning the first input 43 // to the result of the second input + the third input. 44 func _ASSIGN_ADD(_, _, _, _, _, _ string) { 45 colexecerror.InternalError("") 46 } 47 48 // */}} 49 50 func newSumAggAlloc( 51 allocator *colmem.Allocator, t *types.T, allocSize int64, 52 ) (aggregateFuncAlloc, error) { 53 switch typeconv.TypeFamilyToCanonicalTypeFamily(t.Family()) { 54 // {{range .}} 55 case _CANONICAL_TYPE_FAMILY: 56 switch t.Width() { 57 // {{range .WidthOverloads}} 58 case _TYPE_WIDTH: 59 return &sum_TYPEAggAlloc{allocator: allocator, allocSize: allocSize}, nil 60 // {{end}} 61 } 62 // {{end}} 63 } 64 return nil, errors.Errorf("unsupported sum agg type %s", t) 65 } 66 67 // {{range .}} 68 // {{range .WidthOverloads}} 69 70 type sum_TYPEAgg struct { 71 groups []bool 72 scratch struct { 73 curIdx int 74 // curAgg holds the running total, so we can index into the slice once per 75 // group, instead of on each iteration. 76 curAgg _GOTYPE 77 // vec points to the output vector we are updating. 78 vec []_GOTYPE 79 // nulls points to the output null vector that we are updating. 80 nulls *coldata.Nulls 81 // foundNonNullForCurrentGroup tracks if we have seen any non-null values 82 // for the group that is currently being aggregated. 83 foundNonNullForCurrentGroup bool 84 } 85 } 86 87 var _ aggregateFunc = &sum_TYPEAgg{} 88 89 const sizeOfSum_TYPEAgg = int64(unsafe.Sizeof(sum_TYPEAgg{})) 90 91 func (a *sum_TYPEAgg) Init(groups []bool, v coldata.Vec) { 92 a.groups = groups 93 a.scratch.vec = v.TemplateType() 94 a.scratch.nulls = v.Nulls() 95 a.Reset() 96 } 97 98 func (a *sum_TYPEAgg) Reset() { 99 a.scratch.curIdx = -1 100 a.scratch.foundNonNullForCurrentGroup = false 101 a.scratch.nulls.UnsetNulls() 102 } 103 104 func (a *sum_TYPEAgg) CurrentOutputIndex() int { 105 return a.scratch.curIdx 106 } 107 108 func (a *sum_TYPEAgg) SetOutputIndex(idx int) { 109 if a.scratch.curIdx != -1 { 110 a.scratch.curIdx = idx 111 a.scratch.nulls.UnsetNullsAfter(idx + 1) 112 } 113 } 114 115 func (a *sum_TYPEAgg) Compute(b coldata.Batch, inputIdxs []uint32) { 116 inputLen := b.Length() 117 vec, sel := b.ColVec(int(inputIdxs[0])), b.Selection() 118 col, nulls := vec.TemplateType(), vec.Nulls() 119 if nulls.MaybeHasNulls() { 120 if sel != nil { 121 sel = sel[:inputLen] 122 for _, i := range sel { 123 _ACCUMULATE_SUM(a, nulls, i, true) 124 } 125 } else { 126 col = col[:inputLen] 127 for i := range col { 128 _ACCUMULATE_SUM(a, nulls, i, true) 129 } 130 } 131 } else { 132 if sel != nil { 133 sel = sel[:inputLen] 134 for _, i := range sel { 135 _ACCUMULATE_SUM(a, nulls, i, false) 136 } 137 } else { 138 col = col[:inputLen] 139 for i := range col { 140 _ACCUMULATE_SUM(a, nulls, i, false) 141 } 142 } 143 } 144 } 145 146 func (a *sum_TYPEAgg) Flush() { 147 // The aggregation is finished. Flush the last value. If we haven't found 148 // any non-nulls for this group so far, the output for this group should be 149 // null. 150 if !a.scratch.foundNonNullForCurrentGroup { 151 a.scratch.nulls.SetNull(a.scratch.curIdx) 152 } else { 153 a.scratch.vec[a.scratch.curIdx] = a.scratch.curAgg 154 } 155 a.scratch.curIdx++ 156 } 157 158 func (a *sum_TYPEAgg) HandleEmptyInputScalar() { 159 a.scratch.nulls.SetNull(0) 160 } 161 162 type sum_TYPEAggAlloc struct { 163 allocator *colmem.Allocator 164 allocSize int64 165 aggFuncs []sum_TYPEAgg 166 } 167 168 var _ aggregateFuncAlloc = &sum_TYPEAggAlloc{} 169 170 func (a *sum_TYPEAggAlloc) newAggFunc() aggregateFunc { 171 if len(a.aggFuncs) == 0 { 172 a.allocator.AdjustMemoryUsage(sizeOfSum_TYPEAgg * a.allocSize) 173 a.aggFuncs = make([]sum_TYPEAgg, a.allocSize) 174 } 175 f := &a.aggFuncs[0] 176 a.aggFuncs = a.aggFuncs[1:] 177 return f 178 } 179 180 // {{end}} 181 // {{end}} 182 183 // {{/* 184 // _ACCUMULATE_SUM adds the value of the ith row to the output for the current 185 // group. If this is the first row of a new group, and no non-nulls have been 186 // found for the current group, then the output for the current group is set to 187 // null. 188 func _ACCUMULATE_SUM(a *sum_TYPEAgg, nulls *coldata.Nulls, i int, _HAS_NULLS bool) { // */}} 189 190 // {{define "accumulateSum"}} 191 if a.groups[i] { 192 // If we encounter a new group, and we haven't found any non-nulls for the 193 // current group, the output for this group should be null. If 194 // a.scratch.curIdx is negative, it means that this is the first group. 195 if a.scratch.curIdx >= 0 { 196 if !a.scratch.foundNonNullForCurrentGroup { 197 a.scratch.nulls.SetNull(a.scratch.curIdx) 198 } else { 199 a.scratch.vec[a.scratch.curIdx] = a.scratch.curAgg 200 } 201 } 202 a.scratch.curIdx++ 203 // {{with .Global}} 204 a.scratch.curAgg = zero_TYPEValue 205 // {{end}} 206 207 // {{/* 208 // We only need to reset this flag if there are nulls. If there are no 209 // nulls, this will be updated unconditionally below. 210 // */}} 211 // {{if .HasNulls}} 212 a.scratch.foundNonNullForCurrentGroup = false 213 // {{end}} 214 } 215 var isNull bool 216 // {{if .HasNulls}} 217 isNull = nulls.NullAt(i) 218 // {{else}} 219 isNull = false 220 // {{end}} 221 if !isNull { 222 _ASSIGN_ADD(a.scratch.curAgg, a.scratch.curAgg, col[i], _, _, col) 223 a.scratch.foundNonNullForCurrentGroup = true 224 } 225 // {{end}} 226 227 // {{/* 228 } // */}}