1 Star 0 Fork 0

zhoujin826/tidb

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
distsql_builtin.go 22.25 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
// Copyright 2017 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package expression
import (
"fmt"
"time"
"github.com/juju/errors"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/util/codec"
"github.com/pingcap/tidb/util/mock"
"github.com/pingcap/tidb/util/types"
"github.com/pingcap/tipb/go-tipb"
)
var distFuncs = map[tipb.ExprType]string{
// compare op
tipb.ExprType_LT: ast.LT,
tipb.ExprType_LE: ast.LE,
tipb.ExprType_GT: ast.GT,
tipb.ExprType_GE: ast.GE,
tipb.ExprType_EQ: ast.EQ,
tipb.ExprType_NE: ast.NE,
tipb.ExprType_NullEQ: ast.NullEQ,
// bit op
tipb.ExprType_BitAnd: ast.And,
tipb.ExprType_BitOr: ast.Or,
tipb.ExprType_BitXor: ast.Xor,
tipb.ExprType_RighShift: ast.RightShift,
tipb.ExprType_LeftShift: ast.LeftShift,
tipb.ExprType_BitNeg: ast.BitNeg,
// logical op
tipb.ExprType_And: ast.LogicAnd,
tipb.ExprType_Or: ast.LogicOr,
tipb.ExprType_Xor: ast.LogicXor,
tipb.ExprType_Not: ast.UnaryNot,
// arithmetic operator
tipb.ExprType_Plus: ast.Plus,
tipb.ExprType_Minus: ast.Minus,
tipb.ExprType_Mul: ast.Mul,
tipb.ExprType_Div: ast.Div,
tipb.ExprType_IntDiv: ast.IntDiv,
tipb.ExprType_Mod: ast.Mod,
// control operator
tipb.ExprType_Case: ast.Case,
tipb.ExprType_If: ast.If,
tipb.ExprType_IfNull: ast.Ifnull,
tipb.ExprType_NullIf: ast.Nullif,
// other operator
tipb.ExprType_Like: ast.Like,
tipb.ExprType_In: ast.In,
tipb.ExprType_IsNull: ast.IsNull,
tipb.ExprType_Coalesce: ast.Coalesce,
// for json functions.
tipb.ExprType_JsonType: ast.JSONType,
tipb.ExprType_JsonExtract: ast.JSONExtract,
tipb.ExprType_JsonUnquote: ast.JSONUnquote,
tipb.ExprType_JsonMerge: ast.JSONMerge,
tipb.ExprType_JsonSet: ast.JSONSet,
tipb.ExprType_JsonInsert: ast.JSONInsert,
tipb.ExprType_JsonReplace: ast.JSONReplace,
tipb.ExprType_JsonRemove: ast.JSONRemove,
tipb.ExprType_JsonArray: ast.JSONArray,
tipb.ExprType_JsonObject: ast.JSONObject,
}
func pbTypeToFieldType(tp *tipb.FieldType) *types.FieldType {
return &types.FieldType{
Tp: byte(tp.Tp),
Flag: uint(tp.Flag),
Flen: int(tp.Flen),
Decimal: int(tp.Decimal),
Charset: tp.Charset,
Collate: mysql.Collations[uint8(tp.Collate)],
}
}
func getSignatureByPB(ctx context.Context, sigCode tipb.ScalarFuncSig, tp *tipb.FieldType, args []Expression) (f builtinFunc, e error) {
fieldTp := pbTypeToFieldType(tp)
base := newBaseBuiltinFunc(ctx, args)
base.tp = fieldTp
switch sigCode {
case tipb.ScalarFuncSig_CastIntAsInt:
f = &builtinCastIntAsIntSig{base}
case tipb.ScalarFuncSig_CastRealAsInt:
f = &builtinCastRealAsIntSig{base}
case tipb.ScalarFuncSig_CastDecimalAsInt:
f = &builtinCastDecimalAsIntSig{base}
case tipb.ScalarFuncSig_CastDurationAsInt:
f = &builtinCastDurationAsIntSig{base}
case tipb.ScalarFuncSig_CastTimeAsInt:
f = &builtinCastTimeAsIntSig{base}
case tipb.ScalarFuncSig_CastStringAsInt:
f = &builtinCastStringAsIntSig{base}
case tipb.ScalarFuncSig_CastJsonAsInt:
f = &builtinCastJSONAsIntSig{base}
case tipb.ScalarFuncSig_CastIntAsReal:
f = &builtinCastIntAsRealSig{base}
case tipb.ScalarFuncSig_CastRealAsReal:
f = &builtinCastRealAsRealSig{base}
case tipb.ScalarFuncSig_CastDecimalAsReal:
f = &builtinCastDecimalAsRealSig{base}
case tipb.ScalarFuncSig_CastDurationAsReal:
f = &builtinCastDurationAsRealSig{base}
case tipb.ScalarFuncSig_CastTimeAsReal:
f = &builtinCastTimeAsRealSig{base}
case tipb.ScalarFuncSig_CastStringAsReal:
f = &builtinCastStringAsRealSig{base}
case tipb.ScalarFuncSig_CastJsonAsReal:
f = &builtinCastJSONAsRealSig{base}
case tipb.ScalarFuncSig_CastIntAsDecimal:
f = &builtinCastIntAsDecimalSig{base}
case tipb.ScalarFuncSig_CastRealAsDecimal:
f = &builtinCastRealAsDecimalSig{base}
case tipb.ScalarFuncSig_CastDecimalAsDecimal:
f = &builtinCastDecimalAsDecimalSig{base}
case tipb.ScalarFuncSig_CastDurationAsDecimal:
f = &builtinCastDurationAsDecimalSig{base}
case tipb.ScalarFuncSig_CastTimeAsDecimal:
f = &builtinCastTimeAsDecimalSig{base}
case tipb.ScalarFuncSig_CastStringAsDecimal:
f = &builtinCastStringAsDecimalSig{base}
case tipb.ScalarFuncSig_CastJsonAsDecimal:
f = &builtinCastJSONAsDecimalSig{base}
case tipb.ScalarFuncSig_CastIntAsTime:
f = &builtinCastIntAsTimeSig{base}
case tipb.ScalarFuncSig_CastRealAsTime:
f = &builtinCastRealAsTimeSig{base}
case tipb.ScalarFuncSig_CastDecimalAsTime:
f = &builtinCastDecimalAsTimeSig{base}
case tipb.ScalarFuncSig_CastDurationAsTime:
f = &builtinCastDurationAsTimeSig{base}
case tipb.ScalarFuncSig_CastTimeAsTime:
f = &builtinCastTimeAsTimeSig{base}
case tipb.ScalarFuncSig_CastStringAsTime:
f = &builtinCastStringAsTimeSig{base}
case tipb.ScalarFuncSig_CastJsonAsTime:
f = &builtinCastJSONAsTimeSig{base}
case tipb.ScalarFuncSig_CastIntAsString:
f = &builtinCastIntAsStringSig{base}
case tipb.ScalarFuncSig_CastRealAsString:
f = &builtinCastRealAsStringSig{base}
case tipb.ScalarFuncSig_CastDecimalAsString:
f = &builtinCastDecimalAsStringSig{base}
case tipb.ScalarFuncSig_CastDurationAsString:
f = &builtinCastDurationAsStringSig{base}
case tipb.ScalarFuncSig_CastTimeAsString:
f = &builtinCastTimeAsStringSig{base}
case tipb.ScalarFuncSig_CastStringAsString:
f = &builtinCastStringAsStringSig{base}
case tipb.ScalarFuncSig_CastJsonAsString:
f = &builtinCastJSONAsStringSig{base}
case tipb.ScalarFuncSig_CastIntAsDuration:
f = &builtinCastIntAsDurationSig{base}
case tipb.ScalarFuncSig_CastRealAsDuration:
f = &builtinCastRealAsDurationSig{base}
case tipb.ScalarFuncSig_CastDecimalAsDuration:
f = &builtinCastDecimalAsDurationSig{base}
case tipb.ScalarFuncSig_CastDurationAsDuration:
f = &builtinCastDurationAsDurationSig{base}
case tipb.ScalarFuncSig_CastTimeAsDuration:
f = &builtinCastTimeAsDurationSig{base}
case tipb.ScalarFuncSig_CastStringAsDuration:
f = &builtinCastStringAsDurationSig{base}
case tipb.ScalarFuncSig_CastJsonAsDuration:
f = &builtinCastJSONAsDurationSig{base}
case tipb.ScalarFuncSig_CastIntAsJson:
f = &builtinCastIntAsJSONSig{base}
case tipb.ScalarFuncSig_CastRealAsJson:
f = &builtinCastRealAsJSONSig{base}
case tipb.ScalarFuncSig_CastDecimalAsJson:
f = &builtinCastDecimalAsJSONSig{base}
case tipb.ScalarFuncSig_CastTimeAsJson:
f = &builtinCastTimeAsJSONSig{base}
case tipb.ScalarFuncSig_CastDurationAsJson:
f = &builtinCastDurationAsJSONSig{base}
case tipb.ScalarFuncSig_CastStringAsJson:
f = &builtinCastStringAsJSONSig{base}
case tipb.ScalarFuncSig_CastJsonAsJson:
f = &builtinCastJSONAsJSONSig{base}
case tipb.ScalarFuncSig_GTInt:
f = &builtinGTIntSig{base}
case tipb.ScalarFuncSig_GEInt:
f = &builtinGEIntSig{base}
case tipb.ScalarFuncSig_LTInt:
f = &builtinLTIntSig{base}
case tipb.ScalarFuncSig_LEInt:
f = &builtinLEIntSig{base}
case tipb.ScalarFuncSig_EQInt:
f = &builtinEQIntSig{base}
case tipb.ScalarFuncSig_NEInt:
f = &builtinNEIntSig{base}
case tipb.ScalarFuncSig_NullEQInt:
f = &builtinNullEQIntSig{base}
case tipb.ScalarFuncSig_GTReal:
f = &builtinGTRealSig{base}
case tipb.ScalarFuncSig_GEReal:
f = &builtinGERealSig{base}
case tipb.ScalarFuncSig_LTReal:
f = &builtinLTRealSig{base}
case tipb.ScalarFuncSig_LEReal:
f = &builtinLERealSig{base}
case tipb.ScalarFuncSig_EQReal:
f = &builtinEQRealSig{base}
case tipb.ScalarFuncSig_NEReal:
f = &builtinNERealSig{base}
case tipb.ScalarFuncSig_NullEQReal:
f = &builtinNullEQRealSig{base}
case tipb.ScalarFuncSig_GTDecimal:
f = &builtinGTDecimalSig{base}
case tipb.ScalarFuncSig_GEDecimal:
f = &builtinGEDecimalSig{base}
case tipb.ScalarFuncSig_LTDecimal:
f = &builtinLTDecimalSig{base}
case tipb.ScalarFuncSig_LEDecimal:
f = &builtinLEDecimalSig{base}
case tipb.ScalarFuncSig_EQDecimal:
f = &builtinEQDecimalSig{base}
case tipb.ScalarFuncSig_NEDecimal:
f = &builtinNEDecimalSig{base}
case tipb.ScalarFuncSig_NullEQDecimal:
f = &builtinNullEQDecimalSig{base}
case tipb.ScalarFuncSig_GTTime:
f = &builtinGTTimeSig{base}
case tipb.ScalarFuncSig_GETime:
f = &builtinGETimeSig{base}
case tipb.ScalarFuncSig_LTTime:
f = &builtinLTTimeSig{base}
case tipb.ScalarFuncSig_LETime:
f = &builtinLETimeSig{base}
case tipb.ScalarFuncSig_EQTime:
f = &builtinEQTimeSig{base}
case tipb.ScalarFuncSig_NETime:
f = &builtinNETimeSig{base}
case tipb.ScalarFuncSig_NullEQTime:
f = &builtinNullEQTimeSig{base}
case tipb.ScalarFuncSig_GTDuration:
f = &builtinGTDurationSig{base}
case tipb.ScalarFuncSig_GEDuration:
f = &builtinGEDurationSig{base}
case tipb.ScalarFuncSig_LTDuration:
f = &builtinLTDurationSig{base}
case tipb.ScalarFuncSig_LEDuration:
f = &builtinLEDurationSig{base}
case tipb.ScalarFuncSig_EQDuration:
f = &builtinEQDurationSig{base}
case tipb.ScalarFuncSig_NEDuration:
f = &builtinNEDurationSig{base}
case tipb.ScalarFuncSig_NullEQDuration:
f = &builtinNullEQDurationSig{base}
case tipb.ScalarFuncSig_GTString:
f = &builtinGTStringSig{base}
case tipb.ScalarFuncSig_GEString:
f = &builtinGEStringSig{base}
case tipb.ScalarFuncSig_LTString:
f = &builtinLTStringSig{base}
case tipb.ScalarFuncSig_LEString:
f = &builtinLEStringSig{base}
case tipb.ScalarFuncSig_EQString:
f = &builtinEQStringSig{base}
case tipb.ScalarFuncSig_NEString:
f = &builtinNEStringSig{base}
case tipb.ScalarFuncSig_NullEQString:
f = &builtinNullEQStringSig{base}
case tipb.ScalarFuncSig_GTJson:
f = &builtinGTJSONSig{base}
case tipb.ScalarFuncSig_GEJson:
f = &builtinGEJSONSig{base}
case tipb.ScalarFuncSig_LTJson:
f = &builtinLTJSONSig{base}
case tipb.ScalarFuncSig_LEJson:
f = &builtinLEJSONSig{base}
case tipb.ScalarFuncSig_EQJson:
f = &builtinEQJSONSig{base}
case tipb.ScalarFuncSig_NEJson:
f = &builtinNEJSONSig{base}
case tipb.ScalarFuncSig_NullEQJson:
f = &builtinNullEQJSONSig{base}
case tipb.ScalarFuncSig_PlusInt:
f = &builtinArithmeticPlusIntSig{base}
case tipb.ScalarFuncSig_PlusDecimal:
f = &builtinArithmeticPlusDecimalSig{base}
case tipb.ScalarFuncSig_PlusReal:
f = &builtinArithmeticPlusRealSig{base}
case tipb.ScalarFuncSig_MinusInt:
f = &builtinArithmeticMinusIntSig{base}
case tipb.ScalarFuncSig_MinusDecimal:
f = &builtinArithmeticMinusDecimalSig{base}
case tipb.ScalarFuncSig_MinusReal:
f = &builtinArithmeticMinusRealSig{base}
case tipb.ScalarFuncSig_MultiplyInt:
f = &builtinArithmeticMultiplyIntSig{base}
case tipb.ScalarFuncSig_MultiplyDecimal:
f = &builtinArithmeticMultiplyDecimalSig{base}
case tipb.ScalarFuncSig_MultiplyReal:
f = &builtinArithmeticMultiplyRealSig{base}
case tipb.ScalarFuncSig_DivideDecimal:
f = &builtinArithmeticDivideDecimalSig{base}
case tipb.ScalarFuncSig_DivideReal:
f = &builtinArithmeticDivideRealSig{base}
case tipb.ScalarFuncSig_AbsInt:
f = &builtinAbsIntSig{base}
case tipb.ScalarFuncSig_AbsReal:
f = &builtinAbsRealSig{base}
case tipb.ScalarFuncSig_AbsDecimal:
f = &builtinAbsDecSig{base}
case tipb.ScalarFuncSig_CeilIntToInt:
f = &builtinCeilIntToIntSig{base}
case tipb.ScalarFuncSig_CeilIntToDec:
f = &builtinCeilIntToDecSig{base}
case tipb.ScalarFuncSig_CeilDecToInt:
f = &builtinCeilDecToIntSig{base}
case tipb.ScalarFuncSig_CeilReal:
f = &builtinCeilRealSig{base}
case tipb.ScalarFuncSig_FloorIntToInt:
f = &builtinFloorIntToIntSig{base}
case tipb.ScalarFuncSig_FloorIntToDec:
f = &builtinFloorIntToDecSig{base}
case tipb.ScalarFuncSig_FloorDecToInt:
f = &builtinFloorDecToIntSig{base}
case tipb.ScalarFuncSig_FloorReal:
f = &builtinFloorRealSig{base}
case tipb.ScalarFuncSig_LogicalAnd:
f = &builtinLogicAndSig{base}
case tipb.ScalarFuncSig_LogicalOr:
f = &builtinLogicOrSig{base}
case tipb.ScalarFuncSig_LogicalXor:
f = &builtinLogicXorSig{base}
case tipb.ScalarFuncSig_BitAndSig:
f = &builtinBitAndSig{base}
case tipb.ScalarFuncSig_BitOrSig:
f = &builtinBitOrSig{base}
case tipb.ScalarFuncSig_BitXorSig:
f = &builtinBitXorSig{base}
case tipb.ScalarFuncSig_BitNegSig:
f = &builtinBitNegSig{base}
case tipb.ScalarFuncSig_UnaryNot:
f = &builtinUnaryNotSig{base}
case tipb.ScalarFuncSig_UnaryMinusInt:
f = &builtinUnaryMinusIntSig{base}
case tipb.ScalarFuncSig_UnaryMinusReal:
f = &builtinUnaryMinusRealSig{base}
case tipb.ScalarFuncSig_UnaryMinusDecimal:
f = &builtinUnaryMinusDecimalSig{base, false}
case tipb.ScalarFuncSig_DecimalIsNull:
f = &builtinDecimalIsNullSig{base}
case tipb.ScalarFuncSig_DurationIsNull:
f = &builtinDurationIsNullSig{base}
case tipb.ScalarFuncSig_RealIsNull:
f = &builtinRealIsNullSig{base}
case tipb.ScalarFuncSig_TimeIsNull:
f = &builtinTimeIsNullSig{base}
case tipb.ScalarFuncSig_StringIsNull:
f = &builtinStringIsNullSig{base}
case tipb.ScalarFuncSig_IntIsNull:
f = &builtinIntIsNullSig{base}
case tipb.ScalarFuncSig_CoalesceDecimal:
f = &builtinCoalesceDecimalSig{base}
case tipb.ScalarFuncSig_CoalesceDuration:
f = &builtinCoalesceDurationSig{base}
case tipb.ScalarFuncSig_CoalesceReal:
f = &builtinCoalesceRealSig{base}
case tipb.ScalarFuncSig_CoalesceTime:
f = &builtinCoalesceTimeSig{base}
case tipb.ScalarFuncSig_CoalesceString:
f = &builtinCoalesceStringSig{base}
case tipb.ScalarFuncSig_CoalesceInt:
f = &builtinCoalesceIntSig{base}
case tipb.ScalarFuncSig_CaseWhenDecimal:
f = &builtinCaseWhenDecimalSig{base}
case tipb.ScalarFuncSig_CaseWhenDuration:
f = &builtinCaseWhenDurationSig{base}
case tipb.ScalarFuncSig_CaseWhenReal:
f = &builtinCaseWhenRealSig{base}
case tipb.ScalarFuncSig_CaseWhenTime:
f = &builtinCaseWhenTimeSig{base}
case tipb.ScalarFuncSig_CaseWhenString:
f = &builtinCaseWhenStringSig{base}
case tipb.ScalarFuncSig_CaseWhenInt:
f = &builtinCaseWhenIntSig{base}
case tipb.ScalarFuncSig_IntIsFalse:
f = &builtinIntIsFalseSig{base}
case tipb.ScalarFuncSig_RealIsFalse:
f = &builtinRealIsFalseSig{base}
case tipb.ScalarFuncSig_DecimalIsFalse:
f = &builtinDecimalIsFalseSig{base}
case tipb.ScalarFuncSig_IntIsTrue:
f = &builtinIntIsTrueSig{base}
case tipb.ScalarFuncSig_RealIsTrue:
f = &builtinRealIsTrueSig{base}
case tipb.ScalarFuncSig_DecimalIsTrue:
f = &builtinDecimalIsTrueSig{base}
case tipb.ScalarFuncSig_IfNullReal:
f = &builtinIfNullRealSig{base}
case tipb.ScalarFuncSig_IfNullInt:
f = &builtinIfNullIntSig{base}
case tipb.ScalarFuncSig_IfNullDecimal:
f = &builtinIfNullDecimalSig{base}
case tipb.ScalarFuncSig_IfNullString:
f = &builtinIfNullStringSig{base}
case tipb.ScalarFuncSig_IfNullTime:
f = &builtinIfNullTimeSig{base}
case tipb.ScalarFuncSig_IfNullDuration:
f = &builtinIfNullDurationSig{base}
case tipb.ScalarFuncSig_IfNullJson:
f = &builtinIfNullJSONSig{base}
case tipb.ScalarFuncSig_IfReal:
f = &builtinIfRealSig{base}
case tipb.ScalarFuncSig_IfInt:
f = &builtinIfIntSig{base}
case tipb.ScalarFuncSig_IfDecimal:
f = &builtinIfDecimalSig{base}
case tipb.ScalarFuncSig_IfString:
f = &builtinIfStringSig{base}
case tipb.ScalarFuncSig_IfTime:
f = &builtinIfTimeSig{base}
case tipb.ScalarFuncSig_IfDuration:
f = &builtinIfDurationSig{base}
case tipb.ScalarFuncSig_IfJson:
f = &builtinIfJSONSig{base}
case tipb.ScalarFuncSig_JsonTypeSig:
f = &builtinJSONTypeSig{base}
case tipb.ScalarFuncSig_JsonUnquoteSig:
f = &builtinJSONUnquoteSig{base}
case tipb.ScalarFuncSig_JsonArraySig:
f = &builtinJSONArraySig{base}
case tipb.ScalarFuncSig_JsonObjectSig:
f = &builtinJSONObjectSig{base}
case tipb.ScalarFuncSig_JsonExtractSig:
f = &builtinJSONExtractSig{base}
case tipb.ScalarFuncSig_JsonSetSig:
f = &builtinJSONSetSig{base}
case tipb.ScalarFuncSig_JsonInsertSig:
f = &builtinJSONInsertSig{base}
case tipb.ScalarFuncSig_JsonReplaceSig:
f = &builtinJSONReplaceSig{base}
case tipb.ScalarFuncSig_JsonRemoveSig:
f = &builtinJSONRemoveSig{base}
case tipb.ScalarFuncSig_JsonMergeSig:
f = &builtinJSONMergeSig{base}
case tipb.ScalarFuncSig_LikeSig:
f = &builtinLikeSig{base}
case tipb.ScalarFuncSig_InInt:
f = &builtinInIntSig{base}
case tipb.ScalarFuncSig_InReal:
f = &builtinInRealSig{base}
case tipb.ScalarFuncSig_InDecimal:
f = &builtinInDecimalSig{base}
case tipb.ScalarFuncSig_InString:
f = &builtinInStringSig{base}
case tipb.ScalarFuncSig_InTime:
f = &builtinInTimeSig{base}
case tipb.ScalarFuncSig_InDuration:
f = &builtinInDurationSig{base}
case tipb.ScalarFuncSig_InJson:
f = &builtinInJSONSig{base}
default:
e = errFunctionNotExists.GenByArgs("FUNCTION", sigCode)
return nil, errors.Trace(e)
}
return f, nil
}
func newDistSQLFunctionBySig(sc *variable.StatementContext, sigCode tipb.ScalarFuncSig, tp *tipb.FieldType, args []Expression) (Expression, error) {
ctx := mock.NewContext()
ctx.GetSessionVars().StmtCtx = sc
f, err := getSignatureByPB(ctx, sigCode, tp, args)
if err != nil {
return nil, errors.Trace(err)
}
return &ScalarFunction{
FuncName: model.NewCIStr(fmt.Sprintf("sig_%T", f)),
Function: f,
RetType: f.getRetTp(),
}, nil
}
// newDistSQLFunction only creates function for mock-tikv.
func newDistSQLFunction(sc *variable.StatementContext, exprType tipb.ExprType, args []Expression) (Expression, error) {
name, ok := distFuncs[exprType]
if !ok {
return nil, errFunctionNotExists.GenByArgs("FUNCTION", exprType)
}
// TODO: Too ugly...
ctx := mock.NewContext()
ctx.GetSessionVars().StmtCtx = sc
return NewFunction(ctx, name, types.NewFieldType(mysql.TypeUnspecified), args...)
}
// PBToExpr converts pb structure to expression.
func PBToExpr(expr *tipb.Expr, tps []*types.FieldType, sc *variable.StatementContext) (Expression, error) {
switch expr.Tp {
case tipb.ExprType_ColumnRef:
_, offset, err := codec.DecodeInt(expr.Val)
if err != nil {
return nil, errors.Trace(err)
}
return &Column{Index: int(offset), RetType: tps[offset]}, nil
case tipb.ExprType_Null:
return &Constant{Value: types.Datum{}, RetType: types.NewFieldType(mysql.TypeNull)}, nil
case tipb.ExprType_Int64:
return convertInt(expr.Val)
case tipb.ExprType_Uint64:
return convertUint(expr.Val)
case tipb.ExprType_String:
return convertString(expr.Val)
case tipb.ExprType_Bytes:
return &Constant{Value: types.NewBytesDatum(expr.Val), RetType: types.NewFieldType(mysql.TypeString)}, nil
case tipb.ExprType_Float32:
return convertFloat(expr.Val, true)
case tipb.ExprType_Float64:
return convertFloat(expr.Val, false)
case tipb.ExprType_MysqlDecimal:
return convertDecimal(expr.Val)
case tipb.ExprType_MysqlDuration:
return convertDuration(expr.Val)
case tipb.ExprType_MysqlTime:
return convertTime(expr.Val, expr.FieldType, sc.TimeZone)
}
// Then it must be a scalar function.
args := make([]Expression, 0, len(expr.Children))
for _, child := range expr.Children {
if child.Tp == tipb.ExprType_ValueList {
results, err := decodeValueList(child.Val)
if err != nil {
return nil, errors.Trace(err)
}
if len(results) == 0 {
return &Constant{Value: types.NewDatum(false), RetType: types.NewFieldType(mysql.TypeLonglong)}, nil
}
args = append(args, results...)
continue
}
arg, err := PBToExpr(child, tps, sc)
if err != nil {
return nil, errors.Trace(err)
}
args = append(args, arg)
}
if expr.Tp == tipb.ExprType_ScalarFunc {
return newDistSQLFunctionBySig(sc, expr.Sig, expr.FieldType, args)
}
return newDistSQLFunction(sc, expr.Tp, args)
}
func fieldTypeFromPB(ft *tipb.FieldType) *types.FieldType {
return &types.FieldType{
Tp: byte(ft.GetTp()),
Flag: uint(ft.GetFlag()),
Flen: int(ft.GetFlen()),
Decimal: int(ft.GetDecimal()),
Collate: mysql.Collations[uint8(ft.GetCollate())],
}
}
func convertTime(data []byte, ftPB *tipb.FieldType, tz *time.Location) (*Constant, error) {
ft := fieldTypeFromPB(ftPB)
_, v, err := codec.DecodeUint(data)
if err != nil {
return nil, errors.Trace(err)
}
var t types.Time
t.Type = ft.Tp
t.Fsp = ft.Decimal
err = t.FromPackedUint(v)
if err != nil {
return nil, errors.Trace(err)
}
if ft.Tp == mysql.TypeTimestamp && !t.IsZero() {
err = t.ConvertTimeZone(time.UTC, tz)
if err != nil {
return nil, errors.Trace(err)
}
}
return &Constant{Value: types.NewTimeDatum(t), RetType: ft}, nil
}
func decodeValueList(data []byte) ([]Expression, error) {
if len(data) == 0 {
return nil, nil
}
list, err := codec.Decode(data, 1)
if err != nil {
return nil, errors.Trace(err)
}
result := make([]Expression, 0, len(list))
for _, value := range list {
result = append(result, &Constant{Value: value})
}
return result, nil
}
func convertInt(val []byte) (*Constant, error) {
var d types.Datum
_, i, err := codec.DecodeInt(val)
if err != nil {
return nil, errors.Errorf("invalid int % x", val)
}
d.SetInt64(i)
return &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeLonglong)}, nil
}
func convertUint(val []byte) (*Constant, error) {
var d types.Datum
_, u, err := codec.DecodeUint(val)
if err != nil {
return nil, errors.Errorf("invalid uint % x", val)
}
d.SetUint64(u)
return &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeLonglong)}, nil
}
func convertString(val []byte) (*Constant, error) {
var d types.Datum
d.SetBytesAsString(val)
return &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeVarString)}, nil
}
func convertFloat(val []byte, f32 bool) (*Constant, error) {
var d types.Datum
_, f, err := codec.DecodeFloat(val)
if err != nil {
return nil, errors.Errorf("invalid float % x", val)
}
if f32 {
d.SetFloat32(float32(f))
} else {
d.SetFloat64(f)
}
return &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeDouble)}, nil
}
func convertDecimal(val []byte) (*Constant, error) {
_, dec, err := codec.DecodeDecimal(val)
if err != nil {
return nil, errors.Errorf("invalid decimal % x", val)
}
return &Constant{Value: dec, RetType: types.NewFieldType(mysql.TypeNewDecimal)}, nil
}
func convertDuration(val []byte) (*Constant, error) {
var d types.Datum
_, i, err := codec.DecodeInt(val)
if err != nil {
return nil, errors.Errorf("invalid duration %d", i)
}
d.SetMysqlDuration(types.Duration{Duration: time.Duration(i), Fsp: types.MaxFsp})
return &Constant{Value: d, RetType: types.NewFieldType(mysql.TypeDuration)}, nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/zhoujin826/tidb.git
git@gitee.com:zhoujin826/tidb.git
zhoujin826
tidb
tidb
v1.1.0-alpha

搜索帮助