github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin.go (about) 1 // Copyright 2020 The ql Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSES/QL-LICENSE file. 4 5 // Copyright 2020 WHTCORPS INC, Inc. 6 // 7 // Licensed under the Apache License, Version 2.0 (the "License"); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an "AS IS" BASIS, 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 //go:generate go run generator/compare_vec.go 19 //go:generate go run generator/control_vec.go 20 //go:generate go run generator/other_vec.go 21 //go:generate go run generator/string_vec.go 22 //go:generate go run generator/time_vec.go 23 24 package memex 25 26 import ( 27 "sort" 28 "strings" 29 "sync" 30 31 "github.com/gogo/protobuf/proto" 32 "github.com/whtcorpsinc/errors" 33 "github.com/whtcorpsinc/BerolinaSQL/ast" 34 "github.com/whtcorpsinc/BerolinaSQL/charset" 35 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 36 "github.com/whtcorpsinc/BerolinaSQL/opcode" 37 "github.com/whtcorpsinc/milevadb/stochastikctx" 38 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 39 "github.com/whtcorpsinc/milevadb/types" 40 "github.com/whtcorpsinc/milevadb/types/json" 41 "github.com/whtcorpsinc/milevadb/soliton/chunk" 42 "github.com/whtcorpsinc/milevadb/soliton/defCauslate" 43 "github.com/whtcorpsinc/fidelpb/go-fidelpb" 44 ) 45 46 // baseBuiltinFunc will be contained in every struct that implement builtinFunc interface. 47 type baseBuiltinFunc struct { 48 bufSlabPredictor defCausumnBufferSlabPredictor 49 args []Expression 50 ctx stochastikctx.Context 51 tp *types.FieldType 52 pbCode fidelpb.ScalarFuncSig 53 ctor defCauslate.DefCauslator 54 55 childrenVectorized bool 56 childrenReversed bool 57 58 childrenVectorizedOnce *sync.Once 59 childrenReversedOnce *sync.Once 60 61 defCauslationInfo 62 } 63 64 func (b *baseBuiltinFunc) PbCode() fidelpb.ScalarFuncSig { 65 return b.pbCode 66 } 67 68 // spacetimedata returns the spacetimedata of a function. 69 // spacetimedata means some functions contain extra inner fields which will not 70 // contain in `fidelpb.Expr.children` but must be pushed down to interlock 71 func (b *baseBuiltinFunc) spacetimedata() proto.Message { 72 // We will not use a field to causetstore them because of only 73 // a few functions contain implicit parameters 74 return nil 75 } 76 77 func (b *baseBuiltinFunc) setPbCode(c fidelpb.ScalarFuncSig) { 78 b.pbCode = c 79 } 80 81 func (b *baseBuiltinFunc) setDefCauslator(ctor defCauslate.DefCauslator) { 82 b.ctor = ctor 83 } 84 85 func (b *baseBuiltinFunc) defCauslator() defCauslate.DefCauslator { 86 return b.ctor 87 } 88 89 func newBaseBuiltinFunc(ctx stochastikctx.Context, funcName string, args []Expression, retType types.EvalType) (baseBuiltinFunc, error) { 90 if ctx == nil { 91 return baseBuiltinFunc{}, errors.New("unexpected nil stochastik ctx") 92 } 93 if err := checkIllegalMixDefCauslation(funcName, args, retType); err != nil { 94 return baseBuiltinFunc{}, err 95 } 96 derivedCharset, derivedDefCauslate := DeriveDefCauslationFromExprs(ctx, args...) 97 bf := baseBuiltinFunc{ 98 bufSlabPredictor: newLocalSliceBuffer(len(args)), 99 childrenVectorizedOnce: new(sync.Once), 100 childrenReversedOnce: new(sync.Once), 101 102 args: args, 103 ctx: ctx, 104 tp: types.NewFieldType(allegrosql.TypeUnspecified), 105 } 106 bf.SetCharsetAndDefCauslation(derivedCharset, derivedDefCauslate) 107 bf.setDefCauslator(defCauslate.GetDefCauslator(derivedDefCauslate)) 108 return bf, nil 109 } 110 111 var ( 112 coerString = []string{"EXPLICIT", "NONE", "IMPLICIT", "SYSCONST", "COERCIBLE", "NUMERIC", "IGNORABLE"} 113 ) 114 115 func checkIllegalMixDefCauslation(funcName string, args []Expression, evalType types.EvalType) error { 116 if len(args) < 2 { 117 return nil 118 } 119 _, _, coercibility, legal := inferDefCauslation(args...) 120 if !legal { 121 return illegalMixDefCauslationErr(funcName, args) 122 } 123 if coercibility == CoercibilityNone && evalType != types.ETString { 124 return illegalMixDefCauslationErr(funcName, args) 125 } 126 return nil 127 } 128 129 func illegalMixDefCauslationErr(funcName string, args []Expression) error { 130 switch len(args) { 131 case 2: 132 return defCauslate.ErrIllegalMix2DefCauslation.GenWithStackByArgs(args[0].GetType().DefCauslate, coerString[args[0].Coercibility()], args[1].GetType().DefCauslate, coerString[args[1].Coercibility()], funcName) 133 case 3: 134 return defCauslate.ErrIllegalMix3DefCauslation.GenWithStackByArgs(args[0].GetType().DefCauslate, coerString[args[0].Coercibility()], args[1].GetType().DefCauslate, coerString[args[1].Coercibility()], args[0].GetType().DefCauslate, coerString[args[2].Coercibility()], funcName) 135 default: 136 return defCauslate.ErrIllegalMixDefCauslation.GenWithStackByArgs(funcName) 137 } 138 } 139 140 // newBaseBuiltinFuncWithTp creates a built-in function signature with specified types of arguments and the return type of the function. 141 // argTps indicates the types of the args, retType indicates the return type of the built-in function. 142 // Every built-in function needs determined argTps and retType when we create it. 143 func newBaseBuiltinFuncWithTp(ctx stochastikctx.Context, funcName string, args []Expression, retType types.EvalType, argTps ...types.EvalType) (bf baseBuiltinFunc, err error) { 144 if len(args) != len(argTps) { 145 panic("unexpected length of args and argTps") 146 } 147 if ctx == nil { 148 return baseBuiltinFunc{}, errors.New("unexpected nil stochastik ctx") 149 } 150 151 for i := range args { 152 switch argTps[i] { 153 case types.ETInt: 154 args[i] = WrapWithCastAsInt(ctx, args[i]) 155 case types.ETReal: 156 args[i] = WrapWithCastAsReal(ctx, args[i]) 157 case types.ETDecimal: 158 args[i] = WrapWithCastAsDecimal(ctx, args[i]) 159 case types.ETString: 160 args[i] = WrapWithCastAsString(ctx, args[i]) 161 case types.ETDatetime: 162 args[i] = WrapWithCastAsTime(ctx, args[i], types.NewFieldType(allegrosql.TypeDatetime)) 163 case types.ETTimestamp: 164 args[i] = WrapWithCastAsTime(ctx, args[i], types.NewFieldType(allegrosql.TypeTimestamp)) 165 case types.ETDuration: 166 args[i] = WrapWithCastAsDuration(ctx, args[i]) 167 case types.ETJson: 168 args[i] = WrapWithCastAsJSON(ctx, args[i]) 169 } 170 } 171 172 if err = checkIllegalMixDefCauslation(funcName, args, retType); err != nil { 173 return 174 } 175 176 // derive defCauslation information for string function, and we must do it 177 // before doing implicit cast. 178 derivedCharset, derivedDefCauslate := DeriveDefCauslationFromExprs(ctx, args...) 179 var fieldType *types.FieldType 180 switch retType { 181 case types.ETInt: 182 fieldType = &types.FieldType{ 183 Tp: allegrosql.TypeLonglong, 184 Flen: allegrosql.MaxIntWidth, 185 Decimal: 0, 186 Flag: allegrosql.BinaryFlag, 187 } 188 case types.ETReal: 189 fieldType = &types.FieldType{ 190 Tp: allegrosql.TypeDouble, 191 Flen: allegrosql.MaxRealWidth, 192 Decimal: types.UnspecifiedLength, 193 Flag: allegrosql.BinaryFlag, 194 } 195 case types.ETDecimal: 196 fieldType = &types.FieldType{ 197 Tp: allegrosql.TypeNewDecimal, 198 Flen: 11, 199 Decimal: 0, 200 Flag: allegrosql.BinaryFlag, 201 } 202 case types.ETString: 203 fieldType = &types.FieldType{ 204 Tp: allegrosql.TypeVarString, 205 Decimal: types.UnspecifiedLength, 206 Charset: derivedCharset, 207 DefCauslate: derivedDefCauslate, 208 Flen: types.UnspecifiedLength, 209 } 210 case types.ETDatetime: 211 fieldType = &types.FieldType{ 212 Tp: allegrosql.TypeDatetime, 213 Flen: allegrosql.MaxDatetimeWidthWithFsp, 214 Decimal: int(types.MaxFsp), 215 Flag: allegrosql.BinaryFlag, 216 } 217 case types.ETTimestamp: 218 fieldType = &types.FieldType{ 219 Tp: allegrosql.TypeTimestamp, 220 Flen: allegrosql.MaxDatetimeWidthWithFsp, 221 Decimal: int(types.MaxFsp), 222 Flag: allegrosql.BinaryFlag, 223 } 224 case types.ETDuration: 225 fieldType = &types.FieldType{ 226 Tp: allegrosql.TypeDuration, 227 Flen: allegrosql.MaxDurationWidthWithFsp, 228 Decimal: int(types.MaxFsp), 229 Flag: allegrosql.BinaryFlag, 230 } 231 case types.ETJson: 232 fieldType = &types.FieldType{ 233 Tp: allegrosql.TypeJSON, 234 Flen: allegrosql.MaxBlobWidth, 235 Decimal: 0, 236 Charset: allegrosql.DefaultCharset, 237 DefCauslate: allegrosql.DefaultDefCauslationName, 238 Flag: allegrosql.BinaryFlag, 239 } 240 } 241 if allegrosql.HasBinaryFlag(fieldType.Flag) && fieldType.Tp != allegrosql.TypeJSON { 242 fieldType.Charset, fieldType.DefCauslate = charset.CharsetBin, charset.DefCauslationBin 243 } 244 bf = baseBuiltinFunc{ 245 bufSlabPredictor: newLocalSliceBuffer(len(args)), 246 childrenVectorizedOnce: new(sync.Once), 247 childrenReversedOnce: new(sync.Once), 248 249 args: args, 250 ctx: ctx, 251 tp: fieldType, 252 } 253 bf.SetCharsetAndDefCauslation(derivedCharset, derivedDefCauslate) 254 bf.setDefCauslator(defCauslate.GetDefCauslator(derivedDefCauslate)) 255 return bf, nil 256 } 257 258 // newBaseBuiltinFuncWithFieldType create BaseBuiltinFunc with FieldType charset and defCauslation. 259 // do not check and compute defCauslation. 260 func newBaseBuiltinFuncWithFieldType(ctx stochastikctx.Context, tp *types.FieldType, args []Expression) (baseBuiltinFunc, error) { 261 if ctx == nil { 262 return baseBuiltinFunc{}, errors.New("unexpected nil stochastik ctx") 263 } 264 bf := baseBuiltinFunc{ 265 bufSlabPredictor: newLocalSliceBuffer(len(args)), 266 childrenVectorizedOnce: new(sync.Once), 267 childrenReversedOnce: new(sync.Once), 268 269 args: args, 270 ctx: ctx, 271 tp: types.NewFieldType(allegrosql.TypeUnspecified), 272 } 273 bf.SetCharsetAndDefCauslation(tp.Charset, tp.DefCauslate) 274 bf.setDefCauslator(defCauslate.GetDefCauslator(tp.DefCauslate)) 275 return bf, nil 276 } 277 278 func (b *baseBuiltinFunc) getArgs() []Expression { 279 return b.args 280 } 281 282 func (b *baseBuiltinFunc) vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error { 283 return errors.Errorf("baseBuiltinFunc.vecEvalInt() should never be called, please contact the MilevaDB team for help") 284 } 285 286 func (b *baseBuiltinFunc) vecEvalReal(input *chunk.Chunk, result *chunk.DeferredCauset) error { 287 return errors.Errorf("baseBuiltinFunc.vecEvalReal() should never be called, please contact the MilevaDB team for help") 288 } 289 290 func (b *baseBuiltinFunc) vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error { 291 return errors.Errorf("baseBuiltinFunc.vecEvalString() should never be called, please contact the MilevaDB team for help") 292 } 293 294 func (b *baseBuiltinFunc) vecEvalDecimal(input *chunk.Chunk, result *chunk.DeferredCauset) error { 295 return errors.Errorf("baseBuiltinFunc.vecEvalDecimal() should never be called, please contact the MilevaDB team for help") 296 } 297 298 func (b *baseBuiltinFunc) vecEvalTime(input *chunk.Chunk, result *chunk.DeferredCauset) error { 299 return errors.Errorf("baseBuiltinFunc.vecEvalTime() should never be called, please contact the MilevaDB team for help") 300 } 301 302 func (b *baseBuiltinFunc) vecEvalDuration(input *chunk.Chunk, result *chunk.DeferredCauset) error { 303 return errors.Errorf("baseBuiltinFunc.vecEvalDuration() should never be called, please contact the MilevaDB team for help") 304 } 305 306 func (b *baseBuiltinFunc) vecEvalJSON(input *chunk.Chunk, result *chunk.DeferredCauset) error { 307 return errors.Errorf("baseBuiltinFunc.vecEvalJSON() should never be called, please contact the MilevaDB team for help") 308 } 309 310 func (b *baseBuiltinFunc) evalInt(event chunk.Event) (int64, bool, error) { 311 return 0, false, errors.Errorf("baseBuiltinFunc.evalInt() should never be called, please contact the MilevaDB team for help") 312 } 313 314 func (b *baseBuiltinFunc) evalReal(event chunk.Event) (float64, bool, error) { 315 return 0, false, errors.Errorf("baseBuiltinFunc.evalReal() should never be called, please contact the MilevaDB team for help") 316 } 317 318 func (b *baseBuiltinFunc) evalString(event chunk.Event) (string, bool, error) { 319 return "", false, errors.Errorf("baseBuiltinFunc.evalString() should never be called, please contact the MilevaDB team for help") 320 } 321 322 func (b *baseBuiltinFunc) evalDecimal(event chunk.Event) (*types.MyDecimal, bool, error) { 323 return nil, false, errors.Errorf("baseBuiltinFunc.evalDecimal() should never be called, please contact the MilevaDB team for help") 324 } 325 326 func (b *baseBuiltinFunc) evalTime(event chunk.Event) (types.Time, bool, error) { 327 return types.ZeroTime, false, errors.Errorf("baseBuiltinFunc.evalTime() should never be called, please contact the MilevaDB team for help") 328 } 329 330 func (b *baseBuiltinFunc) evalDuration(event chunk.Event) (types.Duration, bool, error) { 331 return types.Duration{}, false, errors.Errorf("baseBuiltinFunc.evalDuration() should never be called, please contact the MilevaDB team for help") 332 } 333 334 func (b *baseBuiltinFunc) evalJSON(event chunk.Event) (json.BinaryJSON, bool, error) { 335 return json.BinaryJSON{}, false, errors.Errorf("baseBuiltinFunc.evalJSON() should never be called, please contact the MilevaDB team for help") 336 } 337 338 func (b *baseBuiltinFunc) vectorized() bool { 339 return false 340 } 341 342 func (b *baseBuiltinFunc) supportReverseEval() bool { 343 return false 344 } 345 346 func (b *baseBuiltinFunc) isChildrenReversed() bool { 347 b.childrenReversedOnce.Do(func() { 348 b.childrenReversed = true 349 for _, arg := range b.args { 350 if !arg.SupportReverseEval() { 351 b.childrenReversed = false 352 break 353 } 354 } 355 }) 356 return b.childrenReversed 357 } 358 359 func (b *baseBuiltinFunc) reverseEval(sc *stmtctx.StatementContext, res types.Causet, rType types.RoundingType) (types.Causet, error) { 360 return types.Causet{}, errors.Errorf("baseBuiltinFunc.reverseEvalInt() should never be called, please contact the MilevaDB team for help") 361 } 362 363 func (b *baseBuiltinFunc) isChildrenVectorized() bool { 364 b.childrenVectorizedOnce.Do(func() { 365 b.childrenVectorized = true 366 for _, arg := range b.args { 367 if !arg.Vectorized() { 368 b.childrenVectorized = false 369 break 370 } 371 } 372 }) 373 return b.childrenVectorized 374 } 375 376 func (b *baseBuiltinFunc) getRetTp() *types.FieldType { 377 switch b.tp.EvalType() { 378 case types.ETString: 379 if b.tp.Flen >= allegrosql.MaxBlobWidth { 380 b.tp.Tp = allegrosql.TypeLongBlob 381 } else if b.tp.Flen >= 65536 { 382 b.tp.Tp = allegrosql.TypeMediumBlob 383 } 384 if len(b.tp.Charset) <= 0 { 385 b.tp.Charset, b.tp.DefCauslate = charset.GetDefaultCharsetAndDefCauslate() 386 } 387 } 388 return b.tp 389 } 390 391 func (b *baseBuiltinFunc) equal(fun builtinFunc) bool { 392 funArgs := fun.getArgs() 393 if len(funArgs) != len(b.args) { 394 return false 395 } 396 for i := range b.args { 397 if !b.args[i].Equal(b.ctx, funArgs[i]) { 398 return false 399 } 400 } 401 return true 402 } 403 404 func (b *baseBuiltinFunc) getCtx() stochastikctx.Context { 405 return b.ctx 406 } 407 408 func (b *baseBuiltinFunc) cloneFrom(from *baseBuiltinFunc) { 409 b.args = make([]Expression, 0, len(b.args)) 410 for _, arg := range from.args { 411 b.args = append(b.args, arg.Clone()) 412 } 413 b.ctx = from.ctx 414 b.tp = from.tp 415 b.pbCode = from.pbCode 416 b.bufSlabPredictor = newLocalSliceBuffer(len(b.args)) 417 b.childrenVectorizedOnce = new(sync.Once) 418 b.childrenReversedOnce = new(sync.Once) 419 b.ctor = from.ctor 420 } 421 422 func (b *baseBuiltinFunc) Clone() builtinFunc { 423 panic("you should not call this method.") 424 } 425 426 // baseBuiltinCastFunc will be contained in every struct that implement cast builtinFunc. 427 type baseBuiltinCastFunc struct { 428 baseBuiltinFunc 429 430 // inUnion indicates whether cast is in union context. 431 inUnion bool 432 } 433 434 // spacetimedata returns the spacetimedata of cast functions 435 func (b *baseBuiltinCastFunc) spacetimedata() proto.Message { 436 args := &fidelpb.InUnionMetadata{ 437 InUnion: b.inUnion, 438 } 439 return args 440 } 441 442 func (b *baseBuiltinCastFunc) cloneFrom(from *baseBuiltinCastFunc) { 443 b.baseBuiltinFunc.cloneFrom(&from.baseBuiltinFunc) 444 b.inUnion = from.inUnion 445 } 446 447 func newBaseBuiltinCastFunc(builtinFunc baseBuiltinFunc, inUnion bool) baseBuiltinCastFunc { 448 return baseBuiltinCastFunc{ 449 baseBuiltinFunc: builtinFunc, 450 inUnion: inUnion, 451 } 452 } 453 454 // vecBuiltinFunc contains all vectorized methods for a builtin function. 455 type vecBuiltinFunc interface { 456 // vectorized returns if this builtin function itself supports vectorized evaluation. 457 vectorized() bool 458 459 // isChildrenVectorized returns if its all children support vectorized evaluation. 460 isChildrenVectorized() bool 461 462 // vecEvalInt evaluates this builtin function in a vectorized manner. 463 vecEvalInt(input *chunk.Chunk, result *chunk.DeferredCauset) error 464 465 // vecEvalReal evaluates this builtin function in a vectorized manner. 466 vecEvalReal(input *chunk.Chunk, result *chunk.DeferredCauset) error 467 468 // vecEvalString evaluates this builtin function in a vectorized manner. 469 vecEvalString(input *chunk.Chunk, result *chunk.DeferredCauset) error 470 471 // vecEvalDecimal evaluates this builtin function in a vectorized manner. 472 vecEvalDecimal(input *chunk.Chunk, result *chunk.DeferredCauset) error 473 474 // vecEvalTime evaluates this builtin function in a vectorized manner. 475 vecEvalTime(input *chunk.Chunk, result *chunk.DeferredCauset) error 476 477 // vecEvalDuration evaluates this builtin function in a vectorized manner. 478 vecEvalDuration(input *chunk.Chunk, result *chunk.DeferredCauset) error 479 480 // vecEvalJSON evaluates this builtin function in a vectorized manner. 481 vecEvalJSON(input *chunk.Chunk, result *chunk.DeferredCauset) error 482 } 483 484 // reverseBuiltinFunc evaluates the exactly one defCausumn value in the function when given a result for memex. 485 // For example, the builtinFunc is builtinArithmeticPlusRealSig(2.3, builtinArithmeticMinusRealSig(DeferredCauset, 3.4)) 486 // when given the result like 1.0, then the ReverseEval should evaluate the defCausumn value 1.0 - 2.3 + 3.4 = 2.1 487 type reverseBuiltinFunc interface { 488 // supportReverseEval checks whether the builtinFunc support reverse evaluation. 489 supportReverseEval() bool 490 // isChildrenReversed checks whether the builtinFunc's children support reverse evaluation. 491 isChildrenReversed() bool 492 // reverseEval evaluates the only one defCausumn value with given function result. 493 reverseEval(sc *stmtctx.StatementContext, res types.Causet, rType types.RoundingType) (val types.Causet, err error) 494 } 495 496 // builtinFunc stands for a particular function signature. 497 type builtinFunc interface { 498 vecBuiltinFunc 499 reverseBuiltinFunc 500 501 // evalInt evaluates int result of builtinFunc by given event. 502 evalInt(event chunk.Event) (val int64, isNull bool, err error) 503 // evalReal evaluates real representation of builtinFunc by given event. 504 evalReal(event chunk.Event) (val float64, isNull bool, err error) 505 // evalString evaluates string representation of builtinFunc by given event. 506 evalString(event chunk.Event) (val string, isNull bool, err error) 507 // evalDecimal evaluates decimal representation of builtinFunc by given event. 508 evalDecimal(event chunk.Event) (val *types.MyDecimal, isNull bool, err error) 509 // evalTime evaluates DATE/DATETIME/TIMESTAMP representation of builtinFunc by given event. 510 evalTime(event chunk.Event) (val types.Time, isNull bool, err error) 511 // evalDuration evaluates duration representation of builtinFunc by given event. 512 evalDuration(event chunk.Event) (val types.Duration, isNull bool, err error) 513 // evalJSON evaluates JSON representation of builtinFunc by given event. 514 evalJSON(event chunk.Event) (val json.BinaryJSON, isNull bool, err error) 515 // getArgs returns the arguments memexs. 516 getArgs() []Expression 517 // equal check if this function equals to another function. 518 equal(builtinFunc) bool 519 // getCtx returns this function's context. 520 getCtx() stochastikctx.Context 521 // getRetTp returns the return type of the built-in function. 522 getRetTp() *types.FieldType 523 // setPbCode sets pbCode for signature. 524 setPbCode(fidelpb.ScalarFuncSig) 525 // PbCode returns PbCode of this signature. 526 PbCode() fidelpb.ScalarFuncSig 527 // setDefCauslator sets defCauslator for signature. 528 setDefCauslator(ctor defCauslate.DefCauslator) 529 // defCauslator returns defCauslator of this signature. 530 defCauslator() defCauslate.DefCauslator 531 // spacetimedata returns the spacetimedata of a function. 532 // spacetimedata means some functions contain extra inner fields which will not 533 // contain in `fidelpb.Expr.children` but must be pushed down to interlock 534 spacetimedata() proto.Message 535 // Clone returns a copy of itself. 536 Clone() builtinFunc 537 538 DefCauslationInfo 539 } 540 541 type builtinFuncNew interface { 542 evalIntWithCtx(ctx stochastikctx.Context, event chunk.Event) (val int64, isNull bool, err error) 543 } 544 545 // baseFunctionClass will be contained in every struct that implement functionClass interface. 546 type baseFunctionClass struct { 547 funcName string 548 minArgs int 549 maxArgs int 550 } 551 552 func (b *baseFunctionClass) verifyArgs(args []Expression) error { 553 l := len(args) 554 if l < b.minArgs || (b.maxArgs != -1 && l > b.maxArgs) { 555 return ErrIncorrectParameterCount.GenWithStackByArgs(b.funcName) 556 } 557 return nil 558 } 559 560 // functionClass is the interface for a function which may contains multiple functions. 561 type functionClass interface { 562 // getFunction gets a function signature by the types and the counts of given arguments. 563 getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) 564 } 565 566 // funcs holds all registered builtin functions. When new function is added, 567 // check memex/function_traits.go to see if it should be appended to 568 // any set there. 569 var funcs = map[string]functionClass{ 570 // common functions 571 ast.Coalesce: &coalesceFunctionClass{baseFunctionClass{ast.Coalesce, 1, -1}}, 572 ast.IsNull: &isNullFunctionClass{baseFunctionClass{ast.IsNull, 1, 1}}, 573 ast.Greatest: &greatestFunctionClass{baseFunctionClass{ast.Greatest, 2, -1}}, 574 ast.Least: &leastFunctionClass{baseFunctionClass{ast.Least, 2, -1}}, 575 ast.Interval: &intervalFunctionClass{baseFunctionClass{ast.Interval, 2, -1}}, 576 577 // math functions 578 ast.Abs: &absFunctionClass{baseFunctionClass{ast.Abs, 1, 1}}, 579 ast.Acos: &acosFunctionClass{baseFunctionClass{ast.Acos, 1, 1}}, 580 ast.Asin: &asinFunctionClass{baseFunctionClass{ast.Asin, 1, 1}}, 581 ast.Atan: &atanFunctionClass{baseFunctionClass{ast.Atan, 1, 2}}, 582 ast.Atan2: &atanFunctionClass{baseFunctionClass{ast.Atan2, 2, 2}}, 583 ast.Ceil: &ceilFunctionClass{baseFunctionClass{ast.Ceil, 1, 1}}, 584 ast.Ceiling: &ceilFunctionClass{baseFunctionClass{ast.Ceiling, 1, 1}}, 585 ast.Conv: &convFunctionClass{baseFunctionClass{ast.Conv, 3, 3}}, 586 ast.Cos: &cosFunctionClass{baseFunctionClass{ast.Cos, 1, 1}}, 587 ast.Cot: &cotFunctionClass{baseFunctionClass{ast.Cot, 1, 1}}, 588 ast.CRC32: &crc32FunctionClass{baseFunctionClass{ast.CRC32, 1, 1}}, 589 ast.Degrees: °reesFunctionClass{baseFunctionClass{ast.Degrees, 1, 1}}, 590 ast.Exp: &expFunctionClass{baseFunctionClass{ast.Exp, 1, 1}}, 591 ast.Floor: &floorFunctionClass{baseFunctionClass{ast.Floor, 1, 1}}, 592 ast.Ln: &logFunctionClass{baseFunctionClass{ast.Ln, 1, 1}}, 593 ast.Log: &logFunctionClass{baseFunctionClass{ast.Log, 1, 2}}, 594 ast.Log2: &log2FunctionClass{baseFunctionClass{ast.Log2, 1, 1}}, 595 ast.Log10: &log10FunctionClass{baseFunctionClass{ast.Log10, 1, 1}}, 596 ast.PI: &piFunctionClass{baseFunctionClass{ast.PI, 0, 0}}, 597 ast.Pow: &powFunctionClass{baseFunctionClass{ast.Pow, 2, 2}}, 598 ast.Power: &powFunctionClass{baseFunctionClass{ast.Power, 2, 2}}, 599 ast.Radians: &radiansFunctionClass{baseFunctionClass{ast.Radians, 1, 1}}, 600 ast.Rand: &randFunctionClass{baseFunctionClass{ast.Rand, 0, 1}}, 601 ast.Round: &roundFunctionClass{baseFunctionClass{ast.Round, 1, 2}}, 602 ast.Sign: &signFunctionClass{baseFunctionClass{ast.Sign, 1, 1}}, 603 ast.Sin: &sinFunctionClass{baseFunctionClass{ast.Sin, 1, 1}}, 604 ast.Sqrt: &sqrtFunctionClass{baseFunctionClass{ast.Sqrt, 1, 1}}, 605 ast.Tan: &tanFunctionClass{baseFunctionClass{ast.Tan, 1, 1}}, 606 ast.Truncate: &truncateFunctionClass{baseFunctionClass{ast.Truncate, 2, 2}}, 607 608 // time functions 609 ast.AddDate: &addDateFunctionClass{baseFunctionClass{ast.AddDate, 3, 3}}, 610 ast.DateAdd: &addDateFunctionClass{baseFunctionClass{ast.DateAdd, 3, 3}}, 611 ast.SubDate: &subDateFunctionClass{baseFunctionClass{ast.SubDate, 3, 3}}, 612 ast.DateSub: &subDateFunctionClass{baseFunctionClass{ast.DateSub, 3, 3}}, 613 ast.AddTime: &addTimeFunctionClass{baseFunctionClass{ast.AddTime, 2, 2}}, 614 ast.ConvertTz: &convertTzFunctionClass{baseFunctionClass{ast.ConvertTz, 3, 3}}, 615 ast.Curdate: ¤tDateFunctionClass{baseFunctionClass{ast.Curdate, 0, 0}}, 616 ast.CurrentDate: ¤tDateFunctionClass{baseFunctionClass{ast.CurrentDate, 0, 0}}, 617 ast.CurrentTime: ¤tTimeFunctionClass{baseFunctionClass{ast.CurrentTime, 0, 1}}, 618 ast.CurrentTimestamp: &nowFunctionClass{baseFunctionClass{ast.CurrentTimestamp, 0, 1}}, 619 ast.Curtime: ¤tTimeFunctionClass{baseFunctionClass{ast.Curtime, 0, 1}}, 620 ast.Date: &dateFunctionClass{baseFunctionClass{ast.Date, 1, 1}}, 621 ast.DateLiteral: &dateLiteralFunctionClass{baseFunctionClass{ast.DateLiteral, 1, 1}}, 622 ast.DateFormat: &dateFormatFunctionClass{baseFunctionClass{ast.DateFormat, 2, 2}}, 623 ast.DateDiff: &dateDiffFunctionClass{baseFunctionClass{ast.DateDiff, 2, 2}}, 624 ast.Day: &dayOfMonthFunctionClass{baseFunctionClass{ast.Day, 1, 1}}, 625 ast.DayName: &dayNameFunctionClass{baseFunctionClass{ast.DayName, 1, 1}}, 626 ast.DayOfMonth: &dayOfMonthFunctionClass{baseFunctionClass{ast.DayOfMonth, 1, 1}}, 627 ast.DayOfWeek: &dayOfWeekFunctionClass{baseFunctionClass{ast.DayOfWeek, 1, 1}}, 628 ast.DayOfYear: &dayOfYearFunctionClass{baseFunctionClass{ast.DayOfYear, 1, 1}}, 629 ast.Extract: &extractFunctionClass{baseFunctionClass{ast.Extract, 2, 2}}, 630 ast.FromDays: &fromDaysFunctionClass{baseFunctionClass{ast.FromDays, 1, 1}}, 631 ast.FromUnixTime: &fromUnixTimeFunctionClass{baseFunctionClass{ast.FromUnixTime, 1, 2}}, 632 ast.GetFormat: &getFormatFunctionClass{baseFunctionClass{ast.GetFormat, 2, 2}}, 633 ast.Hour: &hourFunctionClass{baseFunctionClass{ast.Hour, 1, 1}}, 634 ast.LocalTime: &nowFunctionClass{baseFunctionClass{ast.LocalTime, 0, 1}}, 635 ast.LocalTimestamp: &nowFunctionClass{baseFunctionClass{ast.LocalTimestamp, 0, 1}}, 636 ast.MakeDate: &makeDateFunctionClass{baseFunctionClass{ast.MakeDate, 2, 2}}, 637 ast.MakeTime: &makeTimeFunctionClass{baseFunctionClass{ast.MakeTime, 3, 3}}, 638 ast.MicroSecond: µSecondFunctionClass{baseFunctionClass{ast.MicroSecond, 1, 1}}, 639 ast.Minute: &minuteFunctionClass{baseFunctionClass{ast.Minute, 1, 1}}, 640 ast.Month: &monthFunctionClass{baseFunctionClass{ast.Month, 1, 1}}, 641 ast.MonthName: &monthNameFunctionClass{baseFunctionClass{ast.MonthName, 1, 1}}, 642 ast.Now: &nowFunctionClass{baseFunctionClass{ast.Now, 0, 1}}, 643 ast.PeriodAdd: &periodAddFunctionClass{baseFunctionClass{ast.PeriodAdd, 2, 2}}, 644 ast.PeriodDiff: &periodDiffFunctionClass{baseFunctionClass{ast.PeriodDiff, 2, 2}}, 645 ast.Quarter: &quarterFunctionClass{baseFunctionClass{ast.Quarter, 1, 1}}, 646 ast.SecToTime: &secToTimeFunctionClass{baseFunctionClass{ast.SecToTime, 1, 1}}, 647 ast.Second: &secondFunctionClass{baseFunctionClass{ast.Second, 1, 1}}, 648 ast.StrToDate: &strToDateFunctionClass{baseFunctionClass{ast.StrToDate, 2, 2}}, 649 ast.SubTime: &subTimeFunctionClass{baseFunctionClass{ast.SubTime, 2, 2}}, 650 ast.Sysdate: &sysDateFunctionClass{baseFunctionClass{ast.Sysdate, 0, 1}}, 651 ast.Time: &timeFunctionClass{baseFunctionClass{ast.Time, 1, 1}}, 652 ast.TimeLiteral: &timeLiteralFunctionClass{baseFunctionClass{ast.TimeLiteral, 1, 1}}, 653 ast.TimeFormat: &timeFormatFunctionClass{baseFunctionClass{ast.TimeFormat, 2, 2}}, 654 ast.TimeToSec: &timeToSecFunctionClass{baseFunctionClass{ast.TimeToSec, 1, 1}}, 655 ast.TimeDiff: &timeDiffFunctionClass{baseFunctionClass{ast.TimeDiff, 2, 2}}, 656 ast.Timestamp: ×tampFunctionClass{baseFunctionClass{ast.Timestamp, 1, 2}}, 657 ast.TimestampLiteral: ×tampLiteralFunctionClass{baseFunctionClass{ast.TimestampLiteral, 1, 2}}, 658 ast.TimestampAdd: ×tampAddFunctionClass{baseFunctionClass{ast.TimestampAdd, 3, 3}}, 659 ast.TimestamFIDeliff: ×tamFIDeliffFunctionClass{baseFunctionClass{ast.TimestamFIDeliff, 3, 3}}, 660 ast.ToDays: &toDaysFunctionClass{baseFunctionClass{ast.ToDays, 1, 1}}, 661 ast.ToSeconds: &toSecondsFunctionClass{baseFunctionClass{ast.ToSeconds, 1, 1}}, 662 ast.UnixTimestamp: &unixTimestampFunctionClass{baseFunctionClass{ast.UnixTimestamp, 0, 1}}, 663 ast.UTCDate: &utcDateFunctionClass{baseFunctionClass{ast.UTCDate, 0, 0}}, 664 ast.UTCTime: &utcTimeFunctionClass{baseFunctionClass{ast.UTCTime, 0, 1}}, 665 ast.UTCTimestamp: &utcTimestampFunctionClass{baseFunctionClass{ast.UTCTimestamp, 0, 1}}, 666 ast.Week: &weekFunctionClass{baseFunctionClass{ast.Week, 1, 2}}, 667 ast.Weekday: &weekDayFunctionClass{baseFunctionClass{ast.Weekday, 1, 1}}, 668 ast.WeekOfYear: &weekOfYearFunctionClass{baseFunctionClass{ast.WeekOfYear, 1, 1}}, 669 ast.Year: &yearFunctionClass{baseFunctionClass{ast.Year, 1, 1}}, 670 ast.YearWeek: &yearWeekFunctionClass{baseFunctionClass{ast.YearWeek, 1, 2}}, 671 ast.LastDay: &lastDayFunctionClass{baseFunctionClass{ast.LastDay, 1, 1}}, 672 673 // string functions 674 ast.ASCII: &asciiFunctionClass{baseFunctionClass{ast.ASCII, 1, 1}}, 675 ast.Bin: &binFunctionClass{baseFunctionClass{ast.Bin, 1, 1}}, 676 ast.Concat: &concatFunctionClass{baseFunctionClass{ast.Concat, 1, -1}}, 677 ast.ConcatWS: &concatWSFunctionClass{baseFunctionClass{ast.ConcatWS, 2, -1}}, 678 ast.Convert: &convertFunctionClass{baseFunctionClass{ast.Convert, 2, 2}}, 679 ast.Elt: &eltFunctionClass{baseFunctionClass{ast.Elt, 2, -1}}, 680 ast.ExportSet: &exportSetFunctionClass{baseFunctionClass{ast.ExportSet, 3, 5}}, 681 ast.Field: &fieldFunctionClass{baseFunctionClass{ast.Field, 2, -1}}, 682 ast.Format: &formatFunctionClass{baseFunctionClass{ast.Format, 2, 3}}, 683 ast.FromBase64: &fromBase64FunctionClass{baseFunctionClass{ast.FromBase64, 1, 1}}, 684 ast.InsertFunc: &insertFunctionClass{baseFunctionClass{ast.InsertFunc, 4, 4}}, 685 ast.Instr: &instrFunctionClass{baseFunctionClass{ast.Instr, 2, 2}}, 686 ast.Lcase: &lowerFunctionClass{baseFunctionClass{ast.Lcase, 1, 1}}, 687 ast.Left: &leftFunctionClass{baseFunctionClass{ast.Left, 2, 2}}, 688 ast.Right: &rightFunctionClass{baseFunctionClass{ast.Right, 2, 2}}, 689 ast.Length: &lengthFunctionClass{baseFunctionClass{ast.Length, 1, 1}}, 690 ast.LoadFile: &loadFileFunctionClass{baseFunctionClass{ast.LoadFile, 1, 1}}, 691 ast.Locate: &locateFunctionClass{baseFunctionClass{ast.Locate, 2, 3}}, 692 ast.Lower: &lowerFunctionClass{baseFunctionClass{ast.Lower, 1, 1}}, 693 ast.Lpad: &lpadFunctionClass{baseFunctionClass{ast.Lpad, 3, 3}}, 694 ast.LTrim: &lTrimFunctionClass{baseFunctionClass{ast.LTrim, 1, 1}}, 695 ast.Mid: &substringFunctionClass{baseFunctionClass{ast.Mid, 3, 3}}, 696 ast.MakeSet: &makeSetFunctionClass{baseFunctionClass{ast.MakeSet, 2, -1}}, 697 ast.Oct: &octFunctionClass{baseFunctionClass{ast.Oct, 1, 1}}, 698 ast.OctetLength: &lengthFunctionClass{baseFunctionClass{ast.OctetLength, 1, 1}}, 699 ast.Ord: &ordFunctionClass{baseFunctionClass{ast.Ord, 1, 1}}, 700 ast.Position: &locateFunctionClass{baseFunctionClass{ast.Position, 2, 2}}, 701 ast.Quote: "eFunctionClass{baseFunctionClass{ast.Quote, 1, 1}}, 702 ast.Repeat: &repeatFunctionClass{baseFunctionClass{ast.Repeat, 2, 2}}, 703 ast.Replace: &replaceFunctionClass{baseFunctionClass{ast.Replace, 3, 3}}, 704 ast.Reverse: &reverseFunctionClass{baseFunctionClass{ast.Reverse, 1, 1}}, 705 ast.RTrim: &rTrimFunctionClass{baseFunctionClass{ast.RTrim, 1, 1}}, 706 ast.Space: &spaceFunctionClass{baseFunctionClass{ast.Space, 1, 1}}, 707 ast.Strcmp: &strcmpFunctionClass{baseFunctionClass{ast.Strcmp, 2, 2}}, 708 ast.Substring: &substringFunctionClass{baseFunctionClass{ast.Substring, 2, 3}}, 709 ast.Substr: &substringFunctionClass{baseFunctionClass{ast.Substr, 2, 3}}, 710 ast.SubstringIndex: &substringIndexFunctionClass{baseFunctionClass{ast.SubstringIndex, 3, 3}}, 711 ast.ToBase64: &toBase64FunctionClass{baseFunctionClass{ast.ToBase64, 1, 1}}, 712 ast.Trim: &trimFunctionClass{baseFunctionClass{ast.Trim, 1, 3}}, 713 ast.Upper: &upperFunctionClass{baseFunctionClass{ast.Upper, 1, 1}}, 714 ast.Ucase: &upperFunctionClass{baseFunctionClass{ast.Ucase, 1, 1}}, 715 ast.Hex: &hexFunctionClass{baseFunctionClass{ast.Hex, 1, 1}}, 716 ast.Unhex: &unhexFunctionClass{baseFunctionClass{ast.Unhex, 1, 1}}, 717 ast.Rpad: &rpadFunctionClass{baseFunctionClass{ast.Rpad, 3, 3}}, 718 ast.BitLength: &bitLengthFunctionClass{baseFunctionClass{ast.BitLength, 1, 1}}, 719 ast.CharFunc: &charFunctionClass{baseFunctionClass{ast.CharFunc, 2, -1}}, 720 ast.CharLength: &charLengthFunctionClass{baseFunctionClass{ast.CharLength, 1, 1}}, 721 ast.CharacterLength: &charLengthFunctionClass{baseFunctionClass{ast.CharacterLength, 1, 1}}, 722 ast.FindInSet: &findInSetFunctionClass{baseFunctionClass{ast.FindInSet, 2, 2}}, 723 ast.WeightString: &weightStringFunctionClass{baseFunctionClass{ast.WeightString, 1, 3}}, 724 725 // information functions 726 ast.ConnectionID: &connectionIDFunctionClass{baseFunctionClass{ast.ConnectionID, 0, 0}}, 727 ast.CurrentUser: ¤tUserFunctionClass{baseFunctionClass{ast.CurrentUser, 0, 0}}, 728 ast.CurrentRole: ¤tRoleFunctionClass{baseFunctionClass{ast.CurrentRole, 0, 0}}, 729 ast.Database: &databaseFunctionClass{baseFunctionClass{ast.Database, 0, 0}}, 730 // This function is a synonym for DATABASE(). 731 // See http://dev.allegrosql.com/doc/refman/5.7/en/information-functions.html#function_schema 732 ast.Schema: &databaseFunctionClass{baseFunctionClass{ast.Schema, 0, 0}}, 733 ast.FoundEvents: &foundEventsFunctionClass{baseFunctionClass{ast.FoundEvents, 0, 0}}, 734 ast.LastInsertId: &lastInsertIDFunctionClass{baseFunctionClass{ast.LastInsertId, 0, 1}}, 735 ast.User: &userFunctionClass{baseFunctionClass{ast.User, 0, 0}}, 736 ast.Version: &versionFunctionClass{baseFunctionClass{ast.Version, 0, 0}}, 737 ast.Benchmark: &benchmarkFunctionClass{baseFunctionClass{ast.Benchmark, 2, 2}}, 738 ast.Charset: &charsetFunctionClass{baseFunctionClass{ast.Charset, 1, 1}}, 739 ast.Coercibility: &coercibilityFunctionClass{baseFunctionClass{ast.Coercibility, 1, 1}}, 740 ast.DefCauslation: &defCauslationFunctionClass{baseFunctionClass{ast.DefCauslation, 1, 1}}, 741 ast.EventCount: &rowCountFunctionClass{baseFunctionClass{ast.EventCount, 0, 0}}, 742 ast.StochastikUser: &userFunctionClass{baseFunctionClass{ast.StochastikUser, 0, 0}}, 743 ast.SystemUser: &userFunctionClass{baseFunctionClass{ast.SystemUser, 0, 0}}, 744 745 // See https://dev.allegrosql.com/doc/refman/8.0/en/performance-schemaReplicant-functions.html 746 ast.FormatBytes: &formatBytesFunctionClass{baseFunctionClass{ast.FormatBytes, 1, 1}}, 747 ast.FormatNanoTime: &formatNanoTimeFunctionClass{baseFunctionClass{ast.FormatNanoTime, 1, 1}}, 748 749 // control functions 750 ast.If: &ifFunctionClass{baseFunctionClass{ast.If, 3, 3}}, 751 ast.Ifnull: &ifNullFunctionClass{baseFunctionClass{ast.Ifnull, 2, 2}}, 752 753 // miscellaneous functions 754 ast.Sleep: &sleepFunctionClass{baseFunctionClass{ast.Sleep, 1, 1}}, 755 ast.AnyValue: &anyValueFunctionClass{baseFunctionClass{ast.AnyValue, 1, 1}}, 756 ast.DefaultFunc: &defaultFunctionClass{baseFunctionClass{ast.DefaultFunc, 1, 1}}, 757 ast.InetAton: &inetAtonFunctionClass{baseFunctionClass{ast.InetAton, 1, 1}}, 758 ast.InetNtoa: &inetNtoaFunctionClass{baseFunctionClass{ast.InetNtoa, 1, 1}}, 759 ast.Inet6Aton: &inet6AtonFunctionClass{baseFunctionClass{ast.Inet6Aton, 1, 1}}, 760 ast.Inet6Ntoa: &inet6NtoaFunctionClass{baseFunctionClass{ast.Inet6Ntoa, 1, 1}}, 761 ast.IsFreeLock: &isFreeLockFunctionClass{baseFunctionClass{ast.IsFreeLock, 1, 1}}, 762 ast.IsIPv4: &isIPv4FunctionClass{baseFunctionClass{ast.IsIPv4, 1, 1}}, 763 ast.IsIPv4Compat: &isIPv4CompatFunctionClass{baseFunctionClass{ast.IsIPv4Compat, 1, 1}}, 764 ast.IsIPv4Mapped: &isIPv4MappedFunctionClass{baseFunctionClass{ast.IsIPv4Mapped, 1, 1}}, 765 ast.IsIPv6: &isIPv6FunctionClass{baseFunctionClass{ast.IsIPv6, 1, 1}}, 766 ast.IsUsedLock: &isUsedLockFunctionClass{baseFunctionClass{ast.IsUsedLock, 1, 1}}, 767 ast.MasterPosWait: &masterPosWaitFunctionClass{baseFunctionClass{ast.MasterPosWait, 2, 4}}, 768 ast.NameConst: &nameConstFunctionClass{baseFunctionClass{ast.NameConst, 2, 2}}, 769 ast.ReleaseAllLocks: &releaseAllLocksFunctionClass{baseFunctionClass{ast.ReleaseAllLocks, 0, 0}}, 770 ast.UUID: &uuidFunctionClass{baseFunctionClass{ast.UUID, 0, 0}}, 771 ast.UUIDShort: &uuidShortFunctionClass{baseFunctionClass{ast.UUIDShort, 0, 0}}, 772 773 // get_lock() and release_lock() are parsed but do nothing. 774 // It is used for preventing error in Ruby's activerecord migrations. 775 ast.GetLock: &lockFunctionClass{baseFunctionClass{ast.GetLock, 2, 2}}, 776 ast.ReleaseLock: &releaseLockFunctionClass{baseFunctionClass{ast.ReleaseLock, 1, 1}}, 777 778 ast.LogicAnd: &logicAndFunctionClass{baseFunctionClass{ast.LogicAnd, 2, 2}}, 779 ast.LogicOr: &logicOrFunctionClass{baseFunctionClass{ast.LogicOr, 2, 2}}, 780 ast.LogicXor: &logicXorFunctionClass{baseFunctionClass{ast.LogicXor, 2, 2}}, 781 ast.GE: &compareFunctionClass{baseFunctionClass{ast.GE, 2, 2}, opcode.GE}, 782 ast.LE: &compareFunctionClass{baseFunctionClass{ast.LE, 2, 2}, opcode.LE}, 783 ast.EQ: &compareFunctionClass{baseFunctionClass{ast.EQ, 2, 2}, opcode.EQ}, 784 ast.NE: &compareFunctionClass{baseFunctionClass{ast.NE, 2, 2}, opcode.NE}, 785 ast.LT: &compareFunctionClass{baseFunctionClass{ast.LT, 2, 2}, opcode.LT}, 786 ast.GT: &compareFunctionClass{baseFunctionClass{ast.GT, 2, 2}, opcode.GT}, 787 ast.NullEQ: &compareFunctionClass{baseFunctionClass{ast.NullEQ, 2, 2}, opcode.NullEQ}, 788 ast.Plus: &arithmeticPlusFunctionClass{baseFunctionClass{ast.Plus, 2, 2}}, 789 ast.Minus: &arithmeticMinusFunctionClass{baseFunctionClass{ast.Minus, 2, 2}}, 790 ast.Mod: &arithmeticModFunctionClass{baseFunctionClass{ast.Mod, 2, 2}}, 791 ast.Div: &arithmeticDivideFunctionClass{baseFunctionClass{ast.Div, 2, 2}}, 792 ast.Mul: &arithmeticMultiplyFunctionClass{baseFunctionClass{ast.Mul, 2, 2}}, 793 ast.IntDiv: &arithmeticIntDivideFunctionClass{baseFunctionClass{ast.IntDiv, 2, 2}}, 794 ast.BitNeg: &bitNegFunctionClass{baseFunctionClass{ast.BitNeg, 1, 1}}, 795 ast.And: &bitAndFunctionClass{baseFunctionClass{ast.And, 2, 2}}, 796 ast.LeftShift: &leftShiftFunctionClass{baseFunctionClass{ast.LeftShift, 2, 2}}, 797 ast.RightShift: &rightShiftFunctionClass{baseFunctionClass{ast.RightShift, 2, 2}}, 798 ast.UnaryNot: &unaryNotFunctionClass{baseFunctionClass{ast.UnaryNot, 1, 1}}, 799 ast.Or: &bitOrFunctionClass{baseFunctionClass{ast.Or, 2, 2}}, 800 ast.Xor: &bitXorFunctionClass{baseFunctionClass{ast.Xor, 2, 2}}, 801 ast.UnaryMinus: &unaryMinusFunctionClass{baseFunctionClass{ast.UnaryMinus, 1, 1}}, 802 ast.In: &inFunctionClass{baseFunctionClass{ast.In, 2, -1}}, 803 ast.IsTruthWithoutNull: &isTrueOrFalseFunctionClass{baseFunctionClass{ast.IsTruthWithoutNull, 1, 1}, opcode.IsTruth, false}, 804 ast.IsTruthWithNull: &isTrueOrFalseFunctionClass{baseFunctionClass{ast.IsTruthWithNull, 1, 1}, opcode.IsTruth, true}, 805 ast.IsFalsity: &isTrueOrFalseFunctionClass{baseFunctionClass{ast.IsFalsity, 1, 1}, opcode.IsFalsity, false}, 806 ast.Like: &likeFunctionClass{baseFunctionClass{ast.Like, 3, 3}}, 807 ast.Regexp: ®expFunctionClass{baseFunctionClass{ast.Regexp, 2, 2}}, 808 ast.Case: &caseWhenFunctionClass{baseFunctionClass{ast.Case, 1, -1}}, 809 ast.EventFunc: &rowFunctionClass{baseFunctionClass{ast.EventFunc, 2, -1}}, 810 ast.SetVar: &setVarFunctionClass{baseFunctionClass{ast.SetVar, 2, 2}}, 811 ast.GetVar: &getVarFunctionClass{baseFunctionClass{ast.GetVar, 1, 1}}, 812 ast.BitCount: &bitCountFunctionClass{baseFunctionClass{ast.BitCount, 1, 1}}, 813 ast.GetParam: &getParamFunctionClass{baseFunctionClass{ast.GetParam, 1, 1}}, 814 815 // encryption and compression functions 816 ast.AesDecrypt: &aesDecryptFunctionClass{baseFunctionClass{ast.AesDecrypt, 2, 3}}, 817 ast.AesEncrypt: &aesEncryptFunctionClass{baseFunctionClass{ast.AesEncrypt, 2, 3}}, 818 ast.Compress: &compressFunctionClass{baseFunctionClass{ast.Compress, 1, 1}}, 819 ast.Decode: &decodeFunctionClass{baseFunctionClass{ast.Decode, 2, 2}}, 820 ast.DesDecrypt: &desDecryptFunctionClass{baseFunctionClass{ast.DesDecrypt, 1, 2}}, 821 ast.DesEncrypt: &desEncryptFunctionClass{baseFunctionClass{ast.DesEncrypt, 1, 2}}, 822 ast.Encode: &encodeFunctionClass{baseFunctionClass{ast.Encode, 2, 2}}, 823 ast.Encrypt: &encryptFunctionClass{baseFunctionClass{ast.Encrypt, 1, 2}}, 824 ast.MD5: &md5FunctionClass{baseFunctionClass{ast.MD5, 1, 1}}, 825 ast.OldPassword: &oldPasswordFunctionClass{baseFunctionClass{ast.OldPassword, 1, 1}}, 826 ast.PasswordFunc: &passwordFunctionClass{baseFunctionClass{ast.PasswordFunc, 1, 1}}, 827 ast.RandomBytes: &randomBytesFunctionClass{baseFunctionClass{ast.RandomBytes, 1, 1}}, 828 ast.SHA1: &sha1FunctionClass{baseFunctionClass{ast.SHA1, 1, 1}}, 829 ast.SHA: &sha1FunctionClass{baseFunctionClass{ast.SHA, 1, 1}}, 830 ast.SHA2: &sha2FunctionClass{baseFunctionClass{ast.SHA2, 2, 2}}, 831 ast.Uncompress: &uncompressFunctionClass{baseFunctionClass{ast.Uncompress, 1, 1}}, 832 ast.UncompressedLength: &uncompressedLengthFunctionClass{baseFunctionClass{ast.UncompressedLength, 1, 1}}, 833 ast.ValidatePasswordStrength: &validatePasswordStrengthFunctionClass{baseFunctionClass{ast.ValidatePasswordStrength, 1, 1}}, 834 835 // json functions 836 ast.JSONType: &jsonTypeFunctionClass{baseFunctionClass{ast.JSONType, 1, 1}}, 837 ast.JSONExtract: &jsonExtractFunctionClass{baseFunctionClass{ast.JSONExtract, 2, -1}}, 838 ast.JSONUnquote: &jsonUnquoteFunctionClass{baseFunctionClass{ast.JSONUnquote, 1, 1}}, 839 ast.JSONSet: &jsonSetFunctionClass{baseFunctionClass{ast.JSONSet, 3, -1}}, 840 ast.JSONInsert: &jsonInsertFunctionClass{baseFunctionClass{ast.JSONInsert, 3, -1}}, 841 ast.JSONReplace: &jsonReplaceFunctionClass{baseFunctionClass{ast.JSONReplace, 3, -1}}, 842 ast.JSONRemove: &jsonRemoveFunctionClass{baseFunctionClass{ast.JSONRemove, 2, -1}}, 843 ast.JSONMerge: &jsonMergeFunctionClass{baseFunctionClass{ast.JSONMerge, 2, -1}}, 844 ast.JSONObject: &jsonObjectFunctionClass{baseFunctionClass{ast.JSONObject, 0, -1}}, 845 ast.JSONArray: &jsonArrayFunctionClass{baseFunctionClass{ast.JSONArray, 0, -1}}, 846 ast.JSONContains: &jsonContainsFunctionClass{baseFunctionClass{ast.JSONContains, 2, 3}}, 847 ast.JSONContainsPath: &jsonContainsPathFunctionClass{baseFunctionClass{ast.JSONContainsPath, 3, -1}}, 848 ast.JSONValid: &jsonValidFunctionClass{baseFunctionClass{ast.JSONValid, 1, 1}}, 849 ast.JSONArrayAppend: &jsonArrayAppendFunctionClass{baseFunctionClass{ast.JSONArrayAppend, 3, -1}}, 850 ast.JSONArrayInsert: &jsonArrayInsertFunctionClass{baseFunctionClass{ast.JSONArrayInsert, 3, -1}}, 851 ast.JSONMergePatch: &jsonMergePatchFunctionClass{baseFunctionClass{ast.JSONMergePatch, 2, -1}}, 852 ast.JSONMergePreserve: &jsonMergePreserveFunctionClass{baseFunctionClass{ast.JSONMergePreserve, 2, -1}}, 853 ast.JSONPretty: &jsonPrettyFunctionClass{baseFunctionClass{ast.JSONPretty, 1, 1}}, 854 ast.JSONQuote: &jsonQuoteFunctionClass{baseFunctionClass{ast.JSONQuote, 1, 1}}, 855 ast.JSONSearch: &jsonSearchFunctionClass{baseFunctionClass{ast.JSONSearch, 3, -1}}, 856 ast.JSONStorageSize: &jsonStorageSizeFunctionClass{baseFunctionClass{ast.JSONStorageSize, 1, 1}}, 857 ast.JSONDepth: &jsonDepthFunctionClass{baseFunctionClass{ast.JSONDepth, 1, 1}}, 858 ast.JSONKeys: &jsonKeysFunctionClass{baseFunctionClass{ast.JSONKeys, 1, 2}}, 859 ast.JSONLength: &jsonLengthFunctionClass{baseFunctionClass{ast.JSONLength, 1, 2}}, 860 861 // MilevaDB internal function. 862 ast.MilevaDBDecodeKey: &milevadbDecodeKeyFunctionClass{baseFunctionClass{ast.MilevaDBDecodeKey, 1, 1}}, 863 // This function is used to show milevadb-server version info. 864 ast.MilevaDBVersion: &milevadbVersionFunctionClass{baseFunctionClass{ast.MilevaDBVersion, 0, 0}}, 865 ast.MilevaDBIsDBSTenant: &milevadbIsDBSTenantFunctionClass{baseFunctionClass{ast.MilevaDBIsDBSTenant, 0, 0}}, 866 ast.MilevaDBParseTso: &milevadbParseTsoFunctionClass{baseFunctionClass{ast.MilevaDBParseTso, 1, 1}}, 867 ast.MilevaDBDecodeCauset: &milevadbDecodeCausetFunctionClass{baseFunctionClass{ast.MilevaDBDecodeCauset, 1, 1}}, 868 869 // MilevaDB Sequence function. 870 ast.NextVal: &nextValFunctionClass{baseFunctionClass{ast.NextVal, 1, 1}}, 871 ast.LastVal: &lastValFunctionClass{baseFunctionClass{ast.LastVal, 1, 1}}, 872 ast.SetVal: &setValFunctionClass{baseFunctionClass{ast.SetVal, 2, 2}}, 873 } 874 875 // IsFunctionSupported check if given function name is a builtin allegrosql function. 876 func IsFunctionSupported(name string) bool { 877 _, ok := funcs[name] 878 return ok 879 } 880 881 // GetBuiltinList returns a list of builtin functions 882 func GetBuiltinList() []string { 883 res := make([]string, 0, len(funcs)) 884 notImplementedFunctions := []string{ast.EventFunc, ast.IsTruthWithNull} 885 for funcName := range funcs { 886 skipFunc := false 887 // Skip not implemented functions 888 for _, notImplFunc := range notImplementedFunctions { 889 if funcName == notImplFunc { 890 skipFunc = true 891 } 892 } 893 // Skip literal functions 894 // (their names are not readable: 'milevadb`.(dateliteral, for example) 895 // See: https://github.com/whtcorpsinc/BerolinaSQL/pull/591 896 if strings.HasPrefix(funcName, "'milevadb`.(") { 897 skipFunc = true 898 } 899 if skipFunc { 900 continue 901 } 902 res = append(res, funcName) 903 } 904 sort.Strings(res) 905 return res 906 }