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  }