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 }