github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/interlock/aggfuncs/func_avg.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package aggfuncs 15 16 import ( 17 "unsafe" 18 19 "github.com/cznic/mathutil" 20 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 21 "github.com/whtcorpsinc/milevadb/stochastikctx" 22 "github.com/whtcorpsinc/milevadb/types" 23 "github.com/whtcorpsinc/milevadb/soliton/chunk" 24 "github.com/whtcorpsinc/milevadb/soliton/replog" 25 "github.com/whtcorpsinc/milevadb/soliton/set" 26 ) 27 28 const ( 29 // DefPartialResult4AvgDecimalSize is the size of partialResult4AvgDecimal 30 DefPartialResult4AvgDecimalSize = int64(unsafe.Sizeof(partialResult4AvgDecimal{})) 31 // DefPartialResult4AvgDistinctDecimalSize is the size of partialResult4AvgDistinctDecimal 32 DefPartialResult4AvgDistinctDecimalSize = int64(unsafe.Sizeof(partialResult4AvgDistinctDecimal{})) 33 // DefPartialResult4AvgFloat64Size is the size of partialResult4AvgFloat64 34 DefPartialResult4AvgFloat64Size = int64(unsafe.Sizeof(partialResult4AvgFloat64{})) 35 // DefPartialResult4AvgDistinctFloat64Size is the size of partialResult4AvgDistinctFloat64 36 DefPartialResult4AvgDistinctFloat64Size = int64(unsafe.Sizeof(partialResult4AvgDistinctFloat64{})) 37 ) 38 39 // All the following avg function implementations return the decimal result, 40 // which causetstore the partial results in "partialResult4AvgDecimal". 41 // 42 // "baseAvgDecimal" is wrapped by: 43 // - "avgOriginal4Decimal" 44 // - "avgPartial4Decimal" 45 type baseAvgDecimal struct { 46 baseAggFunc 47 } 48 49 type partialResult4AvgDecimal struct { 50 sum types.MyDecimal 51 count int64 52 } 53 54 func (e *baseAvgDecimal) AllocPartialResult() (pr PartialResult, memDelta int64) { 55 return PartialResult(&partialResult4AvgDecimal{}), DefPartialResult4AvgDecimalSize 56 } 57 58 func (e *baseAvgDecimal) ResetPartialResult(pr PartialResult) { 59 p := (*partialResult4AvgDecimal)(pr) 60 p.sum = *types.NewDecFromInt(0) 61 p.count = int64(0) 62 } 63 64 func (e *baseAvgDecimal) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 65 p := (*partialResult4AvgDecimal)(pr) 66 if p.count == 0 { 67 chk.AppendNull(e.ordinal) 68 return nil 69 } 70 decimalCount := types.NewDecFromInt(p.count) 71 finalResult := new(types.MyDecimal) 72 err := types.DecimalDiv(&p.sum, decimalCount, finalResult, types.DivFracIncr) 73 if err != nil { 74 return err 75 } 76 // Make the decimal be the result of type inferring. 77 frac := e.args[0].GetType().Decimal 78 if len(e.args) == 2 { 79 frac = e.args[1].GetType().Decimal 80 } 81 if frac == -1 { 82 frac = allegrosql.MaxDecimalScale 83 } 84 err = finalResult.Round(finalResult, mathutil.Min(frac, allegrosql.MaxDecimalScale), types.ModeHalfEven) 85 if err != nil { 86 return err 87 } 88 chk.AppendMyDecimal(e.ordinal, finalResult) 89 return nil 90 } 91 92 type avgOriginal4Decimal struct { 93 baseAvgDecimal 94 } 95 96 func (e *avgOriginal4Decimal) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 97 p := (*partialResult4AvgDecimal)(pr) 98 for _, event := range rowsInGroup { 99 input, isNull, err := e.args[0].EvalDecimal(sctx, event) 100 if err != nil { 101 return 0, err 102 } 103 if isNull { 104 continue 105 } 106 107 newSum := new(types.MyDecimal) 108 err = types.DecimalAdd(&p.sum, input, newSum) 109 if err != nil { 110 return 0, err 111 } 112 p.sum = *newSum 113 p.count++ 114 } 115 return 0, nil 116 } 117 118 func (e *avgOriginal4Decimal) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 119 p := (*partialResult4AvgDecimal)(pr) 120 for i := uint64(0); i < shiftEnd; i++ { 121 input, isNull, err := e.args[0].EvalDecimal(sctx, rows[lastEnd+i]) 122 if err != nil { 123 return err 124 } 125 if isNull { 126 continue 127 } 128 newSum := new(types.MyDecimal) 129 err = types.DecimalAdd(&p.sum, input, newSum) 130 if err != nil { 131 return err 132 } 133 p.sum = *newSum 134 p.count++ 135 } 136 for i := uint64(0); i < shiftStart; i++ { 137 input, isNull, err := e.args[0].EvalDecimal(sctx, rows[lastStart+i]) 138 if err != nil { 139 return err 140 } 141 if isNull { 142 continue 143 } 144 newSum := new(types.MyDecimal) 145 err = types.DecimalSub(&p.sum, input, newSum) 146 if err != nil { 147 return err 148 } 149 p.sum = *newSum 150 p.count-- 151 } 152 return nil 153 } 154 155 type avgPartial4Decimal struct { 156 baseAvgDecimal 157 } 158 159 func (e *avgPartial4Decimal) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 160 p := (*partialResult4AvgDecimal)(pr) 161 for _, event := range rowsInGroup { 162 inputSum, isNull, err := e.args[1].EvalDecimal(sctx, event) 163 if err != nil { 164 return 0, err 165 } 166 if isNull { 167 continue 168 } 169 170 inputCount, isNull, err := e.args[0].EvalInt(sctx, event) 171 if err != nil { 172 return 0, err 173 } 174 if isNull { 175 continue 176 } 177 178 newSum := new(types.MyDecimal) 179 err = types.DecimalAdd(&p.sum, inputSum, newSum) 180 if err != nil { 181 return 0, err 182 } 183 p.sum = *newSum 184 p.count += inputCount 185 } 186 return 0, nil 187 } 188 189 func (e *avgPartial4Decimal) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 190 p1, p2 := (*partialResult4AvgDecimal)(src), (*partialResult4AvgDecimal)(dst) 191 if p1.count == 0 { 192 return 0, nil 193 } 194 newSum := new(types.MyDecimal) 195 err = types.DecimalAdd(&p1.sum, &p2.sum, newSum) 196 if err != nil { 197 return 0, err 198 } 199 p2.sum = *newSum 200 p2.count += p1.count 201 return 0, nil 202 } 203 204 type partialResult4AvgDistinctDecimal struct { 205 partialResult4AvgDecimal 206 valSet set.StringSet 207 } 208 209 type avgOriginal4DistinctDecimal struct { 210 baseAggFunc 211 } 212 213 func (e *avgOriginal4DistinctDecimal) AllocPartialResult() (pr PartialResult, memDelta int64) { 214 p := &partialResult4AvgDistinctDecimal{ 215 valSet: set.NewStringSet(), 216 } 217 return PartialResult(p), DefPartialResult4AvgDistinctDecimalSize 218 } 219 220 func (e *avgOriginal4DistinctDecimal) ResetPartialResult(pr PartialResult) { 221 p := (*partialResult4AvgDistinctDecimal)(pr) 222 p.sum = *types.NewDecFromInt(0) 223 p.count = int64(0) 224 p.valSet = set.NewStringSet() 225 } 226 227 func (e *avgOriginal4DistinctDecimal) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 228 p := (*partialResult4AvgDistinctDecimal)(pr) 229 for _, event := range rowsInGroup { 230 input, isNull, err := e.args[0].EvalDecimal(sctx, event) 231 if err != nil { 232 return memDelta, err 233 } 234 if isNull { 235 continue 236 } 237 hash, err := input.ToHashKey() 238 if err != nil { 239 return memDelta, err 240 } 241 decStr := string(replog.String(hash)) 242 if p.valSet.Exist(decStr) { 243 continue 244 } 245 p.valSet.Insert(decStr) 246 memDelta += int64(len(decStr)) 247 newSum := new(types.MyDecimal) 248 err = types.DecimalAdd(&p.sum, input, newSum) 249 if err != nil { 250 return memDelta, err 251 } 252 p.sum = *newSum 253 p.count++ 254 } 255 return memDelta, nil 256 } 257 258 func (e *avgOriginal4DistinctDecimal) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 259 p := (*partialResult4AvgDistinctDecimal)(pr) 260 if p.count == 0 { 261 chk.AppendNull(e.ordinal) 262 return nil 263 } 264 decimalCount := types.NewDecFromInt(p.count) 265 finalResult := new(types.MyDecimal) 266 err := types.DecimalDiv(&p.sum, decimalCount, finalResult, types.DivFracIncr) 267 if err != nil { 268 return err 269 } 270 // Make the decimal be the result of type inferring. 271 frac := e.args[0].GetType().Decimal 272 if frac == -1 { 273 frac = allegrosql.MaxDecimalScale 274 } 275 err = finalResult.Round(finalResult, mathutil.Min(frac, allegrosql.MaxDecimalScale), types.ModeHalfEven) 276 if err != nil { 277 return err 278 } 279 chk.AppendMyDecimal(e.ordinal, finalResult) 280 return nil 281 } 282 283 // All the following avg function implementations return the float64 result, 284 // which causetstore the partial results in "partialResult4AvgFloat64". 285 // 286 // "baseAvgFloat64" is wrapped by: 287 // - "avgOriginal4Float64" 288 // - "avgPartial4Float64" 289 type baseAvgFloat64 struct { 290 baseAggFunc 291 } 292 293 type partialResult4AvgFloat64 struct { 294 sum float64 295 count int64 296 } 297 298 func (e *baseAvgFloat64) AllocPartialResult() (pr PartialResult, memDelta int64) { 299 return (PartialResult)(&partialResult4AvgFloat64{}), DefPartialResult4AvgFloat64Size 300 } 301 302 func (e *baseAvgFloat64) ResetPartialResult(pr PartialResult) { 303 p := (*partialResult4AvgFloat64)(pr) 304 p.sum = 0 305 p.count = 0 306 } 307 308 func (e *baseAvgFloat64) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 309 p := (*partialResult4AvgFloat64)(pr) 310 if p.count == 0 { 311 chk.AppendNull(e.ordinal) 312 } else { 313 chk.AppendFloat64(e.ordinal, p.sum/float64(p.count)) 314 } 315 return nil 316 } 317 318 type avgOriginal4Float64HighPrecision struct { 319 baseAvgFloat64 320 } 321 322 func (e *avgOriginal4Float64HighPrecision) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 323 p := (*partialResult4AvgFloat64)(pr) 324 for _, event := range rowsInGroup { 325 input, isNull, err := e.args[0].EvalReal(sctx, event) 326 if err != nil { 327 return 0, err 328 } 329 if isNull { 330 continue 331 } 332 333 p.sum += input 334 p.count++ 335 } 336 return 0, nil 337 } 338 339 type avgOriginal4Float64 struct { 340 avgOriginal4Float64HighPrecision 341 } 342 343 func (e *avgOriginal4Float64) Slide(sctx stochastikctx.Context, rows []chunk.Event, lastStart, lastEnd uint64, shiftStart, shiftEnd uint64, pr PartialResult) error { 344 p := (*partialResult4AvgFloat64)(pr) 345 for i := uint64(0); i < shiftEnd; i++ { 346 input, isNull, err := e.args[0].EvalReal(sctx, rows[lastEnd+i]) 347 if err != nil { 348 return err 349 } 350 if isNull { 351 continue 352 } 353 p.sum += input 354 p.count++ 355 } 356 for i := uint64(0); i < shiftStart; i++ { 357 input, isNull, err := e.args[0].EvalReal(sctx, rows[lastStart+i]) 358 if err != nil { 359 return err 360 } 361 if isNull { 362 continue 363 } 364 p.sum -= input 365 p.count-- 366 } 367 return nil 368 } 369 370 type avgPartial4Float64 struct { 371 baseAvgFloat64 372 } 373 374 func (e *avgPartial4Float64) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 375 p := (*partialResult4AvgFloat64)(pr) 376 for _, event := range rowsInGroup { 377 inputSum, isNull, err := e.args[1].EvalReal(sctx, event) 378 if err != nil { 379 return 0, err 380 } 381 if isNull { 382 continue 383 } 384 385 inputCount, isNull, err := e.args[0].EvalInt(sctx, event) 386 if err != nil { 387 return 0, err 388 } 389 if isNull { 390 continue 391 } 392 p.sum += inputSum 393 p.count += inputCount 394 } 395 return 0, nil 396 } 397 398 func (e *avgPartial4Float64) MergePartialResult(sctx stochastikctx.Context, src, dst PartialResult) (memDelta int64, err error) { 399 p1, p2 := (*partialResult4AvgFloat64)(src), (*partialResult4AvgFloat64)(dst) 400 p2.sum += p1.sum 401 p2.count += p1.count 402 return 0, nil 403 } 404 405 type partialResult4AvgDistinctFloat64 struct { 406 partialResult4AvgFloat64 407 valSet set.Float64Set 408 } 409 410 type avgOriginal4DistinctFloat64 struct { 411 baseAggFunc 412 } 413 414 func (e *avgOriginal4DistinctFloat64) AllocPartialResult() (pr PartialResult, memDelta int64) { 415 p := &partialResult4AvgDistinctFloat64{ 416 valSet: set.NewFloat64Set(), 417 } 418 return PartialResult(p), DefPartialResult4AvgDistinctFloat64Size 419 } 420 421 func (e *avgOriginal4DistinctFloat64) ResetPartialResult(pr PartialResult) { 422 p := (*partialResult4AvgDistinctFloat64)(pr) 423 p.sum = float64(0) 424 p.count = int64(0) 425 p.valSet = set.NewFloat64Set() 426 } 427 428 func (e *avgOriginal4DistinctFloat64) UFIDelatePartialResult(sctx stochastikctx.Context, rowsInGroup []chunk.Event, pr PartialResult) (memDelta int64, err error) { 429 p := (*partialResult4AvgDistinctFloat64)(pr) 430 for _, event := range rowsInGroup { 431 input, isNull, err := e.args[0].EvalReal(sctx, event) 432 if err != nil { 433 return memDelta, err 434 } 435 if isNull || p.valSet.Exist(input) { 436 continue 437 } 438 439 p.sum += input 440 p.count++ 441 p.valSet.Insert(input) 442 memDelta += DefFloat64Size 443 } 444 return memDelta, nil 445 } 446 447 func (e *avgOriginal4DistinctFloat64) AppendFinalResult2Chunk(sctx stochastikctx.Context, pr PartialResult, chk *chunk.Chunk) error { 448 p := (*partialResult4AvgDistinctFloat64)(pr) 449 if p.count == 0 { 450 chk.AppendNull(e.ordinal) 451 return nil 452 } 453 chk.AppendFloat64(e.ordinal, p.sum/float64(p.count)) 454 return nil 455 }