Skip to content

Commit 1e40387

Browse files
lonngqw4990
authored andcommitted
expression: reuse tipb.Expr 'val' to push down expression implicit parameters (#10790)
1 parent c12abec commit 1e40387

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

expression/builtin.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ func (b *baseBuiltinFunc) PbCode() tipb.ScalarFuncSig {
4141
return b.pbCode
4242
}
4343

44+
// implicitArgs returns the implicit arguments of this function.
45+
// implicit arguments means some functions contain extra inner fields which will not
46+
// contain in `tipb.Expr.children` but must be pushed down to coprocessor
47+
func (b *baseBuiltinFunc) implicitArgs() []types.Datum {
48+
// We will not use a field to store them because of only
49+
// a few functions contain implicit parameters
50+
return nil
51+
}
52+
4453
func (b *baseBuiltinFunc) setPbCode(c tipb.ScalarFuncSig) {
4554
b.pbCode = c
4655
}
@@ -244,6 +253,17 @@ type baseBuiltinCastFunc struct {
244253
inUnion bool
245254
}
246255

256+
// implicitArgs returns the implicit arguments of cast functions
257+
func (b *baseBuiltinCastFunc) implicitArgs() []types.Datum {
258+
args := b.baseBuiltinFunc.implicitArgs()
259+
if b.inUnion {
260+
args = append(args, types.NewIntDatum(1))
261+
} else {
262+
args = append(args, types.NewIntDatum(0))
263+
}
264+
return args
265+
}
266+
247267
func (b *baseBuiltinCastFunc) cloneFrom(from *baseBuiltinCastFunc) {
248268
b.baseBuiltinFunc.cloneFrom(&from.baseBuiltinFunc)
249269
b.inUnion = from.inUnion
@@ -284,6 +304,10 @@ type builtinFunc interface {
284304
setPbCode(tipb.ScalarFuncSig)
285305
// PbCode returns PbCode of this signature.
286306
PbCode() tipb.ScalarFuncSig
307+
// implicitArgs returns the implicit parameters of a function.
308+
// implicit arguments means some functions contain extra inner fields which will not
309+
// contain in `tipb.Expr.children` but must be pushed down to coprocessor
310+
implicitArgs() []types.Datum
287311
// Clone returns a copy of itself.
288312
Clone() builtinFunc
289313
}

expression/expr_to_pb.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,20 @@ func (pc PbConverter) scalarFuncToPBExpr(expr *ScalarFunction) *tipb.Expr {
243243
children = append(children, pbArg)
244244
}
245245

246+
var implicitArgs []byte
247+
if args := expr.Function.implicitArgs(); len(args) > 0 {
248+
encoded, err := codec.EncodeValue(pc.sc, nil, args...)
249+
if err != nil {
250+
logutil.Logger(context.Background()).Error("encode implicit parameters", zap.Any("datums", args), zap.Error(err))
251+
return nil
252+
}
253+
implicitArgs = encoded
254+
}
255+
246256
// construct expression ProtoBuf.
247257
return &tipb.Expr{
248258
Tp: tipb.ExprType_ScalarFunc,
259+
Val: implicitArgs,
249260
Sig: pbCode,
250261
Children: children,
251262
FieldType: ToPBFieldType(expr.RetType),

expression/expr_to_pb_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/pingcap/parser/mysql"
2626
"github.com/pingcap/tidb/sessionctx/stmtctx"
2727
"github.com/pingcap/tidb/types"
28+
"github.com/pingcap/tidb/util/codec"
2829
"github.com/pingcap/tidb/util/mock"
2930
"github.com/pingcap/tipb/go-tipb"
3031
)
@@ -593,3 +594,41 @@ func (s *testEvaluatorSuite) TestSortByItem2Pb(c *C) {
593594
c.Assert(err, IsNil)
594595
c.Assert(string(js), Equals, "{\"expr\":{\"tp\":201,\"val\":\"gAAAAAAAAAE=\",\"sig\":0,\"field_type\":{\"tp\":5,\"flag\":0,\"flen\":-1,\"decimal\":-1,\"collate\":46,\"charset\":\"\"}},\"desc\":true}")
595596
}
597+
598+
func (s *testEvaluatorSuite) TestImplicitArgs(c *C) {
599+
sc := new(stmtctx.StatementContext)
600+
client := new(mock.Client)
601+
dg := new(dataGen4Expr2PbTest)
602+
603+
c.Assert(failpoint.Enable("github.com/pingcap/tidb/expression/PushDownTestSwitcher", `return("all")`), IsNil)
604+
defer func() { c.Assert(failpoint.Disable("github.com/pingcap/tidb/expression/PushDownTestSwitcher"), IsNil) }()
605+
606+
pc := PbConverter{client: client, sc: sc}
607+
608+
// InUnion flag is false in `BuildCastFunction` when `ScalarFuncSig_CastStringAsInt`
609+
cast := BuildCastFunction(mock.NewContext(), dg.genColumn(mysql.TypeString, 1), types.NewFieldType(mysql.TypeLonglong))
610+
c.Assert(cast.(*ScalarFunction).Function.implicitArgs(), DeepEquals, []types.Datum{types.NewIntDatum(0)})
611+
expr := pc.ExprToPB(cast)
612+
c.Assert(expr.Sig, Equals, tipb.ScalarFuncSig_CastStringAsInt)
613+
c.Assert(len(expr.Val), Greater, 0)
614+
datums, err := codec.Decode(expr.Val, 1)
615+
c.Assert(err, IsNil)
616+
c.Assert(datums, DeepEquals, []types.Datum{types.NewIntDatum(0)})
617+
618+
// InUnion flag is nil in `BuildCastFunction4Union` when `ScalarFuncSig_CastIntAsString`
619+
castInUnion := BuildCastFunction4Union(mock.NewContext(), dg.genColumn(mysql.TypeLonglong, 1), types.NewFieldType(mysql.TypeString))
620+
c.Assert(castInUnion.(*ScalarFunction).Function.implicitArgs(), IsNil)
621+
expr = pc.ExprToPB(castInUnion)
622+
c.Assert(expr.Sig, Equals, tipb.ScalarFuncSig_CastIntAsString)
623+
c.Assert(len(expr.Val), Equals, 0)
624+
625+
// InUnion flag is true in `BuildCastFunction4Union` when `ScalarFuncSig_CastStringAsInt`
626+
castInUnion = BuildCastFunction4Union(mock.NewContext(), dg.genColumn(mysql.TypeString, 1), types.NewFieldType(mysql.TypeLonglong))
627+
c.Assert(castInUnion.(*ScalarFunction).Function.implicitArgs(), DeepEquals, []types.Datum{types.NewIntDatum(1)})
628+
expr = pc.ExprToPB(castInUnion)
629+
c.Assert(expr.Sig, Equals, tipb.ScalarFuncSig_CastStringAsInt)
630+
c.Assert(len(expr.Val), Greater, 0)
631+
datums, err = codec.Decode(expr.Val, 1)
632+
c.Assert(err, IsNil)
633+
c.Assert(datums, DeepEquals, []types.Datum{types.NewIntDatum(1)})
634+
}

0 commit comments

Comments
 (0)