github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/function/list_agg.go (about)

     1  // Copyright 2021 - 2022 Matrix Origin
     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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package function
    16  
    17  import (
    18  	"github.com/matrixorigin/matrixone/pkg/container/types"
    19  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    20  	"github.com/matrixorigin/matrixone/pkg/sql/colexec/aggexec"
    21  	"github.com/matrixorigin/matrixone/pkg/sql/plan/function/agg"
    22  )
    23  
    24  var supportedAggInNewFramework = []FuncNew{
    25  	{
    26  		functionId: COUNT,
    27  		class:      plan.Function_AGG | plan.Function_PRODUCE_NO_NULL,
    28  		layout:     STANDARD_FUNCTION,
    29  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
    30  			if len(inputs) == 1 {
    31  				if inputs[0].Oid == types.T_any {
    32  					return newCheckResultWithCast(0, []types.Type{types.T_int64.ToType()})
    33  				}
    34  				return newCheckResultWithSuccess(0)
    35  			}
    36  			return newCheckResultWithFailure(failedAggParametersWrong)
    37  		},
    38  
    39  		Overloads: []overload{
    40  			{
    41  				overloadId: 0,
    42  				isAgg:      true,
    43  				retType:    aggexec.CountReturnType,
    44  				aggFramework: aggregationLogicOfOverload{
    45  					str:         "count",
    46  					aggRegister: agg.RegisterCountColumn,
    47  				},
    48  			},
    49  		},
    50  	},
    51  
    52  	{
    53  		functionId: STARCOUNT,
    54  		class:      plan.Function_AGG | plan.Function_PRODUCE_NO_NULL,
    55  		layout:     STANDARD_FUNCTION,
    56  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
    57  			if len(inputs) == 1 {
    58  				if inputs[0].Oid == types.T_any {
    59  					return newCheckResultWithCast(0, []types.Type{types.T_int64.ToType()})
    60  				}
    61  				return newCheckResultWithSuccess(0)
    62  			}
    63  			return newCheckResultWithFailure(failedAggParametersWrong)
    64  		},
    65  
    66  		Overloads: []overload{
    67  			{
    68  				overloadId: 0,
    69  				isAgg:      true,
    70  				retType:    aggexec.CountReturnType,
    71  				aggFramework: aggregationLogicOfOverload{
    72  					str:         "count(*)",
    73  					aggRegister: agg.RegisterCountStar,
    74  				},
    75  			},
    76  		},
    77  	},
    78  
    79  	{
    80  		functionId: MIN,
    81  		class:      plan.Function_AGG,
    82  		layout:     STANDARD_FUNCTION,
    83  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
    84  			return fixedUnaryAggTypeCheck(inputs, agg.MinSupportedTypes)
    85  		},
    86  
    87  		Overloads: []overload{
    88  			{
    89  				overloadId: 0,
    90  				isAgg:      true,
    91  				retType:    agg.MinReturnType,
    92  				aggFramework: aggregationLogicOfOverload{
    93  					str:         "min",
    94  					aggRegister: agg.RegisterMin1,
    95  				},
    96  			},
    97  		},
    98  	},
    99  
   100  	{
   101  		functionId: MAX,
   102  		class:      plan.Function_AGG,
   103  		layout:     STANDARD_FUNCTION,
   104  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   105  			return fixedUnaryAggTypeCheck(inputs, agg.MaxSupportedTypes)
   106  		},
   107  
   108  		Overloads: []overload{
   109  			{
   110  				overloadId: 0,
   111  				isAgg:      true,
   112  				retType:    agg.MaxReturnType,
   113  				aggFramework: aggregationLogicOfOverload{
   114  					str:         "max",
   115  					aggRegister: agg.RegisterMax1,
   116  				},
   117  			},
   118  		},
   119  	},
   120  
   121  	{
   122  		functionId: SUM,
   123  		class:      plan.Function_AGG,
   124  		layout:     STANDARD_FUNCTION,
   125  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   126  			return fixedUnaryAggTypeCheck(inputs, agg.SumSupportedTypes)
   127  		},
   128  
   129  		Overloads: []overload{
   130  			{
   131  				overloadId: 0,
   132  				isAgg:      true,
   133  				retType:    agg.SumReturnType,
   134  				aggFramework: aggregationLogicOfOverload{
   135  					str:         "sum",
   136  					aggRegister: agg.RegisterSum1,
   137  				},
   138  			},
   139  		},
   140  	},
   141  
   142  	{
   143  		functionId: AVG,
   144  		class:      plan.Function_AGG,
   145  		layout:     STANDARD_FUNCTION,
   146  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   147  			return fixedUnaryAggTypeCheck(inputs, agg.AvgSupportedTypes)
   148  		},
   149  
   150  		Overloads: []overload{
   151  			{
   152  				overloadId: 0,
   153  				isAgg:      true,
   154  				retType:    agg.AvgReturnType,
   155  				aggFramework: aggregationLogicOfOverload{
   156  					str:         "avg",
   157  					aggRegister: agg.RegisterAvg1,
   158  				},
   159  			},
   160  		},
   161  	},
   162  
   163  	{
   164  		functionId: GROUP_CONCAT,
   165  		class:      plan.Function_AGG,
   166  		layout:     STANDARD_FUNCTION,
   167  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   168  			if len(inputs) > 0 {
   169  				kk := make([]types.Type, len(inputs))
   170  				needCast := false
   171  				for i, in := range inputs {
   172  					if in.Oid == types.T_any {
   173  						needCast = true
   174  						kk[i] = types.T_text.ToType()
   175  						continue
   176  					}
   177  					if !aggexec.IsGroupConcatSupported(in) {
   178  						return newCheckResultWithFailure(failedAggParametersWrong)
   179  					}
   180  
   181  					kk[i] = in
   182  				}
   183  				if needCast {
   184  					return newCheckResultWithCast(0, kk)
   185  				}
   186  				return newCheckResultWithSuccess(0)
   187  			}
   188  			return newCheckResultWithFailure(failedAggParametersWrong)
   189  		},
   190  
   191  		Overloads: []overload{
   192  			{
   193  				overloadId: 0,
   194  				isAgg:      true,
   195  				retType:    aggexec.GroupConcatReturnType,
   196  				aggFramework: aggregationLogicOfOverload{
   197  					str:         "group_concat",
   198  					aggRegister: agg.RegisterGroupConcat,
   199  				},
   200  			},
   201  		},
   202  	},
   203  
   204  	{
   205  		functionId: APPROX_COUNT,
   206  		class:      plan.Function_AGG,
   207  		layout:     STANDARD_FUNCTION,
   208  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   209  			if len(inputs) == 1 {
   210  				if inputs[0].Oid == types.T_any {
   211  					return newCheckResultWithCast(0, []types.Type{types.T_uint64.ToType()})
   212  				}
   213  				return newCheckResultWithSuccess(0)
   214  			}
   215  			return newCheckResultWithFailure(failedAggParametersWrong)
   216  		},
   217  
   218  		Overloads: []overload{
   219  			{
   220  				overloadId: 0,
   221  				isAgg:      true,
   222  				retType:    aggexec.CountReturnType,
   223  				aggFramework: aggregationLogicOfOverload{
   224  					str:         "approx_count",
   225  					aggRegister: agg.RegisterApproxCount,
   226  				},
   227  			},
   228  		},
   229  	},
   230  
   231  	// todo: it's a better way to rewrite `approx_count_distinct` to `approx_count(distinct col)`?. not sure.
   232  	{
   233  		functionId: APPROX_COUNT_DISTINCT,
   234  		class:      plan.Function_AGG,
   235  		layout:     STANDARD_FUNCTION,
   236  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   237  			if len(inputs) == 1 {
   238  				if inputs[0].Oid == types.T_any {
   239  					return newCheckResultWithCast(0, []types.Type{types.T_uint64.ToType()})
   240  				}
   241  				return newCheckResultWithSuccess(0)
   242  			}
   243  			return newCheckResultWithFailure(failedAggParametersWrong)
   244  		},
   245  
   246  		Overloads: []overload{
   247  			{
   248  				overloadId: 0,
   249  				isAgg:      true,
   250  				retType:    aggexec.CountReturnType,
   251  				aggFramework: aggregationLogicOfOverload{
   252  					str:         "approx_count_distinct",
   253  					aggRegister: agg.RegisterApproxCount,
   254  				},
   255  			},
   256  		},
   257  	},
   258  
   259  	{
   260  		functionId: ANY_VALUE,
   261  		class:      plan.Function_AGG,
   262  		layout:     STANDARD_FUNCTION,
   263  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   264  			return fixedUnaryAggTypeCheck(inputs, agg.AnyValueSupportedTypes)
   265  		},
   266  
   267  		Overloads: []overload{
   268  			{
   269  				overloadId: 0,
   270  				isAgg:      true,
   271  				retType:    agg.AnyValueReturnType,
   272  				aggFramework: aggregationLogicOfOverload{
   273  					str:         "any_value",
   274  					aggRegister: agg.RegisterAnyValue1,
   275  				},
   276  			},
   277  		},
   278  	},
   279  
   280  	{
   281  		functionId: BIT_AND,
   282  		class:      plan.Function_AGG,
   283  		layout:     STANDARD_FUNCTION,
   284  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   285  			return fixedUnaryAggTypeCheck(inputs, agg.BitAndSupportedParameters)
   286  		},
   287  
   288  		Overloads: []overload{
   289  			{
   290  				overloadId: 0,
   291  				isAgg:      true,
   292  				retType:    agg.BitAndReturnType,
   293  				aggFramework: aggregationLogicOfOverload{
   294  					str:         "bit_and",
   295  					aggRegister: agg.RegisterBitAnd1,
   296  				},
   297  			},
   298  		},
   299  	},
   300  
   301  	{
   302  		functionId: BIT_OR,
   303  		class:      plan.Function_AGG,
   304  		layout:     STANDARD_FUNCTION,
   305  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   306  			return fixedUnaryAggTypeCheck(inputs, agg.BitAndSupportedParameters)
   307  		},
   308  
   309  		Overloads: []overload{
   310  			{
   311  				overloadId: 0,
   312  				isAgg:      true,
   313  				retType:    agg.BitAndReturnType,
   314  				aggFramework: aggregationLogicOfOverload{
   315  					str:         "bit_or",
   316  					aggRegister: agg.RegisterBitOr1,
   317  				},
   318  			},
   319  		},
   320  	},
   321  
   322  	{
   323  		functionId: BIT_XOR,
   324  		class:      plan.Function_AGG,
   325  		layout:     STANDARD_FUNCTION,
   326  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   327  			return fixedUnaryAggTypeCheck(inputs, agg.BitAndSupportedParameters)
   328  		},
   329  
   330  		Overloads: []overload{
   331  			{
   332  				overloadId: 0,
   333  				isAgg:      true,
   334  				retType:    agg.BitAndReturnType,
   335  				aggFramework: aggregationLogicOfOverload{
   336  					str:         "bit_xor",
   337  					aggRegister: agg.RegisterBitXor1,
   338  				},
   339  			},
   340  		},
   341  	},
   342  
   343  	{
   344  		functionId: VAR_POP,
   345  		class:      plan.Function_AGG,
   346  		layout:     STANDARD_FUNCTION,
   347  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   348  			return fixedUnaryAggTypeCheck(inputs, agg.VarPopSupportedParameters)
   349  		},
   350  
   351  		Overloads: []overload{
   352  			{
   353  				overloadId: 0,
   354  				isAgg:      true,
   355  				retType:    agg.VarPopReturnType,
   356  				aggFramework: aggregationLogicOfOverload{
   357  					str:         "var_pop",
   358  					aggRegister: agg.RegisterVarPop1,
   359  				},
   360  			},
   361  		},
   362  	},
   363  
   364  	{
   365  		functionId: STDDEV_POP,
   366  		class:      plan.Function_AGG,
   367  		layout:     STANDARD_FUNCTION,
   368  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   369  			return fixedUnaryAggTypeCheck(inputs, agg.VarPopSupportedParameters)
   370  		},
   371  
   372  		Overloads: []overload{
   373  			{
   374  				overloadId: 0,
   375  				isAgg:      true,
   376  				retType:    agg.VarPopReturnType,
   377  				aggFramework: aggregationLogicOfOverload{
   378  					str:         "stddev_pop",
   379  					aggRegister: agg.RegisterStdDevPop1,
   380  				},
   381  			},
   382  		},
   383  	},
   384  
   385  	{
   386  		functionId: MEDIAN,
   387  		class:      plan.Function_AGG,
   388  		layout:     STANDARD_FUNCTION,
   389  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   390  			return fixedUnaryAggTypeCheck(inputs, aggexec.MedianSupportedType)
   391  		},
   392  
   393  		Overloads: []overload{
   394  			{
   395  				overloadId: 0,
   396  				isAgg:      true,
   397  				retType:    aggexec.MedianReturnType,
   398  				aggFramework: aggregationLogicOfOverload{
   399  					str:         "median",
   400  					aggRegister: agg.RegisterMedian,
   401  				},
   402  			},
   403  		},
   404  	},
   405  
   406  	{
   407  		functionId: CLUSTER_CENTERS,
   408  		class:      plan.Function_AGG,
   409  		layout:     STANDARD_FUNCTION,
   410  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   411  			if len(inputs) == 1 {
   412  				return fixedUnaryAggTypeCheck(inputs, aggexec.ClusterCentersSupportTypes)
   413  			}
   414  			if len(inputs) == 2 && inputs[1].IsVarlen() {
   415  				result := fixedUnaryAggTypeCheck(inputs[:1], aggexec.ClusterCentersSupportTypes)
   416  				if result.status == succeedMatched {
   417  					return result
   418  				}
   419  				if result.status == succeedWithCast {
   420  					result.finalType = append(result.finalType, types.T_varchar.ToType())
   421  					return result
   422  				}
   423  			}
   424  			return newCheckResultWithFailure(failedAggParametersWrong)
   425  		},
   426  
   427  		Overloads: []overload{
   428  			{
   429  				overloadId: 0,
   430  				isAgg:      true,
   431  				retType:    aggexec.ClusterCentersReturnType,
   432  				aggFramework: aggregationLogicOfOverload{
   433  					str:         "cluster_centers",
   434  					aggRegister: agg.RegisterClusterCenters,
   435  				},
   436  			},
   437  		},
   438  	},
   439  
   440  	// function `BITMAP_CONSTRUCT_AGG`
   441  	{
   442  		functionId: BITMAP_CONSTRUCT_AGG,
   443  		class:      plan.Function_AGG,
   444  		layout:     STANDARD_FUNCTION,
   445  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   446  			return fixedUnaryAggTypeCheck(inputs, agg.BitmapConstructSupportedTypes)
   447  		},
   448  
   449  		Overloads: []overload{
   450  			{
   451  				overloadId: 0,
   452  				args:       agg.BitmapConstructSupportedTypes,
   453  				retType:    agg.BitmapConstructReturnType,
   454  
   455  				isAgg: true,
   456  				aggFramework: aggregationLogicOfOverload{
   457  					str:         "bitmap_construct_agg",
   458  					aggRegister: agg.RegisterBitmapConstruct1,
   459  				},
   460  			},
   461  		},
   462  	},
   463  
   464  	// function `BITMAP_OR_AGG`
   465  	{
   466  		functionId: BITMAP_OR_AGG,
   467  		class:      plan.Function_AGG,
   468  		layout:     STANDARD_FUNCTION,
   469  		checkFn: func(overloads []overload, inputs []types.Type) checkResult {
   470  			return fixedUnaryAggTypeCheck(inputs, agg.BitmapOrSupportedTypes)
   471  		},
   472  
   473  		Overloads: []overload{
   474  			{
   475  				overloadId: 0,
   476  				args:       agg.BitmapOrSupportedTypes,
   477  				retType:    agg.BitmapOrReturnType,
   478  
   479  				isAgg: true,
   480  				aggFramework: aggregationLogicOfOverload{
   481  					str:         "bitmap_or_agg",
   482  					aggRegister: agg.RegisterBitmapOr1,
   483  				},
   484  			},
   485  		},
   486  	},
   487  }