github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/plan/make.go (about)

     1  // Copyright 2021 - 2022 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package plan
    16  
    17  import (
    18  	"context"
    19  	"unicode/utf8"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/container/types"
    22  	"github.com/matrixorigin/matrixone/pkg/pb/plan"
    23  	"github.com/matrixorigin/matrixone/pkg/sql/plan/function"
    24  )
    25  
    26  func makePlan2DecimalExprWithType(ctx context.Context, v string, isBin ...bool) (*plan.Expr, error) {
    27  	_, scale, err := types.ParseStringToDecimal128WithoutTable(v, isBin...)
    28  	if err != nil {
    29  		return nil, err
    30  	}
    31  	typ := &plan.Type{
    32  		Id:          int32(types.T_decimal128),
    33  		Width:       34,
    34  		Scale:       scale,
    35  		Precision:   34,
    36  		NotNullable: true,
    37  	}
    38  	return appendCastBeforeExpr(ctx, makePlan2StringConstExprWithType(v, isBin...), typ)
    39  }
    40  
    41  func makePlan2DateConstNullExpr(t types.T) *plan.Expr {
    42  	return &plan.Expr{
    43  		Expr: &plan.Expr_C{
    44  			C: &Const{
    45  				Isnull: true,
    46  			},
    47  		},
    48  		Typ: &plan.Type{
    49  			Id:          int32(t),
    50  			NotNullable: false,
    51  		},
    52  	}
    53  }
    54  
    55  func makePlan2Decimal128ConstNullExpr() *plan.Expr {
    56  	return &plan.Expr{
    57  		Expr: &plan.Expr_C{
    58  			C: &Const{
    59  				Isnull: true,
    60  			},
    61  		},
    62  		Typ: &plan.Type{
    63  			Id:          int32(types.T_decimal128),
    64  			Width:       34,
    65  			Scale:       0,
    66  			Precision:   34,
    67  			NotNullable: false,
    68  		},
    69  	}
    70  }
    71  
    72  func makePlan2NullConstExprWithType() *plan.Expr {
    73  	return &plan.Expr{
    74  		Expr: &plan.Expr_C{
    75  			C: &Const{
    76  				Isnull: true,
    77  			},
    78  		},
    79  		Typ: &plan.Type{
    80  			Id:          int32(types.T_any),
    81  			NotNullable: false,
    82  		},
    83  	}
    84  }
    85  
    86  func makePlan2BoolConstExpr(v bool) *plan.Expr_C {
    87  	return &plan.Expr_C{C: &plan.Const{
    88  		Isnull: false,
    89  		Value: &plan.Const_Bval{
    90  			Bval: v,
    91  		},
    92  	}}
    93  }
    94  
    95  func makePlan2BoolConstExprWithType(v bool) *plan.Expr {
    96  	return &plan.Expr{
    97  		Expr: makePlan2BoolConstExpr(v),
    98  		Typ: &plan.Type{
    99  			Id:          int32(types.T_bool),
   100  			NotNullable: true,
   101  			Size:        1,
   102  		},
   103  	}
   104  }
   105  
   106  func makePlan2Int64ConstExpr(v int64) *plan.Expr_C {
   107  	return &plan.Expr_C{C: &plan.Const{
   108  		Isnull: false,
   109  		Value: &plan.Const_I64Val{
   110  			I64Val: v,
   111  		},
   112  	}}
   113  }
   114  
   115  var MakePlan2Int64ConstExprWithType = makePlan2Int64ConstExprWithType
   116  
   117  func makePlan2Int64ConstExprWithType(v int64) *plan.Expr {
   118  	return &plan.Expr{
   119  		Expr: makePlan2Int64ConstExpr(v),
   120  		Typ: &plan.Type{
   121  			Id:          int32(types.T_int64),
   122  			NotNullable: true,
   123  			Size:        8,
   124  		},
   125  	}
   126  }
   127  
   128  func makePlan2Uint64ConstExpr(v uint64) *plan.Expr_C {
   129  	return &plan.Expr_C{C: &plan.Const{
   130  		Isnull: false,
   131  		Value: &plan.Const_U64Val{
   132  			U64Val: v,
   133  		},
   134  	}}
   135  }
   136  
   137  func makePlan2Uint64ConstExprWithType(v uint64) *plan.Expr {
   138  	return &plan.Expr{
   139  		Expr: makePlan2Uint64ConstExpr(v),
   140  		Typ: &plan.Type{
   141  			Id:          int32(types.T_uint64),
   142  			NotNullable: true,
   143  			Size:        8,
   144  		},
   145  	}
   146  }
   147  
   148  func makePlan2Float64ConstExpr(v float64) *plan.Expr_C {
   149  	return &plan.Expr_C{C: &plan.Const{
   150  		Isnull: false,
   151  		Value: &plan.Const_Dval{
   152  			Dval: v,
   153  		},
   154  	}}
   155  }
   156  
   157  var MakePlan2Float64ConstExprWithType = makePlan2Float64ConstExprWithType
   158  
   159  func makePlan2Float64ConstExprWithType(v float64) *plan.Expr {
   160  	return &plan.Expr{
   161  		Expr: makePlan2Float64ConstExpr(v),
   162  		Typ: &plan.Type{
   163  			Id:          int32(types.T_float64),
   164  			NotNullable: true,
   165  			Size:        8,
   166  		},
   167  	}
   168  }
   169  
   170  func makePlan2StringConstExpr(v string, isBin ...bool) *plan.Expr_C {
   171  	c := &plan.Expr_C{C: &plan.Const{
   172  		Isnull: false,
   173  		Value: &plan.Const_Sval{
   174  			Sval: v,
   175  		},
   176  	}}
   177  	if len(isBin) > 0 {
   178  		c.C.IsBin = isBin[0]
   179  	}
   180  	return c
   181  }
   182  
   183  var MakePlan2StringConstExprWithType = makePlan2StringConstExprWithType
   184  
   185  func makePlan2StringConstExprWithType(v string, isBin ...bool) *plan.Expr {
   186  	return &plan.Expr{
   187  		Expr: makePlan2StringConstExpr(v, isBin...),
   188  		Typ: &plan.Type{
   189  			Id:          int32(types.T_varchar),
   190  			NotNullable: true,
   191  			Size:        4,
   192  			Width:       int32(utf8.RuneCountInString(v)),
   193  		},
   194  	}
   195  }
   196  
   197  func makePlan2NullTextConstExpr(v string) *plan.Expr_C {
   198  	c := &plan.Expr_C{C: &plan.Const{
   199  		Isnull: true,
   200  	}}
   201  	return c
   202  }
   203  
   204  func MakePlan2NullTextConstExprWithType(v string) *plan.Expr {
   205  	return &plan.Expr{
   206  		Expr: makePlan2NullTextConstExpr(v),
   207  		Typ: &plan.Type{
   208  			Id:          int32(types.T_text),
   209  			NotNullable: false,
   210  			Size:        4,
   211  			Width:       int32(utf8.RuneCountInString(v)),
   212  		},
   213  	}
   214  }
   215  
   216  func makePlan2CastExpr(ctx context.Context, expr *Expr, targetType *Type) (*Expr, error) {
   217  	if isSameColumnType(expr.Typ, targetType) {
   218  		return expr, nil
   219  	}
   220  	targetType.NotNullable = expr.Typ.NotNullable
   221  	t1, t2 := makeTypeByPlan2Expr(expr), makeTypeByPlan2Type(targetType)
   222  	if types.T(expr.Typ.Id) == types.T_any {
   223  		expr.Typ = targetType
   224  		return expr, nil
   225  	}
   226  	id, _, _, err := function.GetFunctionByName(ctx, "cast", []types.Type{t1, t2})
   227  	if err != nil {
   228  		return nil, err
   229  	}
   230  	t := &plan.Expr{
   231  		Typ: targetType,
   232  		Expr: &plan.Expr_T{
   233  			T: &plan.TargetType{
   234  				Typ: targetType,
   235  			},
   236  		},
   237  	}
   238  	return &plan.Expr{
   239  		Expr: &plan.Expr_F{
   240  			F: &plan.Function{
   241  				Func: &ObjectRef{Obj: id, ObjName: "cast"},
   242  				Args: []*Expr{expr, t},
   243  			},
   244  		},
   245  		Typ: targetType,
   246  	}, nil
   247  }
   248  
   249  // if typ is decimal128 and decimal64 without scalar and precision
   250  // set a default value for it.
   251  func rewriteDecimalTypeIfNecessary(typ *plan.Type) *plan.Type {
   252  	if typ.Id == int32(types.T_decimal128) && typ.Scale == 0 && typ.Width == 0 {
   253  		typ.Scale = 10
   254  		typ.Width = 38 // precision
   255  		typ.Size = int32(types.T_decimal128.TypeLen())
   256  	}
   257  	if typ.Id == int32(types.T_decimal64) && typ.Scale == 0 && typ.Width == 0 {
   258  		typ.Scale = 2
   259  		typ.Width = 6 // precision
   260  		typ.Size = int32(types.T_decimal64.TypeLen())
   261  	}
   262  	return typ
   263  }
   264  
   265  var MakePlan2Type = makePlan2Type
   266  
   267  func makePlan2Type(typ *types.Type) *plan.Type {
   268  	return &plan.Type{
   269  		Id:        int32(typ.Oid),
   270  		Width:     typ.Width,
   271  		Precision: typ.Precision,
   272  		Size:      typ.Size,
   273  		Scale:     typ.Scale,
   274  	}
   275  }
   276  
   277  var MakeTypeByPlan2Type = makeTypeByPlan2Type
   278  
   279  func makeTypeByPlan2Type(typ *plan.Type) types.Type {
   280  	var size int32 = 0
   281  	oid := types.T(typ.Id)
   282  	if oid != types.T_any && oid != types.T_interval {
   283  		size = int32(oid.TypeLen())
   284  	}
   285  	return types.Type{
   286  		Oid:       types.T(typ.Id),
   287  		Size:      size,
   288  		Width:     typ.Width,
   289  		Scale:     typ.Scale,
   290  		Precision: typ.Precision,
   291  	}
   292  }
   293  
   294  var MakeTypeByPlan2Expr = makeTypeByPlan2Expr
   295  
   296  func makeTypeByPlan2Expr(expr *plan.Expr) types.Type {
   297  	var size int32 = 0
   298  	oid := types.T(expr.Typ.Id)
   299  	if oid != types.T_any && oid != types.T_interval {
   300  		size = int32(oid.TypeLen())
   301  	}
   302  	return types.Type{
   303  		Oid:       oid,
   304  		Size:      size,
   305  		Width:     expr.Typ.Width,
   306  		Scale:     expr.Typ.Scale,
   307  		Precision: expr.Typ.Precision,
   308  	}
   309  }