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