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

     1  // Copyright 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 plan
    16  
    17  import (
    18  	"bytes"
    19  	"container/list"
    20  	"context"
    21  	"encoding/csv"
    22  	"fmt"
    23  	"math"
    24  	"path"
    25  	"strings"
    26  
    27  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    28  	"github.com/matrixorigin/matrixone/pkg/common/mpool"
    29  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    30  	"github.com/matrixorigin/matrixone/pkg/container/types"
    31  	"github.com/matrixorigin/matrixone/pkg/container/vector"
    32  	"github.com/matrixorigin/matrixone/pkg/fileservice"
    33  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    34  	"github.com/matrixorigin/matrixone/pkg/sql/colexec"
    35  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/dialect"
    36  	"github.com/matrixorigin/matrixone/pkg/sql/parsers/tree"
    37  	"github.com/matrixorigin/matrixone/pkg/sql/plan/function"
    38  	"github.com/matrixorigin/matrixone/pkg/sql/plan/rule"
    39  	"github.com/matrixorigin/matrixone/pkg/sql/util"
    40  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    41  )
    42  
    43  func GetBindings(expr *plan.Expr) []int32 {
    44  	bindingSet := doGetBindings(expr)
    45  	bindings := make([]int32, 0, len(bindingSet))
    46  	for id := range bindingSet {
    47  		bindings = append(bindings, id)
    48  	}
    49  	return bindings
    50  }
    51  
    52  func doGetBindings(expr *plan.Expr) map[int32]bool {
    53  	res := make(map[int32]bool)
    54  
    55  	switch expr := expr.Expr.(type) {
    56  	case *plan.Expr_Col:
    57  		res[expr.Col.RelPos] = true
    58  
    59  	case *plan.Expr_F:
    60  		for _, child := range expr.F.Args {
    61  			for id := range doGetBindings(child) {
    62  				res[id] = true
    63  			}
    64  		}
    65  	}
    66  
    67  	return res
    68  }
    69  
    70  func hasParam(expr *plan.Expr) bool {
    71  	switch exprImpl := expr.Expr.(type) {
    72  	case *plan.Expr_P:
    73  		return true
    74  
    75  	case *plan.Expr_F:
    76  		for _, arg := range exprImpl.F.Args {
    77  			if hasParam(arg) {
    78  				return true
    79  			}
    80  		}
    81  		return false
    82  
    83  	case *plan.Expr_List:
    84  		for _, arg := range exprImpl.List.List {
    85  			if hasParam(arg) {
    86  				return true
    87  			}
    88  		}
    89  		return false
    90  
    91  	default:
    92  		return false
    93  	}
    94  }
    95  
    96  func hasCorrCol(expr *plan.Expr) bool {
    97  	switch exprImpl := expr.Expr.(type) {
    98  	case *plan.Expr_Corr:
    99  		return true
   100  
   101  	case *plan.Expr_F:
   102  		for _, arg := range exprImpl.F.Args {
   103  			if hasCorrCol(arg) {
   104  				return true
   105  			}
   106  		}
   107  		return false
   108  
   109  	case *plan.Expr_List:
   110  		for _, arg := range exprImpl.List.List {
   111  			if hasCorrCol(arg) {
   112  				return true
   113  			}
   114  		}
   115  		return false
   116  
   117  	default:
   118  		return false
   119  	}
   120  }
   121  
   122  func hasSubquery(expr *plan.Expr) bool {
   123  	switch exprImpl := expr.Expr.(type) {
   124  	case *plan.Expr_Sub:
   125  		return true
   126  
   127  	case *plan.Expr_F:
   128  		for _, arg := range exprImpl.F.Args {
   129  			if hasSubquery(arg) {
   130  				return true
   131  			}
   132  		}
   133  		return false
   134  
   135  	case *plan.Expr_List:
   136  		for _, arg := range exprImpl.List.List {
   137  			if hasSubquery(arg) {
   138  				return true
   139  			}
   140  		}
   141  		return false
   142  
   143  	default:
   144  		return false
   145  	}
   146  }
   147  
   148  func HasTag(expr *plan.Expr, tag int32) bool {
   149  	switch exprImpl := expr.Expr.(type) {
   150  	case *plan.Expr_Col:
   151  		return exprImpl.Col.RelPos == tag
   152  
   153  	case *plan.Expr_F:
   154  		for _, arg := range exprImpl.F.Args {
   155  			if HasTag(arg, tag) {
   156  				return true
   157  			}
   158  		}
   159  		return false
   160  
   161  	case *plan.Expr_List:
   162  		for _, arg := range exprImpl.List.List {
   163  			if HasTag(arg, tag) {
   164  				return true
   165  			}
   166  		}
   167  		return false
   168  
   169  	default:
   170  		return false
   171  	}
   172  }
   173  
   174  func decreaseDepthAndDispatch(preds []*plan.Expr) ([]*plan.Expr, []*plan.Expr) {
   175  	filterPreds := make([]*plan.Expr, 0, len(preds))
   176  	joinPreds := make([]*plan.Expr, 0, len(preds))
   177  
   178  	for _, pred := range preds {
   179  		newPred, correlated := decreaseDepth(pred)
   180  		if !correlated {
   181  			joinPreds = append(joinPreds, newPred)
   182  			continue
   183  		}
   184  		filterPreds = append(filterPreds, newPred)
   185  	}
   186  
   187  	return filterPreds, joinPreds
   188  }
   189  
   190  func decreaseDepth(expr *plan.Expr) (*plan.Expr, bool) {
   191  	var correlated bool
   192  
   193  	switch exprImpl := expr.Expr.(type) {
   194  	case *plan.Expr_Corr:
   195  		if exprImpl.Corr.Depth > 1 {
   196  			exprImpl.Corr.Depth--
   197  			correlated = true
   198  		} else {
   199  			expr.Expr = &plan.Expr_Col{
   200  				Col: &plan.ColRef{
   201  					RelPos: exprImpl.Corr.RelPos,
   202  					ColPos: exprImpl.Corr.ColPos,
   203  				},
   204  			}
   205  		}
   206  
   207  	case *plan.Expr_F:
   208  		var tmp bool
   209  		for i, arg := range exprImpl.F.Args {
   210  			exprImpl.F.Args[i], tmp = decreaseDepth(arg)
   211  			correlated = correlated || tmp
   212  		}
   213  	}
   214  
   215  	return expr, correlated
   216  }
   217  
   218  func getJoinSide(expr *plan.Expr, leftTags, rightTags map[int32]bool, markTag int32) (side int8) {
   219  	switch exprImpl := expr.Expr.(type) {
   220  	case *plan.Expr_F:
   221  		for _, arg := range exprImpl.F.Args {
   222  			side |= getJoinSide(arg, leftTags, rightTags, markTag)
   223  		}
   224  
   225  	case *plan.Expr_Col:
   226  		if leftTags[exprImpl.Col.RelPos] {
   227  			side = JoinSideLeft
   228  		} else if rightTags[exprImpl.Col.RelPos] {
   229  			side = JoinSideRight
   230  		} else if exprImpl.Col.RelPos == markTag {
   231  			side = JoinSideMark
   232  		}
   233  
   234  	case *plan.Expr_Corr:
   235  		side = JoinSideCorrelated
   236  	}
   237  
   238  	return
   239  }
   240  
   241  func containsTag(expr *plan.Expr, tag int32) bool {
   242  	var ret bool
   243  
   244  	switch exprImpl := expr.Expr.(type) {
   245  	case *plan.Expr_F:
   246  		for _, arg := range exprImpl.F.Args {
   247  			ret = ret || containsTag(arg, tag)
   248  		}
   249  
   250  	case *plan.Expr_Col:
   251  		return exprImpl.Col.RelPos == tag
   252  	}
   253  
   254  	return ret
   255  }
   256  
   257  func replaceColRefs(expr *plan.Expr, tag int32, projects []*plan.Expr) *plan.Expr {
   258  	switch exprImpl := expr.Expr.(type) {
   259  	case *plan.Expr_F:
   260  		for i, arg := range exprImpl.F.Args {
   261  			exprImpl.F.Args[i] = replaceColRefs(arg, tag, projects)
   262  		}
   263  
   264  	case *plan.Expr_Col:
   265  		colRef := exprImpl.Col
   266  		if colRef.RelPos == tag {
   267  			expr = DeepCopyExpr(projects[colRef.ColPos])
   268  		}
   269  	case *plan.Expr_W:
   270  		replaceColRefs(exprImpl.W.WindowFunc, tag, projects)
   271  		for _, arg := range exprImpl.W.PartitionBy {
   272  			replaceColRefs(arg, tag, projects)
   273  		}
   274  		for _, order := range exprImpl.W.OrderBy {
   275  			replaceColRefs(order.Expr, tag, projects)
   276  		}
   277  	}
   278  
   279  	return expr
   280  }
   281  
   282  func replaceColRefsForSet(expr *plan.Expr, projects []*plan.Expr) *plan.Expr {
   283  	switch exprImpl := expr.Expr.(type) {
   284  	case *plan.Expr_F:
   285  		for i, arg := range exprImpl.F.Args {
   286  			exprImpl.F.Args[i] = replaceColRefsForSet(arg, projects)
   287  		}
   288  
   289  	case *plan.Expr_Col:
   290  		expr = DeepCopyExpr(projects[exprImpl.Col.ColPos])
   291  	}
   292  
   293  	return expr
   294  }
   295  
   296  func splitAndBindCondition(astExpr tree.Expr, expandAlias ExpandAliasMode, ctx *BindContext) ([]*plan.Expr, error) {
   297  	conds := splitAstConjunction(astExpr)
   298  	exprs := make([]*plan.Expr, len(conds))
   299  
   300  	for i, cond := range conds {
   301  		cond, err := ctx.qualifyColumnNames(cond, expandAlias)
   302  		if err != nil {
   303  			return nil, err
   304  		}
   305  
   306  		expr, err := ctx.binder.BindExpr(cond, 0, true)
   307  		if err != nil {
   308  			return nil, err
   309  		}
   310  		// expr must be bool type, if not, try to do type convert
   311  		// but just ignore the subQuery. It will be solved at optimizer.
   312  		if expr.GetSub() == nil {
   313  			expr, err = makePlan2CastExpr(ctx.binder.GetContext(), expr, plan.Type{Id: int32(types.T_bool)})
   314  			if err != nil {
   315  				return nil, err
   316  			}
   317  		}
   318  		exprs[i] = expr
   319  	}
   320  
   321  	return exprs, nil
   322  }
   323  
   324  // splitAstConjunction split a expression to a list of AND conditions.
   325  func splitAstConjunction(astExpr tree.Expr) []tree.Expr {
   326  	var astExprs []tree.Expr
   327  	switch typ := astExpr.(type) {
   328  	case nil:
   329  	case *tree.AndExpr:
   330  		astExprs = append(astExprs, splitAstConjunction(typ.Left)...)
   331  		astExprs = append(astExprs, splitAstConjunction(typ.Right)...)
   332  	case *tree.ParenExpr:
   333  		astExprs = append(astExprs, splitAstConjunction(typ.Expr)...)
   334  	default:
   335  		astExprs = append(astExprs, astExpr)
   336  	}
   337  	return astExprs
   338  }
   339  
   340  // applyDistributivity (X AND B) OR (X AND C) OR (X AND D) => X AND (B OR C OR D)
   341  // TODO: move it into optimizer
   342  func applyDistributivity(ctx context.Context, expr *plan.Expr) *plan.Expr {
   343  	switch exprImpl := expr.Expr.(type) {
   344  	case *plan.Expr_F:
   345  		for i, arg := range exprImpl.F.Args {
   346  			exprImpl.F.Args[i] = applyDistributivity(ctx, arg)
   347  		}
   348  
   349  		if exprImpl.F.Func.ObjName != "or" {
   350  			break
   351  		}
   352  
   353  		leftConds := splitPlanConjunction(exprImpl.F.Args[0])
   354  		rightConds := splitPlanConjunction(exprImpl.F.Args[1])
   355  
   356  		condMap := make(map[string]int)
   357  
   358  		for _, cond := range rightConds {
   359  			condMap[cond.String()] = JoinSideRight
   360  		}
   361  
   362  		var commonConds, leftOnlyConds, rightOnlyConds []*plan.Expr
   363  
   364  		for _, cond := range leftConds {
   365  			exprStr := cond.String()
   366  
   367  			if condMap[exprStr] == JoinSideRight {
   368  				commonConds = append(commonConds, cond)
   369  				condMap[exprStr] = JoinSideBoth
   370  			} else {
   371  				leftOnlyConds = append(leftOnlyConds, cond)
   372  				condMap[exprStr] = JoinSideLeft
   373  			}
   374  		}
   375  
   376  		for _, cond := range rightConds {
   377  			if condMap[cond.String()] == JoinSideRight {
   378  				rightOnlyConds = append(rightOnlyConds, cond)
   379  			}
   380  		}
   381  
   382  		if len(commonConds) == 0 {
   383  			return expr
   384  		}
   385  
   386  		expr, _ = combinePlanConjunction(ctx, commonConds)
   387  
   388  		if len(leftOnlyConds) == 0 || len(rightOnlyConds) == 0 {
   389  			return expr
   390  		}
   391  
   392  		leftExpr, _ := combinePlanConjunction(ctx, leftOnlyConds)
   393  		rightExpr, _ := combinePlanConjunction(ctx, rightOnlyConds)
   394  
   395  		leftExpr, _ = BindFuncExprImplByPlanExpr(ctx, "or", []*plan.Expr{leftExpr, rightExpr})
   396  
   397  		expr, _ = BindFuncExprImplByPlanExpr(ctx, "and", []*plan.Expr{expr, leftExpr})
   398  	}
   399  
   400  	return expr
   401  }
   402  
   403  func unionSlice(left, right []string) []string {
   404  	if len(left) < 1 {
   405  		return right
   406  	}
   407  	if len(right) < 1 {
   408  		return left
   409  	}
   410  	m := make(map[string]bool, len(left)+len(right))
   411  	for _, s := range left {
   412  		m[s] = true
   413  	}
   414  	for _, s := range right {
   415  		m[s] = true
   416  	}
   417  	ret := make([]string, 0)
   418  	for s := range m {
   419  		ret = append(ret, s)
   420  	}
   421  	return ret
   422  }
   423  
   424  func intersectSlice(left, right []string) []string {
   425  	if len(left) < 1 || len(right) < 1 {
   426  		return left
   427  	}
   428  	m := make(map[string]bool, len(left)+len(right))
   429  	for _, s := range left {
   430  		m[s] = true
   431  	}
   432  	ret := make([]string, 0)
   433  	for _, s := range right {
   434  		if _, ok := m[s]; ok {
   435  			ret = append(ret, s)
   436  		}
   437  	}
   438  	return ret
   439  }
   440  
   441  /*
   442  DNF means disjunctive normal form, for example (a and b) or (c and d) or (e and f)
   443  if we have a DNF filter, for example (c1=1 and c2=1) or (c1=2 and c2=2)
   444  we can have extra filter: (c1=1 or c1=2) and (c2=1 or c2=2), which can be pushed down to optimize join
   445  
   446  checkDNF scan the expr and return all groups of cond
   447  for example (c1=1 and c2=1) or (c1=2 and c3=2), c1 is a group because it appears in all disjunctives
   448  and c2,c3 is not a group
   449  
   450  walkThroughDNF accept a keyword string, walk through the expr,
   451  and extract all the conds which contains the keyword
   452  */
   453  func checkDNF(expr *plan.Expr) []string {
   454  	var ret []string
   455  	switch exprImpl := expr.Expr.(type) {
   456  	case *plan.Expr_F:
   457  		if exprImpl.F.Func.ObjName == "or" {
   458  			left := checkDNF(exprImpl.F.Args[0])
   459  			right := checkDNF(exprImpl.F.Args[1])
   460  			return intersectSlice(left, right)
   461  		}
   462  		for _, arg := range exprImpl.F.Args {
   463  			ret = unionSlice(ret, checkDNF(arg))
   464  		}
   465  		return ret
   466  
   467  	case *plan.Expr_Corr:
   468  		ret = append(ret, exprImpl.Corr.String())
   469  	case *plan.Expr_Col:
   470  		ret = append(ret, exprImpl.Col.String())
   471  	}
   472  	return ret
   473  }
   474  
   475  func walkThroughDNF(ctx context.Context, expr *plan.Expr, keywords string) *plan.Expr {
   476  	var retExpr *plan.Expr
   477  	switch exprImpl := expr.Expr.(type) {
   478  	case *plan.Expr_F:
   479  		if exprImpl.F.Func.ObjName == "or" {
   480  			left := walkThroughDNF(ctx, exprImpl.F.Args[0], keywords)
   481  			right := walkThroughDNF(ctx, exprImpl.F.Args[1], keywords)
   482  			if left != nil && right != nil {
   483  				retExpr, _ = BindFuncExprImplByPlanExpr(ctx, "or", []*plan.Expr{left, right})
   484  				return retExpr
   485  			}
   486  		} else if exprImpl.F.Func.ObjName == "and" {
   487  			left := walkThroughDNF(ctx, exprImpl.F.Args[0], keywords)
   488  			right := walkThroughDNF(ctx, exprImpl.F.Args[1], keywords)
   489  			if left == nil {
   490  				return right
   491  			} else if right == nil {
   492  				return left
   493  			} else {
   494  				retExpr, _ = BindFuncExprImplByPlanExpr(ctx, "and", []*plan.Expr{left, right})
   495  				return retExpr
   496  			}
   497  		} else {
   498  			for _, arg := range exprImpl.F.Args {
   499  				if walkThroughDNF(ctx, arg, keywords) == nil {
   500  					return nil
   501  				}
   502  			}
   503  			return expr
   504  		}
   505  
   506  	case *plan.Expr_Corr:
   507  		if exprImpl.Corr.String() == keywords {
   508  			return expr
   509  		} else {
   510  			return nil
   511  		}
   512  	case *plan.Expr_Col:
   513  		if exprImpl.Col.String() == keywords {
   514  			return expr
   515  		} else {
   516  			return nil
   517  		}
   518  	}
   519  	return expr
   520  }
   521  
   522  // deduction of new predicates for join on list. for example join on a=b and b=c, then a=c can be deduced
   523  func deduceNewOnList(onList []*plan.Expr) []*plan.Expr {
   524  	var newPreds []*plan.Expr
   525  	lenOnlist := len(onList)
   526  	for i := range onList {
   527  		ok1, col1, col2 := checkStrictJoinPred(onList[i])
   528  		if !ok1 {
   529  			continue
   530  		}
   531  		for j := i + 1; j < lenOnlist; j++ {
   532  			ok2, col3, col4 := checkStrictJoinPred(onList[j])
   533  			if ok2 {
   534  				ok, newPred := deduceTranstivity(onList[i], col1, col2, col3, col4)
   535  				if ok {
   536  					newPreds = append(newPreds, newPred)
   537  				}
   538  			}
   539  		}
   540  	}
   541  	return newPreds
   542  }
   543  
   544  // deduction of new predicates. for example join on a=b where b=1, then a=1 can be deduced
   545  func deduceNewFilterList(filters, onList []*plan.Expr) []*plan.Expr {
   546  	var newFilters []*plan.Expr
   547  	for _, onPred := range onList {
   548  		ret, col1, col2 := checkStrictJoinPred(onPred)
   549  		if !ret {
   550  			continue
   551  		}
   552  		for _, filter := range filters {
   553  			col := extractColRefInFilter(filter)
   554  			if col != nil {
   555  				newExpr := DeepCopyExpr(filter)
   556  				if substituteMatchColumn(newExpr, col1, col2) {
   557  					newFilters = append(newFilters, newExpr)
   558  				}
   559  			}
   560  		}
   561  	}
   562  	return newFilters
   563  }
   564  
   565  func canMergeToBetweenAnd(expr1, expr2 *plan.Expr) bool {
   566  	col1, _, _, _ := extractColRefAndLiteralsInFilter(expr1)
   567  	col2, _, _, _ := extractColRefAndLiteralsInFilter(expr2)
   568  	if col1 == nil || col2 == nil {
   569  		return false
   570  	}
   571  	if col1.ColPos != col2.ColPos || col1.RelPos != col2.RelPos {
   572  		return false
   573  	}
   574  
   575  	fnName1 := expr1.GetF().Func.ObjName
   576  	fnName2 := expr2.GetF().Func.ObjName
   577  	if fnName1 == ">" || fnName1 == ">=" {
   578  		return fnName2 == "<" || fnName2 == "<="
   579  	}
   580  	if fnName1 == "<" || fnName1 == "<=" {
   581  		return fnName2 == ">" || fnName2 == ">="
   582  	}
   583  	return false
   584  }
   585  
   586  func extractColRefAndLiteralsInFilter(expr *plan.Expr) (col *ColRef, litType types.T, literals []*Const, colFnName string) {
   587  	fn := expr.GetF()
   588  	if fn == nil || len(fn.Args) == 0 {
   589  		return
   590  	}
   591  
   592  	col = fn.Args[0].GetCol()
   593  	if col == nil {
   594  		if fn0 := fn.Args[0].GetF(); fn0 != nil {
   595  			switch fn0.Func.ObjName {
   596  			case "year":
   597  				colFnName = "year"
   598  				col = fn0.Args[0].GetCol()
   599  			}
   600  		}
   601  	}
   602  	if col == nil {
   603  		return
   604  	}
   605  
   606  	switch fn.Func.ObjName {
   607  	case "=", ">", "<", ">=", "<=":
   608  		lit := fn.Args[1].GetLit()
   609  		if lit == nil {
   610  			return
   611  		}
   612  		litType = types.T(fn.Args[0].Typ.Id)
   613  		literals = []*Const{lit}
   614  
   615  	case "between":
   616  		litType = types.T(fn.Args[0].Typ.Id)
   617  		literals = []*Const{fn.Args[1].GetLit(), fn.Args[2].GetLit()}
   618  	}
   619  
   620  	return
   621  }
   622  
   623  // for predicate deduction, filter must be like func(col)>1 , or (col=1) or (col=2)
   624  // and only 1 colRef is allowd in the filter
   625  func extractColRefInFilter(expr *plan.Expr) *ColRef {
   626  	switch exprImpl := expr.Expr.(type) {
   627  	case *plan.Expr_F:
   628  		switch exprImpl.F.Func.ObjName {
   629  		case "=", ">", "<", ">=", "<=", "prefix_eq", "between", "in", "prefix_in":
   630  			switch e := exprImpl.F.Args[1].Expr.(type) {
   631  			case *plan.Expr_Lit, *plan.Expr_P, *plan.Expr_V, *plan.Expr_Vec:
   632  				return extractColRefInFilter(exprImpl.F.Args[0])
   633  			case *plan.Expr_F:
   634  				switch e.F.Func.ObjName {
   635  				case "cast", "serial":
   636  					return extractColRefInFilter(exprImpl.F.Args[0])
   637  				}
   638  				return nil
   639  			default:
   640  				return nil
   641  			}
   642  		default:
   643  			var col *ColRef
   644  			for _, arg := range exprImpl.F.Args {
   645  				c := extractColRefInFilter(arg)
   646  				if c == nil {
   647  					return nil
   648  				}
   649  				if col != nil {
   650  					if col.RelPos != c.RelPos || col.ColPos != c.ColPos {
   651  						return nil
   652  					}
   653  				} else {
   654  					col = c
   655  				}
   656  			}
   657  			return col
   658  		}
   659  	case *plan.Expr_Col:
   660  		return exprImpl.Col
   661  	}
   662  	return nil
   663  }
   664  
   665  // for col1=col2 and col3 = col4, trying to deduce new pred
   666  // for example , if col1 and col3 are the same, then we can deduce that col2=col4
   667  func deduceTranstivity(expr *plan.Expr, col1, col2, col3, col4 *ColRef) (bool, *plan.Expr) {
   668  	if col1.String() == col3.String() || col1.String() == col4.String() || col2.String() == col3.String() || col2.String() == col4.String() {
   669  		retExpr := DeepCopyExpr(expr)
   670  		substituteMatchColumn(retExpr, col3, col4)
   671  		return true, retExpr
   672  	}
   673  	return false, nil
   674  }
   675  
   676  // if match col1 in expr, substitute it to col2. and othterwise
   677  func substituteMatchColumn(expr *plan.Expr, onPredCol1, onPredCol2 *ColRef) bool {
   678  	var ret bool
   679  	switch exprImpl := expr.Expr.(type) {
   680  	case *plan.Expr_Col:
   681  		colName := exprImpl.Col.String()
   682  		if colName == onPredCol1.String() {
   683  			exprImpl.Col.RelPos = onPredCol2.RelPos
   684  			exprImpl.Col.ColPos = onPredCol2.ColPos
   685  			exprImpl.Col.Name = onPredCol2.Name
   686  			return true
   687  		} else if colName == onPredCol2.String() {
   688  			exprImpl.Col.RelPos = onPredCol1.RelPos
   689  			exprImpl.Col.ColPos = onPredCol1.ColPos
   690  			exprImpl.Col.Name = onPredCol1.Name
   691  			return true
   692  		}
   693  	case *plan.Expr_F:
   694  		for _, arg := range exprImpl.F.Args {
   695  			if substituteMatchColumn(arg, onPredCol1, onPredCol2) {
   696  				ret = true
   697  			}
   698  		}
   699  	}
   700  	return ret
   701  }
   702  
   703  func checkStrictJoinPred(onPred *plan.Expr) (bool, *ColRef, *ColRef) {
   704  	//onPred must be equality, children must be column name
   705  	switch onPredImpl := onPred.Expr.(type) {
   706  	case *plan.Expr_F:
   707  		if onPredImpl.F.Func.ObjName != "=" {
   708  			return false, nil, nil
   709  		}
   710  		args := onPredImpl.F.Args
   711  		var col1, col2 *ColRef
   712  		switch child1 := args[0].Expr.(type) {
   713  		case *plan.Expr_Col:
   714  			col1 = child1.Col
   715  		}
   716  		switch child2 := args[1].Expr.(type) {
   717  		case *plan.Expr_Col:
   718  			col2 = child2.Col
   719  		}
   720  		if col1 != nil && col2 != nil {
   721  			return true, col1, col2
   722  		}
   723  	}
   724  	return false, nil, nil
   725  }
   726  
   727  func splitPlanConjunctions(exprList []*plan.Expr) []*plan.Expr {
   728  	var exprs []*plan.Expr
   729  	for _, expr := range exprList {
   730  		exprs = append(exprs, splitPlanConjunction(expr)...)
   731  	}
   732  	return exprs
   733  }
   734  
   735  func splitPlanConjunction(expr *plan.Expr) []*plan.Expr {
   736  	var exprs []*plan.Expr
   737  	switch exprImpl := expr.Expr.(type) {
   738  	case *plan.Expr_F:
   739  		if exprImpl.F.Func.ObjName == "and" {
   740  			exprs = append(exprs, splitPlanConjunction(exprImpl.F.Args[0])...)
   741  			exprs = append(exprs, splitPlanConjunction(exprImpl.F.Args[1])...)
   742  		} else {
   743  			exprs = append(exprs, expr)
   744  		}
   745  
   746  	default:
   747  		exprs = append(exprs, expr)
   748  	}
   749  
   750  	return exprs
   751  }
   752  
   753  func combinePlanConjunction(ctx context.Context, exprs []*plan.Expr) (expr *plan.Expr, err error) {
   754  	expr = exprs[0]
   755  
   756  	for i := 1; i < len(exprs); i++ {
   757  		expr, err = BindFuncExprImplByPlanExpr(ctx, "and", []*plan.Expr{expr, exprs[i]})
   758  
   759  		if err != nil {
   760  			break
   761  		}
   762  	}
   763  
   764  	return
   765  }
   766  
   767  func rejectsNull(filter *plan.Expr, proc *process.Process) bool {
   768  	filter = replaceColRefWithNull(DeepCopyExpr(filter))
   769  
   770  	filter, err := ConstantFold(batch.EmptyForConstFoldBatch, filter, proc, false)
   771  	if err != nil {
   772  		return false
   773  	}
   774  
   775  	if f, ok := filter.Expr.(*plan.Expr_Lit); ok {
   776  		if f.Lit.Isnull {
   777  			return true
   778  		}
   779  
   780  		if fbool, ok := f.Lit.Value.(*plan.Literal_Bval); ok {
   781  			return !fbool.Bval
   782  		}
   783  	}
   784  
   785  	return false
   786  }
   787  
   788  func replaceColRefWithNull(expr *plan.Expr) *plan.Expr {
   789  	switch exprImpl := expr.Expr.(type) {
   790  	case *plan.Expr_Col:
   791  		expr = &plan.Expr{
   792  			Typ: expr.Typ,
   793  			Expr: &plan.Expr_Lit{
   794  				Lit: &plan.Literal{
   795  					Isnull: true,
   796  				},
   797  			},
   798  		}
   799  
   800  	case *plan.Expr_F:
   801  		for i, arg := range exprImpl.F.Args {
   802  			exprImpl.F.Args[i] = replaceColRefWithNull(arg)
   803  		}
   804  	}
   805  
   806  	return expr
   807  }
   808  
   809  func increaseRefCnt(expr *plan.Expr, inc int, colRefCnt map[[2]int32]int) {
   810  	switch exprImpl := expr.Expr.(type) {
   811  	case *plan.Expr_Col:
   812  		colRefCnt[[2]int32{exprImpl.Col.RelPos, exprImpl.Col.ColPos}] += inc
   813  
   814  	case *plan.Expr_F:
   815  		for _, arg := range exprImpl.F.Args {
   816  			increaseRefCnt(arg, inc, colRefCnt)
   817  		}
   818  	case *plan.Expr_W:
   819  		increaseRefCnt(exprImpl.W.WindowFunc, inc, colRefCnt)
   820  		//for _, arg := range exprImpl.W.PartitionBy {
   821  		//	increaseRefCnt(arg, inc, colRefCnt)
   822  		//}
   823  		for _, order := range exprImpl.W.OrderBy {
   824  			increaseRefCnt(order.Expr, inc, colRefCnt)
   825  		}
   826  	}
   827  }
   828  
   829  func getHyperEdgeFromExpr(expr *plan.Expr, leafByTag map[int32]int32, hyperEdge map[int32]bool) {
   830  	switch exprImpl := expr.Expr.(type) {
   831  	case *plan.Expr_Col:
   832  		hyperEdge[leafByTag[exprImpl.Col.RelPos]] = true
   833  
   834  	case *plan.Expr_F:
   835  		for _, arg := range exprImpl.F.Args {
   836  			getHyperEdgeFromExpr(arg, leafByTag, hyperEdge)
   837  		}
   838  	}
   839  }
   840  
   841  func getNumOfCharacters(str string) int {
   842  	strRune := []rune(str)
   843  	return len(strRune)
   844  }
   845  
   846  func getUnionSelects(ctx context.Context, stmt *tree.UnionClause, selects *[]tree.Statement, unionTypes *[]plan.Node_NodeType) error {
   847  	switch leftStmt := stmt.Left.(type) {
   848  	case *tree.UnionClause:
   849  		err := getUnionSelects(ctx, leftStmt, selects, unionTypes)
   850  		if err != nil {
   851  			return err
   852  		}
   853  	case *tree.SelectClause:
   854  		*selects = append(*selects, leftStmt)
   855  	case *tree.ParenSelect:
   856  		*selects = append(*selects, leftStmt.Select)
   857  	default:
   858  		return moerr.NewParseError(ctx, "unexpected statement in union: '%v'", tree.String(leftStmt, dialect.MYSQL))
   859  	}
   860  
   861  	// right is not UNION always
   862  	switch rightStmt := stmt.Right.(type) {
   863  	case *tree.SelectClause:
   864  		if stmt.Type == tree.UNION && !stmt.All {
   865  			rightStr := tree.String(rightStmt, dialect.MYSQL)
   866  			if len(*selects) == 1 && tree.String((*selects)[0], dialect.MYSQL) == rightStr {
   867  				return nil
   868  			}
   869  		}
   870  
   871  		*selects = append(*selects, rightStmt)
   872  	case *tree.ParenSelect:
   873  		if stmt.Type == tree.UNION && !stmt.All {
   874  			rightStr := tree.String(rightStmt.Select, dialect.MYSQL)
   875  			if len(*selects) == 1 && tree.String((*selects)[0], dialect.MYSQL) == rightStr {
   876  				return nil
   877  			}
   878  		}
   879  
   880  		*selects = append(*selects, rightStmt.Select)
   881  	default:
   882  		return moerr.NewParseError(ctx, "unexpected statement in union2: '%v'", tree.String(rightStmt, dialect.MYSQL))
   883  	}
   884  
   885  	switch stmt.Type {
   886  	case tree.UNION:
   887  		if stmt.All {
   888  			*unionTypes = append(*unionTypes, plan.Node_UNION_ALL)
   889  		} else {
   890  			*unionTypes = append(*unionTypes, plan.Node_UNION)
   891  		}
   892  	case tree.INTERSECT:
   893  		if stmt.All {
   894  			*unionTypes = append(*unionTypes, plan.Node_INTERSECT_ALL)
   895  		} else {
   896  			*unionTypes = append(*unionTypes, plan.Node_INTERSECT)
   897  		}
   898  	case tree.EXCEPT, tree.UT_MINUS:
   899  		if stmt.All {
   900  			return moerr.NewNYI(ctx, "EXCEPT/MINUS ALL clause")
   901  		} else {
   902  			*unionTypes = append(*unionTypes, plan.Node_MINUS)
   903  		}
   904  	}
   905  	return nil
   906  }
   907  
   908  func GetColumnMapByExpr(expr *plan.Expr, tableDef *plan.TableDef, columnMap map[int]int) {
   909  	if expr == nil {
   910  		return
   911  	}
   912  	switch exprImpl := expr.Expr.(type) {
   913  	case *plan.Expr_F:
   914  		for _, arg := range exprImpl.F.Args {
   915  			GetColumnMapByExpr(arg, tableDef, columnMap)
   916  		}
   917  
   918  	case *plan.Expr_Col:
   919  		idx := exprImpl.Col.ColPos
   920  		colName := exprImpl.Col.Name
   921  		dotIdx := strings.Index(colName, ".")
   922  		colName = colName[dotIdx+1:]
   923  		colIdx := tableDef.Name2ColIndex[colName]
   924  		seqnum := int(colIdx) // for extenal scan case, tableDef has only Name2ColIndex, no Cols, leave seqnum as colIdx
   925  		if len(tableDef.Cols) > 0 {
   926  			seqnum = int(tableDef.Cols[colIdx].Seqnum)
   927  		}
   928  		columnMap[int(idx)] = seqnum
   929  	}
   930  }
   931  
   932  func GetColumnMapByExprs(exprs []*plan.Expr, tableDef *plan.TableDef, columnMap map[int]int) {
   933  	for _, expr := range exprs {
   934  		GetColumnMapByExpr(expr, tableDef, columnMap)
   935  	}
   936  }
   937  
   938  func GetColumnsByExpr(
   939  	expr *plan.Expr,
   940  	tableDef *plan.TableDef,
   941  ) (columnMap map[int]int, defColumns, exprColumns []int, maxCol int) {
   942  	columnMap = make(map[int]int)
   943  	// key = expr's ColPos,  value = tableDef's ColPos
   944  	GetColumnMapByExpr(expr, tableDef, columnMap)
   945  
   946  	if len(columnMap) == 0 {
   947  		return
   948  	}
   949  
   950  	defColumns = make([]int, len(columnMap))
   951  	exprColumns = make([]int, len(columnMap))
   952  
   953  	// k: col pos in expr
   954  	// v: col pos in def
   955  	i := 0
   956  	for k, v := range columnMap {
   957  		if v > maxCol {
   958  			maxCol = v
   959  		}
   960  		exprColumns[i] = k
   961  		defColumns[i] = v
   962  		i = i + 1
   963  	}
   964  	return
   965  }
   966  
   967  func EvalFilterExpr(ctx context.Context, expr *plan.Expr, bat *batch.Batch, proc *process.Process) (bool, error) {
   968  	if len(bat.Vecs) == 0 { //that's constant expr
   969  		e, err := ConstantFold(bat, expr, proc, false)
   970  		if err != nil {
   971  			return false, err
   972  		}
   973  
   974  		if cExpr, ok := e.Expr.(*plan.Expr_Lit); ok {
   975  			if bVal, bOk := cExpr.Lit.Value.(*plan.Literal_Bval); bOk {
   976  				return bVal.Bval, nil
   977  			}
   978  		}
   979  		return false, moerr.NewInternalError(ctx, "cannot eval filter expr")
   980  	} else {
   981  		executor, err := colexec.NewExpressionExecutor(proc, expr)
   982  		if err != nil {
   983  			return false, err
   984  		}
   985  		defer executor.Free()
   986  
   987  		vec, err := executor.Eval(proc, []*batch.Batch{bat})
   988  		if err != nil {
   989  			return false, err
   990  		}
   991  		if vec.GetType().Oid != types.T_bool {
   992  			return false, moerr.NewInternalError(ctx, "cannot eval filter expr")
   993  		}
   994  		cols := vector.MustFixedCol[bool](vec)
   995  		for _, isNeed := range cols {
   996  			if isNeed {
   997  				return true, nil
   998  			}
   999  		}
  1000  		return false, nil
  1001  	}
  1002  }
  1003  
  1004  func exchangeVectors(datas [][2]any, depth int, tmpResult []any, result *[]*vector.Vector, mp *mpool.MPool) {
  1005  	for i := 0; i < len(datas[depth]); i++ {
  1006  		tmpResult[depth] = datas[depth][i]
  1007  		if depth != len(datas)-1 {
  1008  			exchangeVectors(datas, depth+1, tmpResult, result, mp)
  1009  		} else {
  1010  			for j, val := range tmpResult {
  1011  				vector.AppendAny((*result)[j], val, false, mp)
  1012  			}
  1013  		}
  1014  	}
  1015  }
  1016  
  1017  func BuildVectorsByData(datas [][2]any, dataTypes []uint8, mp *mpool.MPool) []*vector.Vector {
  1018  	vectors := make([]*vector.Vector, len(dataTypes))
  1019  	for i, typ := range dataTypes {
  1020  		vectors[i] = vector.NewVec(types.T(typ).ToType())
  1021  	}
  1022  
  1023  	tmpResult := make([]any, len(datas))
  1024  	exchangeVectors(datas, 0, tmpResult, &vectors, mp)
  1025  
  1026  	return vectors
  1027  }
  1028  
  1029  func ExprIsZonemappable(ctx context.Context, expr *plan.Expr) bool {
  1030  	if expr == nil {
  1031  		return false
  1032  	}
  1033  	switch exprImpl := expr.Expr.(type) {
  1034  	case *plan.Expr_F:
  1035  		isConst := true
  1036  		for _, arg := range exprImpl.F.Args {
  1037  			switch arg.Expr.(type) {
  1038  			case *plan.Expr_Lit, *plan.Expr_P, *plan.Expr_V, *plan.Expr_T:
  1039  				continue
  1040  			}
  1041  			isConst = false
  1042  			isZonemappable := ExprIsZonemappable(ctx, arg)
  1043  			if !isZonemappable {
  1044  				return false
  1045  			}
  1046  		}
  1047  		if isConst {
  1048  			return true
  1049  		}
  1050  
  1051  		isZonemappable, _ := function.GetFunctionIsZonemappableById(ctx, exprImpl.F.Func.GetObj())
  1052  		if !isZonemappable {
  1053  			return false
  1054  		}
  1055  
  1056  		return true
  1057  	default:
  1058  		return true
  1059  	}
  1060  }
  1061  
  1062  // todo: remove this in the future
  1063  func GetSortOrderByName(tableDef *plan.TableDef, colName string) int {
  1064  	if tableDef.Pkey != nil {
  1065  		pkNames := tableDef.Pkey.Names
  1066  		for i := range pkNames {
  1067  			if pkNames[i] == colName {
  1068  				return i
  1069  			}
  1070  		}
  1071  	}
  1072  	if tableDef.ClusterBy != nil {
  1073  		return util.GetClusterByColumnOrder(tableDef.ClusterBy.Name, colName)
  1074  	}
  1075  	return -1
  1076  }
  1077  
  1078  func GetSortOrder(tableDef *plan.TableDef, colPos int32) int {
  1079  	colName := tableDef.Cols[colPos].Name
  1080  	return GetSortOrderByName(tableDef, colName)
  1081  }
  1082  
  1083  func ConstandFoldList(exprs []*plan.Expr, proc *process.Process, varAndParamIsConst bool) ([]*plan.Expr, error) {
  1084  	newExprs := DeepCopyExprList(exprs)
  1085  	for i := range newExprs {
  1086  		foldedExpr, err := ConstantFold(batch.EmptyForConstFoldBatch, newExprs[i], proc, varAndParamIsConst)
  1087  		if err != nil {
  1088  			return nil, err
  1089  		}
  1090  		if foldedExpr != nil {
  1091  			newExprs[i] = foldedExpr
  1092  		}
  1093  	}
  1094  	return newExprs, nil
  1095  }
  1096  
  1097  func ConstantFold(bat *batch.Batch, expr *plan.Expr, proc *process.Process, varAndParamIsConst bool) (*plan.Expr, error) {
  1098  	if expr.Typ.Id == int32(types.T_interval) {
  1099  		panic(moerr.NewInternalError(proc.Ctx, "not supported type INTERVAL"))
  1100  	}
  1101  
  1102  	// If it is Expr_List, perform constant folding on its elements
  1103  	if elist := expr.GetList(); elist != nil {
  1104  		exprList := elist.List
  1105  		for i := range exprList {
  1106  			foldExpr, err := ConstantFold(bat, exprList[i], proc, varAndParamIsConst)
  1107  			if err != nil {
  1108  				return nil, err
  1109  			}
  1110  			exprList[i] = foldExpr
  1111  		}
  1112  
  1113  		vec, err := colexec.GenerateConstListExpressionExecutor(proc, exprList)
  1114  		if err != nil {
  1115  			return nil, err
  1116  		}
  1117  		defer vec.Free(proc.Mp())
  1118  
  1119  		vec.InplaceSortAndCompact()
  1120  		data, err := vec.MarshalBinary()
  1121  		if err != nil {
  1122  			return nil, err
  1123  		}
  1124  
  1125  		return &plan.Expr{
  1126  			Typ: expr.Typ,
  1127  			Expr: &plan.Expr_Vec{
  1128  				Vec: &plan.LiteralVec{
  1129  					Len:  int32(vec.Length()),
  1130  					Data: data,
  1131  				},
  1132  			},
  1133  		}, nil
  1134  	}
  1135  
  1136  	fn := expr.GetF()
  1137  	if fn == nil || proc == nil {
  1138  		return expr, nil
  1139  	}
  1140  
  1141  	overloadID := fn.Func.GetObj()
  1142  	f, err := function.GetFunctionById(proc.Ctx, overloadID)
  1143  	if err != nil {
  1144  		return nil, err
  1145  	}
  1146  	if f.CannotFold() || f.IsRealTimeRelated() {
  1147  		return expr, nil
  1148  	}
  1149  	isVec := false
  1150  	for i := range fn.Args {
  1151  		foldExpr, errFold := ConstantFold(bat, fn.Args[i], proc, varAndParamIsConst)
  1152  		if errFold != nil {
  1153  			return nil, errFold
  1154  		}
  1155  		fn.Args[i] = foldExpr
  1156  		isVec = isVec || foldExpr.GetVec() != nil
  1157  	}
  1158  	if !rule.IsConstant(expr, varAndParamIsConst) {
  1159  		return expr, nil
  1160  	}
  1161  
  1162  	vec, err := colexec.EvalExpressionOnce(proc, expr, []*batch.Batch{bat})
  1163  	if err != nil {
  1164  		return nil, err
  1165  	}
  1166  	defer vec.Free(proc.Mp())
  1167  
  1168  	if isVec {
  1169  		data, err := vec.MarshalBinary()
  1170  		if err != nil {
  1171  			return expr, nil
  1172  		}
  1173  
  1174  		return &plan.Expr{
  1175  			Typ: expr.Typ,
  1176  			Expr: &plan.Expr_Vec{
  1177  				Vec: &plan.LiteralVec{
  1178  					Len:  int32(vec.Length()),
  1179  					Data: data,
  1180  				},
  1181  			},
  1182  		}, nil
  1183  	}
  1184  
  1185  	c := rule.GetConstantValue(vec, false, 0)
  1186  	if c == nil {
  1187  		return expr, nil
  1188  	}
  1189  	ec := &plan.Expr_Lit{
  1190  		Lit: c,
  1191  	}
  1192  	expr.Expr = ec
  1193  	return expr, nil
  1194  }
  1195  
  1196  func unwindTupleComparison(ctx context.Context, nonEqOp, op string, leftExprs, rightExprs []*plan.Expr, idx int) (*plan.Expr, error) {
  1197  	if idx == len(leftExprs)-1 {
  1198  		return BindFuncExprImplByPlanExpr(ctx, op, []*plan.Expr{
  1199  			leftExprs[idx],
  1200  			rightExprs[idx],
  1201  		})
  1202  	}
  1203  
  1204  	expr, err := BindFuncExprImplByPlanExpr(ctx, nonEqOp, []*plan.Expr{
  1205  		DeepCopyExpr(leftExprs[idx]),
  1206  		DeepCopyExpr(rightExprs[idx]),
  1207  	})
  1208  	if err != nil {
  1209  		return nil, err
  1210  	}
  1211  
  1212  	eqExpr, err := BindFuncExprImplByPlanExpr(ctx, "=", []*plan.Expr{
  1213  		leftExprs[idx],
  1214  		rightExprs[idx],
  1215  	})
  1216  	if err != nil {
  1217  		return nil, err
  1218  	}
  1219  
  1220  	tailExpr, err := unwindTupleComparison(ctx, nonEqOp, op, leftExprs, rightExprs, idx+1)
  1221  	if err != nil {
  1222  		return nil, err
  1223  	}
  1224  
  1225  	tailExpr, err = BindFuncExprImplByPlanExpr(ctx, "and", []*plan.Expr{eqExpr, tailExpr})
  1226  	if err != nil {
  1227  		return nil, err
  1228  	}
  1229  
  1230  	return BindFuncExprImplByPlanExpr(ctx, "or", []*plan.Expr{expr, tailExpr})
  1231  }
  1232  
  1233  // checkNoNeedCast
  1234  // if constant's type higher than column's type
  1235  // and constant's value in range of column's type, then no cast was needed
  1236  func checkNoNeedCast(constT, columnT types.Type, constExpr *plan.Literal) bool {
  1237  	if constExpr == nil {
  1238  		return false
  1239  	}
  1240  
  1241  	//TODO: Check if T_array is required here?
  1242  	if constT.Eq(columnT) {
  1243  		return true
  1244  	}
  1245  	switch constT.Oid {
  1246  	case types.T_char, types.T_varchar, types.T_text:
  1247  		switch columnT.Oid {
  1248  		case types.T_char, types.T_varchar:
  1249  			return constT.Width <= columnT.Width
  1250  		case types.T_text:
  1251  			return true
  1252  		default:
  1253  			return false
  1254  		}
  1255  
  1256  	case types.T_binary, types.T_varbinary, types.T_blob:
  1257  		switch columnT.Oid {
  1258  		case types.T_binary, types.T_varbinary:
  1259  			if constT.Width <= columnT.Width {
  1260  				return true
  1261  			} else {
  1262  				return false
  1263  			}
  1264  		case types.T_blob:
  1265  			return true
  1266  		default:
  1267  			return false
  1268  		}
  1269  
  1270  	case types.T_int8, types.T_int16, types.T_int32, types.T_int64:
  1271  		val, valOk := constExpr.Value.(*plan.Literal_I64Val)
  1272  		if !valOk {
  1273  			return false
  1274  		}
  1275  		constVal := val.I64Val
  1276  		switch columnT.Oid {
  1277  		case types.T_bit:
  1278  			return constVal >= 0 && uint64(constVal) <= uint64(1<<columnT.Width-1)
  1279  		case types.T_int8:
  1280  			return constVal <= int64(math.MaxInt8) && constVal >= int64(math.MinInt8)
  1281  		case types.T_int16:
  1282  			return constVal <= int64(math.MaxInt16) && constVal >= int64(math.MinInt16)
  1283  		case types.T_int32:
  1284  			return constVal <= int64(math.MaxInt32) && constVal >= int64(math.MinInt32)
  1285  		case types.T_int64:
  1286  			return true
  1287  		case types.T_uint8:
  1288  			return constVal <= math.MaxUint8 && constVal >= 0
  1289  		case types.T_uint16:
  1290  			return constVal <= math.MaxUint16 && constVal >= 0
  1291  		case types.T_uint32:
  1292  			return constVal <= math.MaxUint32 && constVal >= 0
  1293  		case types.T_uint64:
  1294  			return constVal >= 0
  1295  		case types.T_float32:
  1296  			//float32 has 6 significant digits.
  1297  			return constVal <= 100000 && constVal >= -100000
  1298  		case types.T_float64:
  1299  			//float64 has 15 significant digits.
  1300  			return constVal <= int64(math.MaxInt32) && constVal >= int64(math.MinInt32)
  1301  		case types.T_decimal64:
  1302  			return constVal <= int64(math.MaxInt32) && constVal >= int64(math.MinInt32)
  1303  		default:
  1304  			return false
  1305  		}
  1306  
  1307  	case types.T_uint8, types.T_uint16, types.T_uint32, types.T_uint64:
  1308  		val_u, valOk := constExpr.Value.(*plan.Literal_U64Val)
  1309  		if !valOk {
  1310  			return false
  1311  		}
  1312  		constVal := val_u.U64Val
  1313  		switch columnT.Oid {
  1314  		case types.T_bit:
  1315  			return constVal <= uint64(1<<columnT.Width-1)
  1316  		case types.T_int8:
  1317  			return constVal <= math.MaxInt8
  1318  		case types.T_int16:
  1319  			return constVal <= math.MaxInt16
  1320  		case types.T_int32:
  1321  			return constVal <= math.MaxInt32
  1322  		case types.T_int64:
  1323  			return constVal <= math.MaxInt64
  1324  		case types.T_uint8:
  1325  			return constVal <= math.MaxUint8
  1326  		case types.T_uint16:
  1327  			return constVal <= math.MaxUint16
  1328  		case types.T_uint32:
  1329  			return constVal <= math.MaxUint32
  1330  		case types.T_uint64:
  1331  			return true
  1332  		case types.T_float32:
  1333  			//float32 has 6 significant digits.
  1334  			return constVal <= 100000
  1335  		case types.T_float64:
  1336  			//float64 has 15 significant digits.
  1337  			return constVal <= math.MaxUint32
  1338  		case types.T_decimal64:
  1339  			return constVal <= math.MaxInt32
  1340  		default:
  1341  			return false
  1342  		}
  1343  
  1344  	case types.T_decimal64, types.T_decimal128:
  1345  		return columnT.Oid == types.T_decimal64 || columnT.Oid == types.T_decimal128
  1346  
  1347  	default:
  1348  		return false
  1349  	}
  1350  
  1351  }
  1352  
  1353  func InitInfileParam(param *tree.ExternParam) error {
  1354  	for i := 0; i < len(param.Option); i += 2 {
  1355  		switch strings.ToLower(param.Option[i]) {
  1356  		case "filepath":
  1357  			param.Filepath = param.Option[i+1]
  1358  		case "compression":
  1359  			param.CompressType = param.Option[i+1]
  1360  		case "format":
  1361  			format := strings.ToLower(param.Option[i+1])
  1362  			if format != tree.CSV && format != tree.JSONLINE && format != tree.PARQUET {
  1363  				return moerr.NewBadConfig(param.Ctx, "the format '%s' is not supported", format)
  1364  			}
  1365  			param.Format = format
  1366  		case "jsondata":
  1367  			jsondata := strings.ToLower(param.Option[i+1])
  1368  			if jsondata != tree.OBJECT && jsondata != tree.ARRAY {
  1369  				return moerr.NewBadConfig(param.Ctx, "the jsondata '%s' is not supported", jsondata)
  1370  			}
  1371  			param.JsonData = jsondata
  1372  			param.Format = tree.JSONLINE
  1373  		default:
  1374  			return moerr.NewBadConfig(param.Ctx, "the keyword '%s' is not support", strings.ToLower(param.Option[i]))
  1375  		}
  1376  	}
  1377  	if len(param.Filepath) == 0 {
  1378  		return moerr.NewBadConfig(param.Ctx, "the filepath must be specified")
  1379  	}
  1380  	if param.Format == tree.JSONLINE && len(param.JsonData) == 0 {
  1381  		return moerr.NewBadConfig(param.Ctx, "the jsondata must be specified")
  1382  	}
  1383  	if len(param.Format) == 0 {
  1384  		param.Format = tree.CSV
  1385  	}
  1386  	return nil
  1387  }
  1388  
  1389  func InitS3Param(param *tree.ExternParam) error {
  1390  	param.S3Param = &tree.S3Parameter{}
  1391  	for i := 0; i < len(param.Option); i += 2 {
  1392  		switch strings.ToLower(param.Option[i]) {
  1393  		case "endpoint":
  1394  			param.S3Param.Endpoint = param.Option[i+1]
  1395  		case "region":
  1396  			param.S3Param.Region = param.Option[i+1]
  1397  		case "access_key_id":
  1398  			param.S3Param.APIKey = param.Option[i+1]
  1399  		case "secret_access_key":
  1400  			param.S3Param.APISecret = param.Option[i+1]
  1401  		case "bucket":
  1402  			param.S3Param.Bucket = param.Option[i+1]
  1403  		case "filepath":
  1404  			param.Filepath = param.Option[i+1]
  1405  		case "compression":
  1406  			param.CompressType = param.Option[i+1]
  1407  		case "provider":
  1408  			param.S3Param.Provider = param.Option[i+1]
  1409  		case "role_arn":
  1410  			param.S3Param.RoleArn = param.Option[i+1]
  1411  		case "external_id":
  1412  			param.S3Param.ExternalId = param.Option[i+1]
  1413  		case "format":
  1414  			format := strings.ToLower(param.Option[i+1])
  1415  			if format != tree.CSV && format != tree.JSONLINE {
  1416  				return moerr.NewBadConfig(param.Ctx, "the format '%s' is not supported", format)
  1417  			}
  1418  			param.Format = format
  1419  		case "jsondata":
  1420  			jsondata := strings.ToLower(param.Option[i+1])
  1421  			if jsondata != tree.OBJECT && jsondata != tree.ARRAY {
  1422  				return moerr.NewBadConfig(param.Ctx, "the jsondata '%s' is not supported", jsondata)
  1423  			}
  1424  			param.JsonData = jsondata
  1425  			param.Format = tree.JSONLINE
  1426  
  1427  		default:
  1428  			return moerr.NewBadConfig(param.Ctx, "the keyword '%s' is not support", strings.ToLower(param.Option[i]))
  1429  		}
  1430  	}
  1431  	if param.Format == tree.JSONLINE && len(param.JsonData) == 0 {
  1432  		return moerr.NewBadConfig(param.Ctx, "the jsondata must be specified")
  1433  	}
  1434  	if len(param.Format) == 0 {
  1435  		param.Format = tree.CSV
  1436  	}
  1437  	return nil
  1438  }
  1439  
  1440  func GetForETLWithType(param *tree.ExternParam, prefix string) (res fileservice.ETLFileService, readPath string, err error) {
  1441  	if param.ScanType == tree.S3 {
  1442  		buf := new(strings.Builder)
  1443  		w := csv.NewWriter(buf)
  1444  		opts := []string{"s3-opts", "endpoint=" + param.S3Param.Endpoint, "region=" + param.S3Param.Region, "key=" + param.S3Param.APIKey, "secret=" + param.S3Param.APISecret,
  1445  			"bucket=" + param.S3Param.Bucket, "role-arn=" + param.S3Param.RoleArn, "external-id=" + param.S3Param.ExternalId}
  1446  		if strings.ToLower(param.S3Param.Provider) != "" && strings.ToLower(param.S3Param.Provider) != "minio" {
  1447  			return nil, "", moerr.NewBadConfig(param.Ctx, "the provider only support 'minio' now")
  1448  		}
  1449  		if strings.ToLower(param.S3Param.Provider) == "minio" {
  1450  			opts = append(opts, "is-minio=true")
  1451  		}
  1452  		if err = w.Write(opts); err != nil {
  1453  			return nil, "", err
  1454  		}
  1455  		w.Flush()
  1456  		return fileservice.GetForETL(context.TODO(), nil, fileservice.JoinPath(buf.String(), prefix))
  1457  	}
  1458  	return fileservice.GetForETL(context.TODO(), param.FileService, prefix)
  1459  }
  1460  
  1461  func StatFile(param *tree.ExternParam) error {
  1462  	filePath := strings.TrimSpace(param.Filepath)
  1463  	if strings.HasPrefix(filePath, "etl:") {
  1464  		filePath = path.Clean(filePath)
  1465  	} else {
  1466  		filePath = path.Clean("/" + filePath)
  1467  	}
  1468  	param.Filepath = filePath
  1469  	fs, readPath, err := GetForETLWithType(param, filePath)
  1470  	if err != nil {
  1471  		return err
  1472  	}
  1473  	st, err := fs.StatFile(param.Ctx, readPath)
  1474  	if err != nil {
  1475  		return err
  1476  	}
  1477  	param.Ctx = nil
  1478  	param.FileSize = st.Size
  1479  	return nil
  1480  }
  1481  
  1482  // ReadDir support "etl:" and "/..." absolute path, NOT support relative path.
  1483  func ReadDir(param *tree.ExternParam) (fileList []string, fileSize []int64, err error) {
  1484  	filePath := strings.TrimSpace(param.Filepath)
  1485  	if strings.HasPrefix(filePath, "etl:") {
  1486  		filePath = path.Clean(filePath)
  1487  	} else {
  1488  		filePath = path.Clean("/" + filePath)
  1489  	}
  1490  
  1491  	sep := "/"
  1492  	pathDir := strings.Split(filePath, sep)
  1493  	l := list.New()
  1494  	l2 := list.New()
  1495  	if pathDir[0] == "" {
  1496  		l.PushBack(sep)
  1497  	} else {
  1498  		l.PushBack(pathDir[0])
  1499  	}
  1500  
  1501  	for i := 1; i < len(pathDir); i++ {
  1502  		length := l.Len()
  1503  		for j := 0; j < length; j++ {
  1504  			prefix := l.Front().Value.(string)
  1505  			fs, readPath, err := GetForETLWithType(param, prefix)
  1506  			if err != nil {
  1507  				return nil, nil, err
  1508  			}
  1509  			entries, err := fs.List(param.Ctx, readPath)
  1510  			if err != nil {
  1511  				return nil, nil, err
  1512  			}
  1513  			for _, entry := range entries {
  1514  				if !entry.IsDir && i+1 != len(pathDir) {
  1515  					continue
  1516  				}
  1517  				if entry.IsDir && i+1 == len(pathDir) {
  1518  					continue
  1519  				}
  1520  				matched, err := path.Match(pathDir[i], entry.Name)
  1521  				if err != nil {
  1522  					return nil, nil, err
  1523  				}
  1524  				if !matched {
  1525  					continue
  1526  				}
  1527  				l.PushBack(path.Join(l.Front().Value.(string), entry.Name))
  1528  				if !entry.IsDir {
  1529  					l2.PushBack(entry.Size)
  1530  				}
  1531  			}
  1532  			l.Remove(l.Front())
  1533  		}
  1534  	}
  1535  	length := l.Len()
  1536  	for j := 0; j < length; j++ {
  1537  		fileList = append(fileList, l.Front().Value.(string))
  1538  		l.Remove(l.Front())
  1539  		fileSize = append(fileSize, l2.Front().Value.(int64))
  1540  		l2.Remove(l2.Front())
  1541  	}
  1542  	return fileList, fileSize, err
  1543  }
  1544  
  1545  // GetUniqueColAndIdxFromTableDef
  1546  // if get table:  t1(a int primary key, b int, c int, d int, unique key(b,c));
  1547  // return : []map[string]int { {'a'=1},  {'b'=2,'c'=3} }
  1548  func GetUniqueColAndIdxFromTableDef(tableDef *TableDef) []map[string]int {
  1549  	uniqueCols := make([]map[string]int, 0, len(tableDef.Cols))
  1550  	if tableDef.Pkey != nil && !onlyHasHiddenPrimaryKey(tableDef) {
  1551  		pkMap := make(map[string]int)
  1552  		for _, colName := range tableDef.Pkey.Names {
  1553  			pkMap[colName] = int(tableDef.Name2ColIndex[colName])
  1554  		}
  1555  		uniqueCols = append(uniqueCols, pkMap)
  1556  	}
  1557  
  1558  	for _, index := range tableDef.Indexes {
  1559  		if index.Unique {
  1560  			pkMap := make(map[string]int)
  1561  			for _, part := range index.Parts {
  1562  				pkMap[part] = int(tableDef.Name2ColIndex[part])
  1563  			}
  1564  			uniqueCols = append(uniqueCols, pkMap)
  1565  		}
  1566  	}
  1567  	return uniqueCols
  1568  }
  1569  
  1570  // GenUniqueColJoinExpr
  1571  // if get table:  t1(a int primary key, b int, c int, d int, unique key(b,c));
  1572  // uniqueCols is: []map[string]int { {'a'=1},  {'b'=2,'c'=3} }
  1573  // we will get expr like: 'leftTag.a = rightTag.a or (leftTag.b = rightTag.b and leftTag.c = rightTag. c)
  1574  func GenUniqueColJoinExpr(ctx context.Context, tableDef *TableDef, uniqueCols []map[string]int, leftTag int32, rightTag int32) (*Expr, error) {
  1575  	var checkExpr *Expr
  1576  	var err error
  1577  
  1578  	for i, uniqueColMap := range uniqueCols {
  1579  		var condExpr *Expr
  1580  		condIdx := int(0)
  1581  		for _, colIdx := range uniqueColMap {
  1582  			col := tableDef.Cols[colIdx]
  1583  			leftExpr := &Expr{
  1584  				Typ: col.Typ,
  1585  				Expr: &plan.Expr_Col{
  1586  					Col: &plan.ColRef{
  1587  						RelPos: leftTag,
  1588  						ColPos: int32(colIdx),
  1589  					},
  1590  				},
  1591  			}
  1592  			rightExpr := &plan.Expr{
  1593  				Typ: col.Typ,
  1594  				Expr: &plan.Expr_Col{
  1595  					Col: &plan.ColRef{
  1596  						RelPos: rightTag,
  1597  						ColPos: int32(colIdx),
  1598  					},
  1599  				},
  1600  			}
  1601  			eqExpr, err := BindFuncExprImplByPlanExpr(ctx, "=", []*Expr{leftExpr, rightExpr})
  1602  			if err != nil {
  1603  				return nil, err
  1604  			}
  1605  			if condIdx == 0 {
  1606  				condExpr = eqExpr
  1607  			} else {
  1608  				condExpr, err = BindFuncExprImplByPlanExpr(ctx, "and", []*Expr{condExpr, eqExpr})
  1609  				if err != nil {
  1610  					return nil, err
  1611  				}
  1612  			}
  1613  			condIdx++
  1614  		}
  1615  
  1616  		if i == 0 {
  1617  			checkExpr = condExpr
  1618  		} else {
  1619  			checkExpr, err = BindFuncExprImplByPlanExpr(ctx, "or", []*Expr{checkExpr, condExpr})
  1620  			if err != nil {
  1621  				return nil, err
  1622  			}
  1623  		}
  1624  	}
  1625  
  1626  	return checkExpr, nil
  1627  }
  1628  
  1629  // GenUniqueColCheckExpr   like GenUniqueColJoinExpr. but use for on duplicate key clause to check conflict
  1630  // if get table:  t1(a int primary key, b int, c int, d int, unique key(b,c));
  1631  // we get batch like [1,2,3,4, origin_a, origin_b, origin_c, origin_d, row_id ....]。
  1632  // we get expr like:  []*Expr{ 1=origin_a ,  (2 = origin_b and 3 = origin_c) }
  1633  func GenUniqueColCheckExpr(ctx context.Context, tableDef *TableDef, uniqueCols []map[string]int, colCount int) ([]*Expr, error) {
  1634  	checkExpr := make([]*Expr, len(uniqueCols))
  1635  
  1636  	for i, uniqueColMap := range uniqueCols {
  1637  		var condExpr *Expr
  1638  		condIdx := int(0)
  1639  		for _, colIdx := range uniqueColMap {
  1640  			col := tableDef.Cols[colIdx]
  1641  			// insert values
  1642  			leftExpr := &Expr{
  1643  				Typ: col.Typ,
  1644  				Expr: &plan.Expr_Col{
  1645  					Col: &plan.ColRef{
  1646  						RelPos: 0,
  1647  						ColPos: int32(colIdx),
  1648  					},
  1649  				},
  1650  			}
  1651  			rightExpr := &plan.Expr{
  1652  				Typ: col.Typ,
  1653  				Expr: &plan.Expr_Col{
  1654  					Col: &plan.ColRef{
  1655  						RelPos: 1,
  1656  						ColPos: int32(colIdx + colCount),
  1657  					},
  1658  				},
  1659  			}
  1660  			eqExpr, err := BindFuncExprImplByPlanExpr(ctx, "=", []*Expr{leftExpr, rightExpr})
  1661  			if err != nil {
  1662  				return nil, err
  1663  			}
  1664  			if condIdx == 0 {
  1665  				condExpr = eqExpr
  1666  			} else {
  1667  				condExpr, err = BindFuncExprImplByPlanExpr(ctx, "and", []*Expr{condExpr, eqExpr})
  1668  				if err != nil {
  1669  					return nil, err
  1670  				}
  1671  			}
  1672  			condIdx++
  1673  		}
  1674  		checkExpr[i] = condExpr
  1675  	}
  1676  
  1677  	return checkExpr, nil
  1678  }
  1679  func onlyContainsTag(filter *Expr, tag int32) bool {
  1680  	switch ex := filter.Expr.(type) {
  1681  	case *plan.Expr_Col:
  1682  		return ex.Col.RelPos == tag
  1683  	case *plan.Expr_F:
  1684  		for _, arg := range ex.F.Args {
  1685  			if !onlyContainsTag(arg, tag) {
  1686  				return false
  1687  			}
  1688  		}
  1689  		return true
  1690  	default:
  1691  		return true
  1692  	}
  1693  }
  1694  
  1695  func AssignAuxIdForExpr(expr *plan.Expr, start int32) int32 {
  1696  	expr.AuxId = start
  1697  	vertexCnt := int32(1)
  1698  
  1699  	if f, ok := expr.Expr.(*plan.Expr_F); ok {
  1700  		for _, child := range f.F.Args {
  1701  			vertexCnt += AssignAuxIdForExpr(child, start+vertexCnt)
  1702  		}
  1703  	}
  1704  
  1705  	return vertexCnt
  1706  }
  1707  
  1708  func ResetAuxIdForExpr(expr *plan.Expr) {
  1709  	expr.AuxId = 0
  1710  
  1711  	if f, ok := expr.Expr.(*plan.Expr_F); ok {
  1712  		for _, child := range f.F.Args {
  1713  			ResetAuxIdForExpr(child)
  1714  		}
  1715  	}
  1716  }
  1717  
  1718  // func SubstitueParam(expr *plan.Expr, proc *process.Process) *plan.Expr {
  1719  // 	switch t := expr.Expr.(type) {
  1720  // 	case *plan.Expr_F:
  1721  // 		for _, arg := range t.F.Args {
  1722  // 			SubstitueParam(arg, proc)
  1723  // 		}
  1724  // 	case *plan.Expr_P:
  1725  // 		vec, _ := proc.GetPrepareParamsAt(int(t.P.Pos))
  1726  // 		c := rule.GetConstantValue(vec, false)
  1727  // 		ec := &plan.Expr_C{
  1728  // 			C: c,
  1729  // 		}
  1730  // 		expr.Typ = &plan.Type{Id: int32(vec.GetType().Oid), Scale: vec.GetType().Scale, Width: vec.GetType().Width}
  1731  // 		expr.Expr = ec
  1732  // 	case *plan.Expr_V:
  1733  // 		val, _ := proc.GetResolveVariableFunc()(t.V.Name, t.V.System, t.V.Global)
  1734  // 		typ := types.New(types.T(expr.Typ.Id), expr.Typ.Width, expr.Typ.Scale)
  1735  // 		vec, _ := util.GenVectorByVarValue(proc, typ, val)
  1736  // 		c := rule.GetConstantValue(vec, false)
  1737  // 		ec := &plan.Expr_C{
  1738  // 			C: c,
  1739  // 		}
  1740  // 		expr.Typ = &plan.Type{Id: int32(vec.GetType().Oid), Scale: vec.GetType().Scale, Width: vec.GetType().Width}
  1741  // 		expr.Expr = ec
  1742  // 	}
  1743  // 	return expr
  1744  // }
  1745  
  1746  func FormatExprs(exprs []*plan.Expr) string {
  1747  	var w bytes.Buffer
  1748  	for _, expr := range exprs {
  1749  		w.WriteString(FormatExpr(expr))
  1750  		w.WriteByte('\n')
  1751  	}
  1752  	return w.String()
  1753  }
  1754  
  1755  func FormatExpr(expr *plan.Expr) string {
  1756  	var w bytes.Buffer
  1757  	doFormatExpr(expr, &w, 0)
  1758  	return w.String()
  1759  }
  1760  
  1761  func doFormatExpr(expr *plan.Expr, out *bytes.Buffer, depth int) {
  1762  	out.WriteByte('\n')
  1763  	prefix := strings.Repeat("\t", depth)
  1764  	switch t := expr.Expr.(type) {
  1765  	case *plan.Expr_Col:
  1766  		out.WriteString(fmt.Sprintf("%sExpr_Col(%s)", prefix, t.Col.Name))
  1767  	case *plan.Expr_Lit:
  1768  		out.WriteString(fmt.Sprintf("%sExpr_C(%s)", prefix, t.Lit.String()))
  1769  	case *plan.Expr_F:
  1770  		out.WriteString(fmt.Sprintf("%sExpr_F(\n%s\tFunc[\"%s\"](nargs=%d)", prefix, prefix, t.F.Func.ObjName, len(t.F.Args)))
  1771  		for _, arg := range t.F.Args {
  1772  			doFormatExpr(arg, out, depth+1)
  1773  		}
  1774  		out.WriteString(fmt.Sprintf("\n%s)", prefix))
  1775  	case *plan.Expr_P:
  1776  		out.WriteString(fmt.Sprintf("%sExpr_P(%d)", prefix, t.P.Pos))
  1777  	case *plan.Expr_T:
  1778  		out.WriteString(fmt.Sprintf("%sExpr_T(%s)", prefix, t.T.String()))
  1779  	default:
  1780  		out.WriteString(fmt.Sprintf("%sExpr_Unknown(%s)", prefix, expr.String()))
  1781  	}
  1782  }
  1783  
  1784  // databaseIsValid checks whether the database exists or not.
  1785  func databaseIsValid(dbName string, ctx CompilerContext, snapshot Snapshot) (string, error) {
  1786  	connectDBFirst := false
  1787  	if len(dbName) == 0 {
  1788  		connectDBFirst = true
  1789  	}
  1790  	if dbName == "" {
  1791  		dbName = ctx.DefaultDatabase()
  1792  	}
  1793  
  1794  	if len(dbName) == 0 || !ctx.DatabaseExists(dbName, snapshot) {
  1795  		if connectDBFirst {
  1796  			return "", moerr.NewNoDB(ctx.GetContext())
  1797  		} else {
  1798  			return "", moerr.NewBadDB(ctx.GetContext(), dbName)
  1799  		}
  1800  	}
  1801  	return dbName, nil
  1802  }
  1803  
  1804  /*
  1805  *
  1806  getSuitableDBName get the database name which need to be used in next steps.
  1807  
  1808  For Cases:
  1809  
  1810  	SHOW XXX FROM [DB_NAME1].TABLE_NAME [FROM [DB_NAME2]];
  1811  
  1812  	In mysql,
  1813  		if the second FROM clause exists, the DB_NAME1 in first FROM clause if it exists will be ignored.
  1814  		if the second FROM clause does not exist, the DB_NAME1 in first FROM clause if it exists  will be used.
  1815  		if the DB_NAME1 and DB_NAME2 neither does not exist, the current connected database (by USE statement) will be used.
  1816  		if neither case above succeeds, an error is reported.
  1817  */
  1818  func getSuitableDBName(dbName1 string, dbName2 string) string {
  1819  	if len(dbName2) != 0 {
  1820  		return dbName2
  1821  	}
  1822  	return dbName1
  1823  }
  1824  
  1825  func detectedExprWhetherTimeRelated(expr *plan.Expr) bool {
  1826  	if ef, ok := expr.Expr.(*plan.Expr_F); !ok {
  1827  		return false
  1828  	} else {
  1829  		overloadID := ef.F.Func.GetObj()
  1830  		f, exists := function.GetFunctionByIdWithoutError(overloadID)
  1831  		// current_timestamp()
  1832  		if !exists {
  1833  			return false
  1834  		}
  1835  		if f.IsRealTimeRelated() {
  1836  			return true
  1837  		}
  1838  
  1839  		// current_timestamp() + 1
  1840  		for _, arg := range ef.F.Args {
  1841  			if detectedExprWhetherTimeRelated(arg) {
  1842  				return true
  1843  			}
  1844  		}
  1845  	}
  1846  	return false
  1847  }
  1848  
  1849  func ResetPreparePlan(ctx CompilerContext, preparePlan *Plan) ([]*plan.ObjectRef, []int32, error) {
  1850  	// dcl tcl is not support
  1851  	var schemas []*plan.ObjectRef
  1852  	var paramTypes []int32
  1853  
  1854  	switch pp := preparePlan.Plan.(type) {
  1855  	case *plan.Plan_Tcl:
  1856  		return nil, nil, moerr.NewInvalidInput(ctx.GetContext(), "cannot prepare TCL and DCL statement")
  1857  	case *plan.Plan_Dcl:
  1858  		switch pp.Dcl.GetDclType() {
  1859  		case plan.DataControl_CREATE_ACCOUNT,
  1860  			plan.DataControl_ALTER_ACCOUNT,
  1861  			plan.DataControl_DROP_ACCOUNT:
  1862  			return nil, pp.Dcl.GetOther().GetParamTypes(), nil
  1863  		default:
  1864  			return nil, nil, moerr.NewInvalidInput(ctx.GetContext(), "cannot prepare TCL and DCL statement")
  1865  		}
  1866  	case *plan.Plan_Ddl:
  1867  		if pp.Ddl.Query != nil {
  1868  			getParamRule := NewGetParamRule()
  1869  			VisitQuery := NewVisitPlan(preparePlan, []VisitPlanRule{getParamRule})
  1870  			err := VisitQuery.Visit(ctx.GetContext())
  1871  			if err != nil {
  1872  				return nil, nil, err
  1873  			}
  1874  			// TODO : need confirm
  1875  			if len(getParamRule.params) > 0 {
  1876  				return nil, nil, moerr.NewInvalidInput(ctx.GetContext(), "cannot plan DDL statement")
  1877  			}
  1878  		}
  1879  
  1880  	case *plan.Plan_Query:
  1881  		// collect args
  1882  		getParamRule := NewGetParamRule()
  1883  		VisitQuery := NewVisitPlan(preparePlan, []VisitPlanRule{getParamRule})
  1884  		err := VisitQuery.Visit(ctx.GetContext())
  1885  		if err != nil {
  1886  			return nil, nil, err
  1887  		}
  1888  
  1889  		// sort arg
  1890  		getParamRule.SetParamOrder()
  1891  		args := getParamRule.params
  1892  		schemas = getParamRule.schemas
  1893  		paramTypes = getParamRule.paramTypes
  1894  
  1895  		// reset arg order
  1896  		resetParamRule := NewResetParamOrderRule(args)
  1897  		VisitQuery = NewVisitPlan(preparePlan, []VisitPlanRule{resetParamRule})
  1898  		err = VisitQuery.Visit(ctx.GetContext())
  1899  		if err != nil {
  1900  			return nil, nil, err
  1901  		}
  1902  	}
  1903  	return schemas, paramTypes, nil
  1904  }
  1905  
  1906  func getParamTypes(params []tree.Expr, ctx CompilerContext, isPrepareStmt bool) ([]int32, error) {
  1907  	paramTypes := make([]int32, 0, len(params))
  1908  	for _, p := range params {
  1909  		switch ast := p.(type) {
  1910  		case *tree.NumVal:
  1911  			if ast.ValType != tree.P_char {
  1912  				return nil, moerr.NewInvalidInput(ctx.GetContext(), "unsupport value '%s'", ast.String())
  1913  			}
  1914  		case *tree.ParamExpr:
  1915  			if !isPrepareStmt {
  1916  				return nil, moerr.NewInvalidInput(ctx.GetContext(), "only prepare statement can use ? expr")
  1917  			}
  1918  			paramTypes = append(paramTypes, int32(types.T_varchar))
  1919  			if ast.Offset != len(paramTypes) {
  1920  				return nil, moerr.NewInternalError(ctx.GetContext(), "offset not match")
  1921  			}
  1922  		default:
  1923  			return nil, moerr.NewInvalidInput(ctx.GetContext(), "unsupport value '%s'", ast.String())
  1924  		}
  1925  	}
  1926  	return paramTypes, nil
  1927  }
  1928  
  1929  // HasMoCtrl checks whether the expression has mo_ctrl(..,..,..)
  1930  func HasMoCtrl(expr *plan.Expr) bool {
  1931  	switch exprImpl := expr.Expr.(type) {
  1932  	case *plan.Expr_F:
  1933  		if exprImpl.F.Func.ObjName == "mo_ctl" {
  1934  			return true
  1935  		}
  1936  		for _, arg := range exprImpl.F.Args {
  1937  			if HasMoCtrl(arg) {
  1938  				return true
  1939  			}
  1940  		}
  1941  		return false
  1942  
  1943  	case *plan.Expr_List:
  1944  		for _, arg := range exprImpl.List.List {
  1945  			if HasMoCtrl(arg) {
  1946  				return true
  1947  			}
  1948  		}
  1949  		return false
  1950  
  1951  	default:
  1952  		return false
  1953  	}
  1954  }
  1955  
  1956  // IsFkSelfRefer checks the foreign key referencing itself
  1957  func IsFkSelfRefer(fkDbName, fkTableName, curDbName, curTableName string) bool {
  1958  	return fkDbName == curDbName && fkTableName == curTableName
  1959  }
  1960  
  1961  // HasFkSelfReferOnly checks the foreign key referencing itself only.
  1962  // If there is no children tables, it also returns true
  1963  // the tbleId 0 is special. it always denotes the table itself.
  1964  func HasFkSelfReferOnly(tableDef *TableDef) bool {
  1965  	for _, tbl := range tableDef.RefChildTbls {
  1966  		if tbl != 0 {
  1967  			return false
  1968  		}
  1969  	}
  1970  	return true
  1971  }
  1972  
  1973  func IsFalseExpr(e *Expr) bool {
  1974  	if e == nil || e.GetTyp().Id != int32(types.T_bool) || e.GetLit() == nil {
  1975  		return false
  1976  	}
  1977  	if x, ok := e.GetLit().GetValue().(*plan.Literal_Bval); ok {
  1978  		return !x.Bval
  1979  	}
  1980  	return false
  1981  }
  1982  func MakeFalseExpr() *Expr {
  1983  	return &plan.Expr{
  1984  		Typ: plan.Type{
  1985  			Id: int32(types.T_bool),
  1986  		},
  1987  		Expr: &plan.Expr_Lit{
  1988  			Lit: &plan.Literal{
  1989  				Isnull: false,
  1990  				Value:  &plan.Literal_Bval{Bval: false},
  1991  			},
  1992  		},
  1993  	}
  1994  }
  1995  
  1996  func MakeRuntimeFilter(tag int32, matchPrefix bool, upperlimit int32, expr *Expr) *plan.RuntimeFilterSpec {
  1997  	return &plan.RuntimeFilterSpec{
  1998  		Tag:         tag,
  1999  		UpperLimit:  upperlimit,
  2000  		Expr:        expr,
  2001  		MatchPrefix: matchPrefix,
  2002  	}
  2003  }
  2004  
  2005  func MakeIntervalExpr(num int64, str string) *Expr {
  2006  	arg0 := makePlan2Int64ConstExprWithType(num)
  2007  	arg1 := makePlan2StringConstExprWithType(str, false)
  2008  	return &plan.Expr{
  2009  		Typ: plan.Type{
  2010  			Id: int32(types.T_interval),
  2011  		},
  2012  		Expr: &plan.Expr_List{
  2013  			List: &plan.ExprList{
  2014  				List: []*Expr{arg0, arg1},
  2015  			},
  2016  		},
  2017  	}
  2018  }
  2019  
  2020  func MakeInExpr(ctx context.Context, left *Expr, length int32, data []byte, matchPrefix bool) *Expr {
  2021  	rightType := plan.Type{Id: int32(types.T_tuple)}
  2022  	if matchPrefix {
  2023  		rightType = left.Typ
  2024  	}
  2025  	rightArg := &plan.Expr{
  2026  		Typ: rightType,
  2027  		Expr: &plan.Expr_Vec{
  2028  			Vec: &plan.LiteralVec{
  2029  				Len:  length,
  2030  				Data: data,
  2031  			},
  2032  		},
  2033  	}
  2034  
  2035  	funcID := function.InFunctionEncodedID
  2036  	funcName := function.InFunctionName
  2037  	if matchPrefix {
  2038  		funcID = function.PrefixInFunctionEncodedID
  2039  		funcName = function.PrefixInFunctionName
  2040  	}
  2041  	args := []types.Type{makeTypeByPlan2Expr(left), makeTypeByPlan2Expr(rightArg)}
  2042  	fGet, err := function.GetFunctionByName(ctx, funcName, args)
  2043  	if err == nil {
  2044  		funcID = fGet.GetEncodedOverloadID()
  2045  	}
  2046  	inExpr := &plan.Expr{
  2047  		Typ: plan.Type{
  2048  			Id:          int32(types.T_bool),
  2049  			NotNullable: left.Typ.NotNullable,
  2050  		},
  2051  		Expr: &plan.Expr_F{
  2052  			F: &plan.Function{
  2053  				Func: &plan.ObjectRef{
  2054  					Obj:     funcID,
  2055  					ObjName: funcName,
  2056  				},
  2057  				Args: []*plan.Expr{
  2058  					left,
  2059  					rightArg,
  2060  				},
  2061  			},
  2062  		},
  2063  	}
  2064  	return inExpr
  2065  }
  2066  
  2067  // FillValuesOfParamsInPlan replaces the params by their values
  2068  func FillValuesOfParamsInPlan(ctx context.Context, preparePlan *Plan, paramVals []any) (*Plan, error) {
  2069  	copied := preparePlan
  2070  
  2071  	switch pp := copied.Plan.(type) {
  2072  	case *plan.Plan_Tcl, *plan.Plan_Dcl:
  2073  		return nil, moerr.NewInvalidInput(ctx, "cannot prepare TCL and DCL statement")
  2074  
  2075  	case *plan.Plan_Ddl:
  2076  		if pp.Ddl.Query != nil {
  2077  			err := replaceParamVals(ctx, preparePlan, paramVals)
  2078  			if err != nil {
  2079  				return nil, err
  2080  			}
  2081  		}
  2082  
  2083  	case *plan.Plan_Query:
  2084  		err := replaceParamVals(ctx, preparePlan, paramVals)
  2085  		if err != nil {
  2086  			return nil, err
  2087  		}
  2088  	}
  2089  	return copied, nil
  2090  }
  2091  
  2092  func replaceParamVals(ctx context.Context, plan0 *Plan, paramVals []any) error {
  2093  	params := make([]*Expr, len(paramVals))
  2094  	for i, val := range paramVals {
  2095  		pc := &plan.Literal{}
  2096  		pc.Value = &plan.Literal_Sval{Sval: fmt.Sprintf("%v", val)}
  2097  		params[i] = &plan.Expr{
  2098  			Expr: &plan.Expr_Lit{
  2099  				Lit: pc,
  2100  			},
  2101  		}
  2102  	}
  2103  	paramRule := NewResetParamRefRule(ctx, params)
  2104  	VisitQuery := NewVisitPlan(plan0, []VisitPlanRule{paramRule})
  2105  	err := VisitQuery.Visit(ctx)
  2106  	if err != nil {
  2107  		return err
  2108  	}
  2109  	return nil
  2110  }
  2111  
  2112  // XXX: Any code relying on Name in ColRef, except for "explain", is bad design and practically buggy.
  2113  func (builder *QueryBuilder) addNameByColRef(tag int32, tableDef *plan.TableDef) {
  2114  	for i, col := range tableDef.Cols {
  2115  		builder.nameByColRef[[2]int32{tag, int32(i)}] = tableDef.Name + "." + col.Name
  2116  	}
  2117  }
  2118  
  2119  func GetRowSizeFromTableDef(tableDef *TableDef, ignoreHiddenKey bool) float64 {
  2120  	size := int32(0)
  2121  	for _, col := range tableDef.Cols {
  2122  		if col.Hidden && ignoreHiddenKey {
  2123  			continue
  2124  		}
  2125  		if col.Typ.Width > 0 {
  2126  			size += col.Typ.Width
  2127  			continue
  2128  		}
  2129  		typ := types.T(col.Typ.Id).ToType()
  2130  		if typ.Width > 0 {
  2131  			size += typ.Width
  2132  		} else {
  2133  			size += typ.Size
  2134  		}
  2135  	}
  2136  	return float64(size)
  2137  }