github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/plan/visit_plan_rule.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  	"context"
    19  	"sort"
    20  	"strconv"
    21  
    22  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    23  	"github.com/matrixorigin/matrixone/pkg/container/batch"
    24  	"github.com/matrixorigin/matrixone/pkg/container/types"
    25  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    26  	"github.com/matrixorigin/matrixone/pkg/sql/colexec"
    27  	"github.com/matrixorigin/matrixone/pkg/sql/plan/rule"
    28  	"github.com/matrixorigin/matrixone/pkg/vm/process"
    29  )
    30  
    31  var (
    32  	_ VisitPlanRule = &GetParamRule{}
    33  	_ VisitPlanRule = &ResetParamOrderRule{}
    34  	_ VisitPlanRule = &ResetParamRefRule{}
    35  	_ VisitPlanRule = &ResetVarRefRule{}
    36  	_ VisitPlanRule = &ConstantFoldRule{}
    37  )
    38  
    39  var (
    40  	constantFoldRule = rule.NewConstantFold(false)
    41  )
    42  
    43  type GetParamRule struct {
    44  	params     map[int]int
    45  	mapTypes   map[int]int32
    46  	paramTypes []int32
    47  	schemas    []*plan.ObjectRef
    48  }
    49  
    50  func NewGetParamRule() *GetParamRule {
    51  	return &GetParamRule{
    52  		params:   make(map[int]int),
    53  		mapTypes: make(map[int]int32),
    54  	}
    55  }
    56  
    57  func (rule *GetParamRule) MatchNode(node *Node) bool {
    58  	if node.NodeType == plan.Node_TABLE_SCAN {
    59  		rule.schemas = append(rule.schemas, &plan.ObjectRef{
    60  			Server:     int64(node.TableDef.Version), //we use this unused field to store table's version
    61  			Db:         node.ObjRef.Db,
    62  			Schema:     node.ObjRef.Schema,
    63  			Obj:        node.ObjRef.Obj,
    64  			ServerName: node.ObjRef.ServerName,
    65  			DbName:     node.ObjRef.DbName,
    66  			SchemaName: node.ObjRef.SchemaName,
    67  			ObjName:    node.ObjRef.ObjName,
    68  		})
    69  	}
    70  	return false
    71  }
    72  
    73  func (rule *GetParamRule) IsApplyExpr() bool {
    74  	return true
    75  }
    76  
    77  func (rule *GetParamRule) ApplyNode(node *Node) error {
    78  	return nil
    79  }
    80  
    81  func (rule *GetParamRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) {
    82  	switch exprImpl := e.Expr.(type) {
    83  	case *plan.Expr_F:
    84  		for i := range exprImpl.F.Args {
    85  			exprImpl.F.Args[i], _ = rule.ApplyExpr(exprImpl.F.Args[i])
    86  		}
    87  		return e, nil
    88  	case *plan.Expr_P:
    89  		pos := int(exprImpl.P.Pos)
    90  		rule.params[pos] = 0
    91  		/*
    92  			if e.Typ.Id == int32(types.T_any) && e.Typ.NotNullable {
    93  				// is not null, use string
    94  				rule.mapTypes[pos] = int32(types.T_varchar)
    95  			} else {
    96  				rule.mapTypes[pos] = e.Typ.Id
    97  			}
    98  		*/
    99  		return e, nil
   100  	default:
   101  		return e, nil
   102  	}
   103  }
   104  
   105  func (rule *GetParamRule) SetParamOrder() {
   106  	argPos := []int{}
   107  	for pos := range rule.params {
   108  		argPos = append(argPos, pos)
   109  	}
   110  	sort.Ints(argPos)
   111  	rule.paramTypes = make([]int32, len(argPos))
   112  
   113  	for idx, pos := range argPos {
   114  		rule.params[pos] = idx
   115  		rule.paramTypes[idx] = rule.mapTypes[pos]
   116  	}
   117  }
   118  
   119  // ---------------------------
   120  
   121  type ResetParamOrderRule struct {
   122  	params map[int]int
   123  }
   124  
   125  func NewResetParamOrderRule(params map[int]int) *ResetParamOrderRule {
   126  	return &ResetParamOrderRule{
   127  		params: params,
   128  	}
   129  }
   130  
   131  func (rule *ResetParamOrderRule) MatchNode(_ *Node) bool {
   132  	return false
   133  }
   134  
   135  func (rule *ResetParamOrderRule) IsApplyExpr() bool {
   136  	return true
   137  }
   138  
   139  func (rule *ResetParamOrderRule) ApplyNode(node *Node) error {
   140  	return nil
   141  }
   142  
   143  func (rule *ResetParamOrderRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) {
   144  	switch exprImpl := e.Expr.(type) {
   145  	case *plan.Expr_F:
   146  		for i := range exprImpl.F.Args {
   147  			exprImpl.F.Args[i], _ = rule.ApplyExpr(exprImpl.F.Args[i])
   148  		}
   149  		return e, nil
   150  	case *plan.Expr_P:
   151  		exprImpl.P.Pos = int32(rule.params[int(exprImpl.P.Pos)])
   152  		return e, nil
   153  	default:
   154  		return e, nil
   155  	}
   156  }
   157  
   158  // ---------------------------
   159  
   160  type ResetParamRefRule struct {
   161  	ctx    context.Context
   162  	params []*Expr
   163  }
   164  
   165  func NewResetParamRefRule(ctx context.Context, params []*Expr) *ResetParamRefRule {
   166  	return &ResetParamRefRule{
   167  		ctx:    ctx,
   168  		params: params,
   169  	}
   170  }
   171  
   172  func (rule *ResetParamRefRule) MatchNode(_ *Node) bool {
   173  	return false
   174  }
   175  
   176  func (rule *ResetParamRefRule) IsApplyExpr() bool {
   177  	return true
   178  }
   179  
   180  func (rule *ResetParamRefRule) ApplyNode(node *Node) error {
   181  	return nil
   182  }
   183  
   184  func (rule *ResetParamRefRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) {
   185  	var err error
   186  	switch exprImpl := e.Expr.(type) {
   187  	case *plan.Expr_F:
   188  		needResetFunction := false
   189  		for i, arg := range exprImpl.F.Args {
   190  			if _, ok := arg.Expr.(*plan.Expr_P); ok {
   191  				needResetFunction = true
   192  			}
   193  			exprImpl.F.Args[i], err = rule.ApplyExpr(arg)
   194  			if err != nil {
   195  				return nil, err
   196  			}
   197  		}
   198  
   199  		// reset function
   200  		if needResetFunction {
   201  			return BindFuncExprImplByPlanExpr(rule.ctx, exprImpl.F.Func.GetObjName(), exprImpl.F.Args)
   202  		}
   203  		return e, nil
   204  	case *plan.Expr_P:
   205  		return &plan.Expr{
   206  			Typ:  e.Typ,
   207  			Expr: rule.params[int(exprImpl.P.Pos)].Expr,
   208  		}, nil
   209  	default:
   210  		return e, nil
   211  	}
   212  }
   213  
   214  // ---------------------------
   215  
   216  type ResetVarRefRule struct {
   217  	compCtx CompilerContext
   218  	proc    *process.Process
   219  	bat     *batch.Batch
   220  }
   221  
   222  func NewResetVarRefRule(compCtx CompilerContext, proc *process.Process) *ResetVarRefRule {
   223  	bat := batch.NewWithSize(0)
   224  	bat.SetRowCount(1)
   225  	return &ResetVarRefRule{
   226  		compCtx: compCtx,
   227  		proc:    proc,
   228  		bat:     bat,
   229  	}
   230  }
   231  
   232  func (rule *ResetVarRefRule) MatchNode(_ *Node) bool {
   233  	return false
   234  }
   235  
   236  func (rule *ResetVarRefRule) IsApplyExpr() bool {
   237  	return true
   238  }
   239  
   240  func (rule *ResetVarRefRule) ApplyNode(node *Node) error {
   241  	return nil
   242  }
   243  
   244  func (rule *ResetVarRefRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) {
   245  	var err error
   246  	switch exprImpl := e.Expr.(type) {
   247  	case *plan.Expr_F:
   248  		needResetFunction := false
   249  		for i, arg := range exprImpl.F.Args {
   250  			if _, ok := arg.Expr.(*plan.Expr_V); ok {
   251  				needResetFunction = true
   252  			}
   253  			exprImpl.F.Args[i], err = rule.ApplyExpr(arg)
   254  			if err != nil {
   255  				return nil, err
   256  			}
   257  		}
   258  
   259  		// reset function
   260  		if needResetFunction {
   261  			return BindFuncExprImplByPlanExpr(rule.getContext(), exprImpl.F.Func.GetObjName(), exprImpl.F.Args)
   262  		}
   263  		return e, nil
   264  	case *plan.Expr_V:
   265  		return GetVarValue(rule.getContext(), rule.compCtx, rule.proc, rule.bat, e)
   266  	case *plan.Expr_Lit:
   267  		if exprImpl.Lit.Src != nil {
   268  			if _, ok := exprImpl.Lit.Src.Expr.(*plan.Expr_V); ok {
   269  				return GetVarValue(rule.getContext(), rule.compCtx, rule.proc, rule.bat, exprImpl.Lit.Src)
   270  			}
   271  		}
   272  		return e, nil
   273  	default:
   274  		return e, nil
   275  	}
   276  }
   277  
   278  func (rule *ResetVarRefRule) getContext() context.Context { return rule.compCtx.GetContext() }
   279  
   280  func GetVarValue(
   281  	ctx context.Context,
   282  	compCtx CompilerContext,
   283  	proc *process.Process,
   284  	emptyBat *batch.Batch,
   285  	e *Expr,
   286  ) (*plan.Expr, error) {
   287  	exprImpl := e.Expr.(*plan.Expr_V)
   288  	var expr *plan.Expr
   289  	getVal, err := compCtx.ResolveVariable(exprImpl.V.Name, exprImpl.V.System, exprImpl.V.Global)
   290  	if err != nil {
   291  		return nil, err
   292  	}
   293  
   294  	switch val := getVal.(type) {
   295  	case string:
   296  		expr = makePlan2StringConstExprWithType(val)
   297  	case int:
   298  		expr = makePlan2Int64ConstExprWithType(int64(val))
   299  	case uint8:
   300  		expr = makePlan2Int64ConstExprWithType(int64(val))
   301  	case uint16:
   302  		expr = makePlan2Int64ConstExprWithType(int64(val))
   303  	case uint32:
   304  		expr = makePlan2Int64ConstExprWithType(int64(val))
   305  	case int8:
   306  		expr = makePlan2Int64ConstExprWithType(int64(val))
   307  	case int16:
   308  		expr = makePlan2Int64ConstExprWithType(int64(val))
   309  	case int32:
   310  		expr = makePlan2Int64ConstExprWithType(int64(val))
   311  	case int64:
   312  		expr = makePlan2Int64ConstExprWithType(val)
   313  	case uint64:
   314  		expr = makePlan2Uint64ConstExprWithType(val)
   315  	case float32:
   316  		// when we build plan with constant in float, we cast them to decimal.
   317  		// so we cast @float_var to decimal too.
   318  		strVal := strconv.FormatFloat(float64(val), 'f', -1, 64)
   319  		expr, err = makePlan2DecimalExprWithType(ctx, strVal)
   320  	case float64:
   321  		// when we build plan with constant in float, we cast them to decimal.
   322  		// so we cast @float_var to decimal too.
   323  		strVal := strconv.FormatFloat(val, 'f', -1, 64)
   324  		expr, err = makePlan2DecimalExprWithType(ctx, strVal)
   325  	case bool:
   326  		expr = makePlan2BoolConstExprWithType(val)
   327  	case nil:
   328  		if e.Typ.Id == int32(types.T_any) {
   329  			expr = makePlan2NullConstExprWithType()
   330  		} else {
   331  			expr = &plan.Expr{
   332  				Expr: &plan.Expr_Lit{
   333  					Lit: &Const{
   334  						Isnull: true,
   335  					},
   336  				},
   337  				Typ: e.Typ,
   338  			}
   339  		}
   340  	case *Expr:
   341  		expr = DeepCopyExpr(val)
   342  	case types.Decimal64, types.Decimal128:
   343  		err = moerr.NewNYI(ctx, "decimal var")
   344  	default:
   345  		err = moerr.NewParseError(ctx, "type of var %q is not supported now", exprImpl.V.Name)
   346  	}
   347  	if err != nil {
   348  		return nil, err
   349  	}
   350  	if e.Typ.Id != int32(types.T_any) && expr.Typ.Id != e.Typ.Id {
   351  		expr, err = appendCastBeforeExpr(ctx, expr, e.Typ)
   352  	}
   353  	if err != nil {
   354  		return nil, err
   355  	}
   356  	if c, ok := expr.Expr.(*plan.Expr_Lit); ok {
   357  		c.Lit.Src = e
   358  	} else if _, ok = expr.Expr.(*plan.Expr_F); ok {
   359  		vec, err1 := colexec.EvalExpressionOnce(proc, expr, []*batch.Batch{emptyBat})
   360  		if err1 != nil {
   361  			return nil, err1
   362  		}
   363  		constValue := rule.GetConstantValue(vec, true, 0)
   364  		constValue.Src = e
   365  		expr.Typ = plan.Type{Id: int32(vec.GetType().Oid), Scale: vec.GetType().Scale, Width: vec.GetType().Width}
   366  		expr.Expr = &plan.Expr_Lit{
   367  			Lit: constValue,
   368  		}
   369  		vec.Free(proc.Mp())
   370  	}
   371  	return expr, err
   372  }
   373  
   374  type ConstantFoldRule struct {
   375  	compCtx CompilerContext
   376  	rule    *rule.ConstantFold
   377  }
   378  
   379  func NewConstantFoldRule(compCtx CompilerContext) *ConstantFoldRule {
   380  	return &ConstantFoldRule{
   381  		compCtx: compCtx,
   382  		rule:    constantFoldRule,
   383  	}
   384  }
   385  
   386  func (r *ConstantFoldRule) MatchNode(node *Node) bool {
   387  	return r.rule.Match(node)
   388  }
   389  
   390  func (r *ConstantFoldRule) IsApplyExpr() bool {
   391  	return false
   392  }
   393  
   394  func (r *ConstantFoldRule) ApplyNode(node *Node) error {
   395  	r.rule.Apply(node, nil, r.compCtx.GetProcess())
   396  	return nil
   397  }
   398  
   399  func (r *ConstantFoldRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) {
   400  	return e, nil
   401  }
   402  
   403  type RecomputeRealTimeRelatedFuncRule struct {
   404  	bat  *batch.Batch
   405  	proc *process.Process
   406  }
   407  
   408  func NewRecomputeRealTimeRelatedFuncRule(proc *process.Process) *RecomputeRealTimeRelatedFuncRule {
   409  	bat := batch.NewWithSize(0)
   410  	bat.SetRowCount(1)
   411  	return &RecomputeRealTimeRelatedFuncRule{bat, proc}
   412  }
   413  
   414  func (r *RecomputeRealTimeRelatedFuncRule) MatchNode(_ *Node) bool {
   415  	return false
   416  }
   417  
   418  func (r *RecomputeRealTimeRelatedFuncRule) IsApplyExpr() bool {
   419  	return true
   420  }
   421  
   422  func (r *RecomputeRealTimeRelatedFuncRule) ApplyNode(_ *Node) error {
   423  	return nil
   424  }
   425  
   426  func (r *RecomputeRealTimeRelatedFuncRule) ApplyExpr(e *plan.Expr) (*plan.Expr, error) {
   427  	var err error
   428  	switch exprImpl := e.Expr.(type) {
   429  	case *plan.Expr_F:
   430  		for i, arg := range exprImpl.F.Args {
   431  			exprImpl.F.Args[i], err = r.ApplyExpr(arg)
   432  			if err != nil {
   433  				return nil, err
   434  			}
   435  		}
   436  		return e, nil
   437  	case *plan.Expr_Lit:
   438  		if exprImpl.Lit.Src != nil {
   439  			if _, ok := exprImpl.Lit.Src.Expr.(*plan.Expr_F); ok {
   440  				executor, err := colexec.NewExpressionExecutor(r.proc, exprImpl.Lit.Src)
   441  				if err != nil {
   442  					return nil, err
   443  				}
   444  				defer executor.Free()
   445  				vec, err := executor.Eval(r.proc, []*batch.Batch{r.bat})
   446  				if err != nil {
   447  					return nil, err
   448  				}
   449  				constValue := rule.GetConstantValue(vec, false, 0)
   450  				constValue.Src = exprImpl.Lit.Src
   451  				exprImpl.Lit = constValue
   452  			}
   453  		}
   454  		return e, nil
   455  	default:
   456  		return e, nil
   457  	}
   458  }