github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/interlock/aggfuncs/builder.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 "fmt" 18 "strconv" 19 20 "github.com/whtcorpsinc/BerolinaSQL/ast" 21 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 22 "github.com/whtcorpsinc/milevadb/memex" 23 "github.com/whtcorpsinc/milevadb/memex/aggregation" 24 "github.com/whtcorpsinc/milevadb/stochastikctx" 25 "github.com/whtcorpsinc/milevadb/stochastikctx/variable" 26 "github.com/whtcorpsinc/milevadb/types" 27 "github.com/whtcorpsinc/milevadb/soliton/chunk" 28 ) 29 30 // Build is used to build a specific AggFunc implementation according to the 31 // input aggFuncDesc. 32 func Build(ctx stochastikctx.Context, aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 33 switch aggFuncDesc.Name { 34 case ast.AggFuncCount: 35 return buildCount(aggFuncDesc, ordinal) 36 case ast.AggFuncSum: 37 return buildSum(ctx, aggFuncDesc, ordinal) 38 case ast.AggFuncAvg: 39 return buildAvg(ctx, aggFuncDesc, ordinal) 40 case ast.AggFuncFirstEvent: 41 return buildFirstEvent(aggFuncDesc, ordinal) 42 case ast.AggFuncMax: 43 return buildMaxMin(aggFuncDesc, ordinal, true) 44 case ast.AggFuncMin: 45 return buildMaxMin(aggFuncDesc, ordinal, false) 46 case ast.AggFuncGroupConcat: 47 return buildGroupConcat(ctx, aggFuncDesc, ordinal) 48 case ast.AggFuncBitOr: 49 return buildBitOr(aggFuncDesc, ordinal) 50 case ast.AggFuncBitXor: 51 return buildBitXor(aggFuncDesc, ordinal) 52 case ast.AggFuncBitAnd: 53 return buildBitAnd(aggFuncDesc, ordinal) 54 case ast.AggFuncVarPop: 55 return buildVarPop(aggFuncDesc, ordinal) 56 case ast.AggFuncJsonObjectAgg: 57 return buildJSONObjectAgg(aggFuncDesc, ordinal) 58 case ast.AggFuncApproxCountDistinct: 59 return buildApproxCountDistinct(aggFuncDesc, ordinal) 60 case ast.AggFuncStddevPop: 61 return buildStdDevPop(aggFuncDesc, ordinal) 62 case ast.AggFuncVarSamp: 63 return buildVarSamp(aggFuncDesc, ordinal) 64 case ast.AggFuncStddevSamp: 65 return buildStddevSamp(aggFuncDesc, ordinal) 66 } 67 return nil 68 } 69 70 // BuildWindowFunctions builds specific window function according to function description and order by defCausumns. 71 func BuildWindowFunctions(ctx stochastikctx.Context, windowFuncDesc *aggregation.AggFuncDesc, ordinal int, orderByDefCauss []*memex.DeferredCauset) AggFunc { 72 switch windowFuncDesc.Name { 73 case ast.WindowFuncRank: 74 return buildRank(ordinal, orderByDefCauss, false) 75 case ast.WindowFuncDenseRank: 76 return buildRank(ordinal, orderByDefCauss, true) 77 case ast.WindowFuncEventNumber: 78 return buildEventNumber(windowFuncDesc, ordinal) 79 case ast.WindowFuncFirstValue: 80 return buildFirstValue(windowFuncDesc, ordinal) 81 case ast.WindowFuncLastValue: 82 return buildLastValue(windowFuncDesc, ordinal) 83 case ast.WindowFuncCumeDist: 84 return buildCumeDist(ordinal, orderByDefCauss) 85 case ast.WindowFuncNthValue: 86 return buildNthValue(windowFuncDesc, ordinal) 87 case ast.WindowFuncNtile: 88 return buildNtile(windowFuncDesc, ordinal) 89 case ast.WindowFuncPercentRank: 90 return buildPercenRank(ordinal, orderByDefCauss) 91 case ast.WindowFuncLead: 92 return buildLead(windowFuncDesc, ordinal) 93 case ast.WindowFuncLag: 94 return buildLag(windowFuncDesc, ordinal) 95 case ast.AggFuncMax: 96 // The max/min aggFunc using in the window function will using the sliding window algo. 97 return buildMaxMinInWindowFunction(windowFuncDesc, ordinal, true) 98 case ast.AggFuncMin: 99 return buildMaxMinInWindowFunction(windowFuncDesc, ordinal, false) 100 default: 101 return Build(ctx, windowFuncDesc, ordinal) 102 } 103 } 104 105 func buildApproxCountDistinct(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 106 base := baseApproxCountDistinct{baseAggFunc{ 107 args: aggFuncDesc.Args, 108 ordinal: ordinal, 109 }} 110 111 // In partition causet, union need to compute partial result into partial result. 112 // We can detect and handle this case by checking whether return type is string. 113 114 switch aggFuncDesc.RetTp.Tp { 115 case allegrosql.TypeLonglong: 116 switch aggFuncDesc.Mode { 117 case aggregation.CompleteMode: 118 return &approxCountDistinctOriginal{base} 119 case aggregation.Partial1Mode: 120 return &approxCountDistinctPartial1{approxCountDistinctOriginal{base}} 121 case aggregation.Partial2Mode: 122 return &approxCountDistinctPartial2{approxCountDistinctPartial1{approxCountDistinctOriginal{base}}} 123 case aggregation.FinalMode: 124 return &approxCountDistinctFinal{approxCountDistinctPartial2{approxCountDistinctPartial1{approxCountDistinctOriginal{base}}}} 125 } 126 case allegrosql.TypeString: 127 switch aggFuncDesc.Mode { 128 case aggregation.CompleteMode, aggregation.Partial1Mode: 129 return &approxCountDistinctPartial1{approxCountDistinctOriginal{base}} 130 case aggregation.Partial2Mode, aggregation.FinalMode: 131 return &approxCountDistinctPartial2{approxCountDistinctPartial1{approxCountDistinctOriginal{base}}} 132 } 133 } 134 135 return nil 136 } 137 138 // buildCount builds the AggFunc implementation for function "COUNT". 139 func buildCount(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 140 // If mode is DedupMode, we return nil for not implemented. 141 if aggFuncDesc.Mode == aggregation.DedupMode { 142 return nil // not implemented yet. 143 } 144 145 base := baseAggFunc{ 146 args: aggFuncDesc.Args, 147 ordinal: ordinal, 148 } 149 150 // If HasDistinct and mode is CompleteMode or Partial1Mode, we should 151 // use countOriginalWithDistinct. 152 if aggFuncDesc.HasDistinct && 153 (aggFuncDesc.Mode == aggregation.CompleteMode || aggFuncDesc.Mode == aggregation.Partial1Mode) { 154 if len(base.args) == 1 { 155 // optimize with single defCausumn 156 // TODO: because Time and JSON does not have `hashcode()` or similar method 157 // so they're in exception for now. 158 // TODO: add hashCode method for all evaluate types (Decimal, Time, Duration, JSON). 159 // https://github.com/whtcorpsinc/milevadb/issues/15857 160 switch aggFuncDesc.Args[0].GetType().EvalType() { 161 case types.ETInt: 162 return &countOriginalWithDistinct4Int{baseCount{base}} 163 case types.ETReal: 164 return &countOriginalWithDistinct4Real{baseCount{base}} 165 case types.ETDecimal: 166 return &countOriginalWithDistinct4Decimal{baseCount{base}} 167 case types.ETDuration: 168 return &countOriginalWithDistinct4Duration{baseCount{base}} 169 case types.ETString: 170 return &countOriginalWithDistinct4String{baseCount{base}} 171 } 172 } 173 return &countOriginalWithDistinct{baseCount{base}} 174 } 175 176 switch aggFuncDesc.Mode { 177 case aggregation.CompleteMode, aggregation.Partial1Mode: 178 switch aggFuncDesc.Args[0].GetType().EvalType() { 179 case types.ETInt: 180 return &countOriginal4Int{baseCount{base}} 181 case types.ETReal: 182 return &countOriginal4Real{baseCount{base}} 183 case types.ETDecimal: 184 return &countOriginal4Decimal{baseCount{base}} 185 case types.ETTimestamp, types.ETDatetime: 186 return &countOriginal4Time{baseCount{base}} 187 case types.ETDuration: 188 return &countOriginal4Duration{baseCount{base}} 189 case types.ETJson: 190 return &countOriginal4JSON{baseCount{base}} 191 case types.ETString: 192 return &countOriginal4String{baseCount{base}} 193 } 194 case aggregation.Partial2Mode, aggregation.FinalMode: 195 return &countPartial{baseCount{base}} 196 } 197 198 return nil 199 } 200 201 // buildSum builds the AggFunc implementation for function "SUM". 202 func buildSum(ctx stochastikctx.Context, aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 203 base := baseSumAggFunc{ 204 baseAggFunc: baseAggFunc{ 205 args: aggFuncDesc.Args, 206 ordinal: ordinal, 207 }, 208 } 209 switch aggFuncDesc.Mode { 210 case aggregation.DedupMode: 211 return nil 212 default: 213 switch aggFuncDesc.RetTp.EvalType() { 214 case types.ETDecimal: 215 if aggFuncDesc.HasDistinct { 216 return &sum4DistinctDecimal{base} 217 } 218 return &sum4Decimal{base} 219 default: 220 if aggFuncDesc.HasDistinct { 221 return &sum4DistinctFloat64{base} 222 } 223 if ctx.GetStochastikVars().WindowingUseHighPrecision { 224 return &sum4Float64HighPrecision{baseSum4Float64{base}} 225 } 226 return &sum4Float64{baseSum4Float64{base}} 227 } 228 } 229 } 230 231 // buildAvg builds the AggFunc implementation for function "AVG". 232 func buildAvg(ctx stochastikctx.Context, aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 233 base := baseAggFunc{ 234 args: aggFuncDesc.Args, 235 ordinal: ordinal, 236 } 237 switch aggFuncDesc.Mode { 238 // Build avg functions which consume the original data and remove the 239 // duplicated input of the same group. 240 case aggregation.DedupMode: 241 return nil // not implemented yet. 242 243 // Build avg functions which consume the original data and uFIDelate their 244 // partial results. 245 case aggregation.CompleteMode, aggregation.Partial1Mode: 246 switch aggFuncDesc.RetTp.EvalType() { 247 case types.ETDecimal: 248 if aggFuncDesc.HasDistinct { 249 return &avgOriginal4DistinctDecimal{base} 250 } 251 return &avgOriginal4Decimal{baseAvgDecimal{base}} 252 default: 253 if aggFuncDesc.HasDistinct { 254 return &avgOriginal4DistinctFloat64{base} 255 } 256 if ctx.GetStochastikVars().WindowingUseHighPrecision { 257 return &avgOriginal4Float64HighPrecision{baseAvgFloat64{base}} 258 } 259 return &avgOriginal4Float64{avgOriginal4Float64HighPrecision{baseAvgFloat64{base}}} 260 } 261 262 // Build avg functions which consume the partial result of other avg 263 // functions and uFIDelate their partial results. 264 case aggregation.Partial2Mode, aggregation.FinalMode: 265 switch aggFuncDesc.RetTp.Tp { 266 case allegrosql.TypeNewDecimal: 267 return &avgPartial4Decimal{baseAvgDecimal{base}} 268 case allegrosql.TypeDouble: 269 return &avgPartial4Float64{baseAvgFloat64{base}} 270 } 271 } 272 return nil 273 } 274 275 // buildFirstEvent builds the AggFunc implementation for function "FIRST_ROW". 276 func buildFirstEvent(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 277 base := baseAggFunc{ 278 args: aggFuncDesc.Args, 279 ordinal: ordinal, 280 } 281 282 evalType, fieldType := aggFuncDesc.RetTp.EvalType(), aggFuncDesc.RetTp 283 if fieldType.Tp == allegrosql.TypeBit { 284 evalType = types.ETString 285 } 286 switch aggFuncDesc.Mode { 287 case aggregation.DedupMode: 288 default: 289 switch fieldType.Tp { 290 case allegrosql.TypeEnum: 291 return &firstEvent4Enum{base} 292 case allegrosql.TypeSet: 293 return &firstEvent4Set{base} 294 } 295 296 switch evalType { 297 case types.ETInt: 298 return &firstEvent4Int{base} 299 case types.ETReal: 300 switch fieldType.Tp { 301 case allegrosql.TypeFloat: 302 return &firstEvent4Float32{base} 303 case allegrosql.TypeDouble: 304 return &firstEvent4Float64{base} 305 } 306 case types.ETDecimal: 307 return &firstEvent4Decimal{base} 308 case types.ETDatetime, types.ETTimestamp: 309 return &firstEvent4Time{base} 310 case types.ETDuration: 311 return &firstEvent4Duration{base} 312 case types.ETString: 313 return &firstEvent4String{base} 314 case types.ETJson: 315 return &firstEvent4JSON{base} 316 } 317 } 318 return nil 319 } 320 321 // buildMaxMin builds the AggFunc implementation for function "MAX" and "MIN". 322 func buildMaxMin(aggFuncDesc *aggregation.AggFuncDesc, ordinal int, isMax bool) AggFunc { 323 base := baseMaxMinAggFunc{ 324 baseAggFunc: baseAggFunc{ 325 args: aggFuncDesc.Args, 326 ordinal: ordinal, 327 }, 328 isMax: isMax, 329 } 330 331 evalType, fieldType := aggFuncDesc.RetTp.EvalType(), aggFuncDesc.RetTp 332 if fieldType.Tp == allegrosql.TypeBit { 333 evalType = types.ETString 334 } 335 switch aggFuncDesc.Mode { 336 case aggregation.DedupMode: 337 default: 338 switch fieldType.Tp { 339 case allegrosql.TypeEnum: 340 return &maxMin4Enum{base} 341 case allegrosql.TypeSet: 342 return &maxMin4Set{base} 343 } 344 345 switch evalType { 346 case types.ETInt: 347 if allegrosql.HasUnsignedFlag(fieldType.Flag) { 348 return &maxMin4Uint{base} 349 } 350 return &maxMin4Int{base} 351 case types.ETReal: 352 switch fieldType.Tp { 353 case allegrosql.TypeFloat: 354 return &maxMin4Float32{base} 355 case allegrosql.TypeDouble: 356 return &maxMin4Float64{base} 357 } 358 case types.ETDecimal: 359 return &maxMin4Decimal{base} 360 case types.ETString: 361 return &maxMin4String{baseMaxMinAggFunc: base, retTp: aggFuncDesc.RetTp} 362 case types.ETDatetime, types.ETTimestamp: 363 return &maxMin4Time{base} 364 case types.ETDuration: 365 return &maxMin4Duration{base} 366 case types.ETJson: 367 return &maxMin4JSON{base} 368 } 369 } 370 return nil 371 } 372 373 // buildMaxMin builds the AggFunc implementation for function "MAX" and "MIN" using by window function. 374 func buildMaxMinInWindowFunction(aggFuncDesc *aggregation.AggFuncDesc, ordinal int, isMax bool) AggFunc { 375 base := buildMaxMin(aggFuncDesc, ordinal, isMax) 376 // build max/min aggFunc for window function using sliding window 377 switch baseAggFunc := base.(type) { 378 case *maxMin4Int: 379 return &maxMin4IntSliding{*baseAggFunc} 380 case *maxMin4Uint: 381 return &maxMin4UintSliding{*baseAggFunc} 382 case *maxMin4Float32: 383 return &maxMin4Float32Sliding{*baseAggFunc} 384 case *maxMin4Float64: 385 return &maxMin4Float64Sliding{*baseAggFunc} 386 case *maxMin4Decimal: 387 return &maxMin4DecimalSliding{*baseAggFunc} 388 case *maxMin4String: 389 return &maxMin4StringSliding{*baseAggFunc} 390 case *maxMin4Time: 391 return &maxMin4TimeSliding{*baseAggFunc} 392 case *maxMin4Duration: 393 return &maxMin4DurationSliding{*baseAggFunc} 394 } 395 return base 396 } 397 398 // buildGroupConcat builds the AggFunc implementation for function "GROUP_CONCAT". 399 func buildGroupConcat(ctx stochastikctx.Context, aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 400 switch aggFuncDesc.Mode { 401 case aggregation.DedupMode: 402 return nil 403 default: 404 // The last arg is promised to be a not-null string constant, so the error can be ignored. 405 c, _ := aggFuncDesc.Args[len(aggFuncDesc.Args)-1].(*memex.Constant) 406 sep, _, err := c.EvalString(nil, chunk.Event{}) 407 // This err should never happen. 408 if err != nil { 409 panic(fmt.Sprintf("Error happened when buildGroupConcat: %s", err.Error())) 410 } 411 var s string 412 s, err = variable.GetStochastikSystemVar(ctx.GetStochastikVars(), variable.GroupConcatMaxLen) 413 if err != nil { 414 panic(fmt.Sprintf("Error happened when buildGroupConcat: no system variable named '%s'", variable.GroupConcatMaxLen)) 415 } 416 maxLen, err := strconv.ParseUint(s, 10, 64) 417 // Should never happen 418 if err != nil { 419 panic(fmt.Sprintf("Error happened when buildGroupConcat: %s", err.Error())) 420 } 421 var truncated int32 422 base := baseGroupConcat4String{ 423 baseAggFunc: baseAggFunc{ 424 args: aggFuncDesc.Args[:len(aggFuncDesc.Args)-1], 425 ordinal: ordinal, 426 }, 427 byItems: aggFuncDesc.OrderByItems, 428 sep: sep, 429 maxLen: maxLen, 430 truncated: &truncated, 431 } 432 if aggFuncDesc.HasDistinct { 433 if len(aggFuncDesc.OrderByItems) > 0 { 434 return &groupConcatDistinctOrder{base} 435 } 436 return &groupConcatDistinct{base} 437 } 438 if len(aggFuncDesc.OrderByItems) > 0 { 439 return &groupConcatOrder{base} 440 } 441 return &groupConcat{base} 442 } 443 } 444 445 // buildBitOr builds the AggFunc implementation for function "BIT_OR". 446 func buildBitOr(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 447 base := baseAggFunc{ 448 args: aggFuncDesc.Args, 449 ordinal: ordinal, 450 } 451 return &bitOrUint64{baseBitAggFunc{base}} 452 } 453 454 // buildBitXor builds the AggFunc implementation for function "BIT_XOR". 455 func buildBitXor(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 456 base := baseAggFunc{ 457 args: aggFuncDesc.Args, 458 ordinal: ordinal, 459 } 460 return &bitXorUint64{baseBitAggFunc{base}} 461 } 462 463 // buildBitAnd builds the AggFunc implementation for function "BIT_AND". 464 func buildBitAnd(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 465 base := baseAggFunc{ 466 args: aggFuncDesc.Args, 467 ordinal: ordinal, 468 } 469 return &bitAndUint64{baseBitAggFunc{base}} 470 } 471 472 // buildVarPop builds the AggFunc implementation for function "VAR_POP". 473 func buildVarPop(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 474 base := baseVarPopAggFunc{ 475 baseAggFunc{ 476 args: aggFuncDesc.Args, 477 ordinal: ordinal, 478 }, 479 } 480 switch aggFuncDesc.Mode { 481 case aggregation.DedupMode: 482 return nil 483 default: 484 if aggFuncDesc.HasDistinct { 485 return &varPop4DistinctFloat64{base} 486 } 487 return &varPop4Float64{base} 488 } 489 } 490 491 // buildStdDevPop builds the AggFunc implementation for function "STD()/STDDEV()/STDDEV_POP()" 492 func buildStdDevPop(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 493 base := baseVarPopAggFunc{ 494 baseAggFunc{ 495 args: aggFuncDesc.Args, 496 ordinal: ordinal, 497 }, 498 } 499 switch aggFuncDesc.Mode { 500 case aggregation.DedupMode: 501 return nil 502 default: 503 if aggFuncDesc.HasDistinct { 504 return &stdDevPop4DistinctFloat64{varPop4DistinctFloat64{base}} 505 } 506 return &stdDevPop4Float64{varPop4Float64{base}} 507 } 508 } 509 510 // buildVarSamp builds the AggFunc implementation for function "VAR_SAMP()" 511 func buildVarSamp(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 512 base := baseVarPopAggFunc{ 513 baseAggFunc{ 514 args: aggFuncDesc.Args, 515 ordinal: ordinal, 516 }, 517 } 518 switch aggFuncDesc.Mode { 519 case aggregation.DedupMode: 520 return nil 521 default: 522 if aggFuncDesc.HasDistinct { 523 return &varSamp4DistinctFloat64{varPop4DistinctFloat64{base}} 524 } 525 return &varSamp4Float64{varPop4Float64{base}} 526 } 527 } 528 529 // buildStddevSamp builds the AggFunc implementation for function "STDDEV_SAMP()" 530 func buildStddevSamp(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 531 base := baseVarPopAggFunc{ 532 baseAggFunc{ 533 args: aggFuncDesc.Args, 534 ordinal: ordinal, 535 }, 536 } 537 switch aggFuncDesc.Mode { 538 case aggregation.DedupMode: 539 return nil 540 default: 541 if aggFuncDesc.HasDistinct { 542 return &stddevSamp4DistinctFloat64{varPop4DistinctFloat64{base}} 543 } 544 return &stddevSamp4Float64{varPop4Float64{base}} 545 } 546 } 547 548 // buildJSONObjectAgg builds the AggFunc implementation for function "json_objectagg". 549 func buildJSONObjectAgg(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 550 base := baseAggFunc{ 551 args: aggFuncDesc.Args, 552 ordinal: ordinal, 553 } 554 switch aggFuncDesc.Mode { 555 case aggregation.DedupMode: 556 return nil 557 default: 558 return &jsonObjectAgg{base} 559 } 560 } 561 562 // buildEventNumber builds the AggFunc implementation for function "ROW_NUMBER". 563 func buildEventNumber(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 564 base := baseAggFunc{ 565 args: aggFuncDesc.Args, 566 ordinal: ordinal, 567 } 568 return &rowNumber{base} 569 } 570 571 func buildRank(ordinal int, orderByDefCauss []*memex.DeferredCauset, isDense bool) AggFunc { 572 base := baseAggFunc{ 573 ordinal: ordinal, 574 } 575 r := &rank{baseAggFunc: base, isDense: isDense, rowComparer: buildEventComparer(orderByDefCauss)} 576 return r 577 } 578 579 func buildFirstValue(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 580 base := baseAggFunc{ 581 args: aggFuncDesc.Args, 582 ordinal: ordinal, 583 } 584 return &firstValue{baseAggFunc: base, tp: aggFuncDesc.RetTp} 585 } 586 587 func buildLastValue(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 588 base := baseAggFunc{ 589 args: aggFuncDesc.Args, 590 ordinal: ordinal, 591 } 592 return &lastValue{baseAggFunc: base, tp: aggFuncDesc.RetTp} 593 } 594 595 func buildCumeDist(ordinal int, orderByDefCauss []*memex.DeferredCauset) AggFunc { 596 base := baseAggFunc{ 597 ordinal: ordinal, 598 } 599 r := &cumeDist{baseAggFunc: base, rowComparer: buildEventComparer(orderByDefCauss)} 600 return r 601 } 602 603 func buildNthValue(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 604 base := baseAggFunc{ 605 args: aggFuncDesc.Args, 606 ordinal: ordinal, 607 } 608 // Already checked when building the function description. 609 nth, _, _ := memex.GetUint64FromConstant(aggFuncDesc.Args[1]) 610 return &nthValue{baseAggFunc: base, tp: aggFuncDesc.RetTp, nth: nth} 611 } 612 613 func buildNtile(aggFuncDes *aggregation.AggFuncDesc, ordinal int) AggFunc { 614 base := baseAggFunc{ 615 args: aggFuncDes.Args, 616 ordinal: ordinal, 617 } 618 n, _, _ := memex.GetUint64FromConstant(aggFuncDes.Args[0]) 619 return &ntile{baseAggFunc: base, n: n} 620 } 621 622 func buildPercenRank(ordinal int, orderByDefCauss []*memex.DeferredCauset) AggFunc { 623 base := baseAggFunc{ 624 ordinal: ordinal, 625 } 626 return &percentRank{baseAggFunc: base, rowComparer: buildEventComparer(orderByDefCauss)} 627 } 628 629 func buildLeadLag(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) baseLeadLag { 630 offset := uint64(1) 631 if len(aggFuncDesc.Args) >= 2 { 632 offset, _, _ = memex.GetUint64FromConstant(aggFuncDesc.Args[1]) 633 } 634 var defaultExpr memex.Expression 635 defaultExpr = memex.NewNull() 636 if len(aggFuncDesc.Args) == 3 { 637 defaultExpr = aggFuncDesc.Args[2] 638 } 639 base := baseAggFunc{ 640 args: aggFuncDesc.Args, 641 ordinal: ordinal, 642 } 643 ve, _ := buildValueEvaluator(aggFuncDesc.RetTp) 644 return baseLeadLag{baseAggFunc: base, offset: offset, defaultExpr: defaultExpr, valueEvaluator: ve} 645 } 646 647 func buildLead(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 648 return &lead{buildLeadLag(aggFuncDesc, ordinal)} 649 } 650 651 func buildLag(aggFuncDesc *aggregation.AggFuncDesc, ordinal int) AggFunc { 652 return &lag{buildLeadLag(aggFuncDesc, ordinal)} 653 }