github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/expression_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package memex
    15  
    16  import (
    17  	"time"
    18  
    19  	. "github.com/whtcorpsinc/check"
    20  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    21  	"github.com/whtcorpsinc/BerolinaSQL/perceptron"
    22  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    23  	"github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx"
    24  	"github.com/whtcorpsinc/milevadb/types"
    25  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    26  	"github.com/whtcorpsinc/milevadb/soliton/mock"
    27  )
    28  
    29  func (s *testEvaluatorSuite) TestNewValuesFunc(c *C) {
    30  	res := NewValuesFunc(s.ctx, 0, types.NewFieldType(allegrosql.TypeLonglong))
    31  	c.Assert(res.FuncName.O, Equals, "values")
    32  	c.Assert(res.RetType.Tp, Equals, allegrosql.TypeLonglong)
    33  	_, ok := res.Function.(*builtinValuesIntSig)
    34  	c.Assert(ok, IsTrue)
    35  }
    36  
    37  func (s *testEvaluatorSuite) TestEvaluateExprWithNull(c *C) {
    38  	tblInfo := newTestBlockBuilder("").add("defCaus0", allegrosql.TypeLonglong).add("defCaus1", allegrosql.TypeLonglong).build()
    39  	schemaReplicant := blockInfoToSchemaForTest(tblInfo)
    40  	defCaus0 := schemaReplicant.DeferredCausets[0]
    41  	defCaus1 := schemaReplicant.DeferredCausets[1]
    42  	schemaReplicant.DeferredCausets = schemaReplicant.DeferredCausets[:1]
    43  	innerIfNull, err := newFunctionForTest(s.ctx, ast.Ifnull, defCaus1, NewOne())
    44  	c.Assert(err, IsNil)
    45  	outerIfNull, err := newFunctionForTest(s.ctx, ast.Ifnull, defCaus0, innerIfNull)
    46  	c.Assert(err, IsNil)
    47  
    48  	res := EvaluateExprWithNull(s.ctx, schemaReplicant, outerIfNull)
    49  	c.Assert(res.String(), Equals, "ifnull(DeferredCauset#1, 1)")
    50  
    51  	schemaReplicant.DeferredCausets = append(schemaReplicant.DeferredCausets, defCaus1)
    52  	// ifnull(null, ifnull(null, 1))
    53  	res = EvaluateExprWithNull(s.ctx, schemaReplicant, outerIfNull)
    54  	c.Assert(res.Equal(s.ctx, NewOne()), IsTrue)
    55  }
    56  
    57  func (s *testEvaluatorSuite) TestConstant(c *C) {
    58  	sc := &stmtctx.StatementContext{TimeZone: time.Local}
    59  	c.Assert(NewZero().IsCorrelated(), IsFalse)
    60  	c.Assert(NewZero().ConstItem(sc), IsTrue)
    61  	c.Assert(NewZero().Decorrelate(nil).Equal(s.ctx, NewZero()), IsTrue)
    62  	c.Assert(NewZero().HashCode(sc), DeepEquals, []byte{0x0, 0x8, 0x0})
    63  	c.Assert(NewZero().Equal(s.ctx, NewOne()), IsFalse)
    64  	res, err := NewZero().MarshalJSON()
    65  	c.Assert(err, IsNil)
    66  	c.Assert(res, DeepEquals, []byte{0x22, 0x30, 0x22})
    67  }
    68  
    69  func (s *testEvaluatorSuite) TestIsBinaryLiteral(c *C) {
    70  	defCaus := &DeferredCauset{RetType: types.NewFieldType(allegrosql.TypeEnum)}
    71  	c.Assert(IsBinaryLiteral(defCaus), IsFalse)
    72  	defCaus.RetType.Tp = allegrosql.TypeSet
    73  	c.Assert(IsBinaryLiteral(defCaus), IsFalse)
    74  	defCaus.RetType.Tp = allegrosql.TypeBit
    75  	c.Assert(IsBinaryLiteral(defCaus), IsFalse)
    76  	defCaus.RetType.Tp = allegrosql.TypeDuration
    77  	c.Assert(IsBinaryLiteral(defCaus), IsFalse)
    78  
    79  	con := &Constant{RetType: types.NewFieldType(allegrosql.TypeVarString), Value: types.NewBinaryLiteralCauset([]byte{byte(0), byte(1)})}
    80  	c.Assert(IsBinaryLiteral(con), IsTrue)
    81  	con.Value = types.NewIntCauset(1)
    82  	c.Assert(IsBinaryLiteral(con), IsFalse)
    83  }
    84  
    85  func (s *testEvaluatorSuite) TestConstItem(c *C) {
    86  	sf := newFunction(ast.Rand)
    87  	c.Assert(sf.ConstItem(s.ctx.GetStochastikVars().StmtCtx), Equals, false)
    88  	sf = newFunction(ast.UUID)
    89  	c.Assert(sf.ConstItem(s.ctx.GetStochastikVars().StmtCtx), Equals, false)
    90  	sf = newFunction(ast.GetParam, NewOne())
    91  	c.Assert(sf.ConstItem(s.ctx.GetStochastikVars().StmtCtx), Equals, false)
    92  	sf = newFunction(ast.Abs, NewOne())
    93  	c.Assert(sf.ConstItem(s.ctx.GetStochastikVars().StmtCtx), Equals, true)
    94  }
    95  
    96  func (s *testEvaluatorSuite) TestVectorizable(c *C) {
    97  	exprs := make([]Expression, 0, 4)
    98  	sf := newFunction(ast.Rand)
    99  	defCausumn := &DeferredCauset{
   100  		UniqueID: 0,
   101  		RetType:  types.NewFieldType(allegrosql.TypeLonglong),
   102  	}
   103  	exprs = append(exprs, sf)
   104  	exprs = append(exprs, NewOne())
   105  	exprs = append(exprs, NewNull())
   106  	exprs = append(exprs, defCausumn)
   107  	c.Assert(Vectorizable(exprs), Equals, true)
   108  
   109  	defCausumn0 := &DeferredCauset{
   110  		UniqueID: 1,
   111  		RetType:  types.NewFieldType(allegrosql.TypeString),
   112  	}
   113  	defCausumn1 := &DeferredCauset{
   114  		UniqueID: 2,
   115  		RetType:  types.NewFieldType(allegrosql.TypeString),
   116  	}
   117  	defCausumn2 := &DeferredCauset{
   118  		UniqueID: 3,
   119  		RetType:  types.NewFieldType(allegrosql.TypeLonglong),
   120  	}
   121  	exprs = exprs[:0]
   122  	sf = newFunction(ast.SetVar, defCausumn0, defCausumn1)
   123  	exprs = append(exprs, sf)
   124  	c.Assert(Vectorizable(exprs), Equals, false)
   125  
   126  	exprs = exprs[:0]
   127  	sf = newFunction(ast.GetVar, defCausumn0)
   128  	exprs = append(exprs, sf)
   129  	c.Assert(Vectorizable(exprs), Equals, false)
   130  
   131  	exprs = exprs[:0]
   132  	sf = newFunction(ast.NextVal, defCausumn0)
   133  	exprs = append(exprs, sf)
   134  	sf = newFunction(ast.LastVal, defCausumn0)
   135  	exprs = append(exprs, sf)
   136  	sf = newFunction(ast.SetVal, defCausumn1, defCausumn2)
   137  	exprs = append(exprs, sf)
   138  	c.Assert(Vectorizable(exprs), Equals, false)
   139  }
   140  
   141  type testBlockBuilder struct {
   142  	blockName   string
   143  	defCausumnNames []string
   144  	tps         []byte
   145  }
   146  
   147  func newTestBlockBuilder(blockName string) *testBlockBuilder {
   148  	return &testBlockBuilder{blockName: blockName}
   149  }
   150  
   151  func (builder *testBlockBuilder) add(name string, tp byte) *testBlockBuilder {
   152  	builder.defCausumnNames = append(builder.defCausumnNames, name)
   153  	builder.tps = append(builder.tps, tp)
   154  	return builder
   155  }
   156  
   157  func (builder *testBlockBuilder) build() *perceptron.BlockInfo {
   158  	ti := &perceptron.BlockInfo{
   159  		ID:    1,
   160  		Name:  perceptron.NewCIStr(builder.blockName),
   161  		State: perceptron.StatePublic,
   162  	}
   163  	for i, defCausName := range builder.defCausumnNames {
   164  		tp := builder.tps[i]
   165  		fieldType := types.NewFieldType(tp)
   166  		fieldType.Flen, fieldType.Decimal = allegrosql.GetDefaultFieldLengthAndDecimal(tp)
   167  		fieldType.Charset, fieldType.DefCauslate = types.DefaultCharsetForType(tp)
   168  		ti.DeferredCausets = append(ti.DeferredCausets, &perceptron.DeferredCausetInfo{
   169  			ID:        int64(i + 1),
   170  			Name:      perceptron.NewCIStr(defCausName),
   171  			Offset:    i,
   172  			FieldType: *fieldType,
   173  			State:     perceptron.StatePublic,
   174  		})
   175  	}
   176  	return ti
   177  }
   178  
   179  func blockInfoToSchemaForTest(blockInfo *perceptron.BlockInfo) *Schema {
   180  	defCausumns := blockInfo.DeferredCausets
   181  	schemaReplicant := NewSchema(make([]*DeferredCauset, 0, len(defCausumns))...)
   182  	for i, defCaus := range defCausumns {
   183  		schemaReplicant.Append(&DeferredCauset{
   184  			UniqueID: int64(i),
   185  			ID:       defCaus.ID,
   186  			RetType:  &defCaus.FieldType,
   187  		})
   188  	}
   189  	return schemaReplicant
   190  }
   191  
   192  func (s *testEvaluatorSuite) TestEvalExpr(c *C) {
   193  	ctx := mock.NewContext()
   194  	eTypes := []types.EvalType{types.ETInt, types.ETReal, types.ETDecimal, types.ETString, types.ETTimestamp, types.ETDatetime, types.ETDuration}
   195  	tNames := []string{"int", "real", "decimal", "string", "timestamp", "datetime", "duration"}
   196  	for i := 0; i < len(tNames); i++ {
   197  		ft := eType2FieldType(eTypes[i])
   198  		defCausExpr := &DeferredCauset{Index: 0, RetType: ft}
   199  		input := chunk.New([]*types.FieldType{ft}, 1024, 1024)
   200  		fillDeferredCausetWithGener(eTypes[i], input, 0, nil)
   201  		defCausBuf := chunk.NewDeferredCauset(ft, 1024)
   202  		defCausBuf2 := chunk.NewDeferredCauset(ft, 1024)
   203  		var err error
   204  		c.Assert(defCausExpr.Vectorized(), IsTrue)
   205  		ctx.GetStochastikVars().EnableVectorizedExpression = false
   206  		err = EvalExpr(ctx, defCausExpr, input, defCausBuf)
   207  		if err != nil {
   208  			c.Fatal(err)
   209  		}
   210  		ctx.GetStochastikVars().EnableVectorizedExpression = true
   211  		err = EvalExpr(ctx, defCausExpr, input, defCausBuf2)
   212  		if err != nil {
   213  			c.Fatal(err)
   214  		}
   215  		for j := 0; j < 1024; j++ {
   216  			isNull := defCausBuf.IsNull(j)
   217  			isNull2 := defCausBuf2.IsNull(j)
   218  			c.Assert(isNull, Equals, isNull2)
   219  			if isNull {
   220  				continue
   221  			}
   222  			c.Assert(string(defCausBuf.GetRaw(j)), Equals, string(defCausBuf2.GetRaw(j)))
   223  		}
   224  	}
   225  }