Skip to content

Commit

Permalink
expression: disable some json function from pushdown to TiFlash (#56177
Browse files Browse the repository at this point in the history
…) (#56225)

close #56173
  • Loading branch information
ti-chi-bot authored Sep 24, 2024
1 parent 20ad05f commit eb9d3bf
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 23 deletions.
122 changes: 100 additions & 22 deletions expression/expr_to_pb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,27 +503,18 @@ func TestOtherFunc2Pb(t *testing.T) {
}
}

func TestExprPushDownToFlash(t *testing.T) {
func TestJsonPushDownToFlash(t *testing.T) {
sc := new(stmtctx.StatementContext)
client := new(mock.Client)

exprs := make([]Expression, 0)

jsonColumn := genColumn(mysql.TypeJSON, 1)
intColumn := genColumn(mysql.TypeLonglong, 2)
realColumn := genColumn(mysql.TypeDouble, 3)
decimalColumn := genColumn(mysql.TypeNewDecimal, 4)
decimalColumn.RetType.SetDecimal(mysql.MaxDecimalScale)
decimalColumn.RetType.SetFlen(mysql.MaxDecimalWidth)
stringColumn := genColumn(mysql.TypeString, 5)
datetimeColumn := genColumn(mysql.TypeDatetime, 6)
binaryStringColumn := genColumn(mysql.TypeString, 7)
binaryStringColumn.RetType.SetCollate(charset.CollationBin)
int32Column := genColumn(mysql.TypeLong, 8)
float32Column := genColumn(mysql.TypeFloat, 9)
enumColumn := genColumn(mysql.TypeEnum, 10)
durationColumn := genColumn(mysql.TypeDuration, 11)

// functions that can be pushdown to tiflash
// json_length
function, err := NewFunction(mock.NewContext(), ast.JSONLength, types.NewFieldType(mysql.TypeLonglong), jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)
Expand All @@ -540,8 +531,104 @@ func TestExprPushDownToFlash(t *testing.T) {
require.NoError(t, err)
exprs = append(exprs, function)

// CastJsonAsString
function, err = NewFunction(mock.NewContext(), ast.Cast, types.NewFieldType(mysql.TypeString), jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// IfNullJson
function, err = NewFunction(mock.NewContext(), ast.Ifnull, types.NewFieldType(mysql.TypeJSON), jsonColumn, jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// JsonIsNull is not implement, for function json_col is null, it will be converted to cast(json as string) is null
function, err = NewFunction(mock.NewContext(), ast.IsNull, types.NewFieldType(mysql.TypeLonglong), jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// CaseWhenJson
function, err = NewFunction(mock.NewContext(), ast.Case, types.NewFieldType(mysql.TypeJSON), intColumn, jsonColumn, intColumn, jsonColumn, jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// CoalesceJson
function, err = NewFunction(mock.NewContext(), ast.Coalesce, types.NewFieldType(mysql.TypeJSON), jsonColumn, jsonColumn, jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

pushed, remained := PushDownExprs(sc, exprs, client, kv.TiFlash)
require.Len(t, pushed, len(exprs))
require.Len(t, remained, 0)

// functions that can not be pushed to tiflash
exprs = exprs[:0]
// LTJson
function, err = NewFunction(mock.NewContext(), ast.LT, types.NewFieldType(mysql.TypeLonglong), jsonColumn, jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// LEJson
function, err = NewFunction(mock.NewContext(), ast.LE, types.NewFieldType(mysql.TypeLonglong), jsonColumn, jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// GTJson
function, err = NewFunction(mock.NewContext(), ast.GT, types.NewFieldType(mysql.TypeLonglong), jsonColumn, jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// GEJson
function, err = NewFunction(mock.NewContext(), ast.GE, types.NewFieldType(mysql.TypeLonglong), jsonColumn, jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// EQJson
function, err = NewFunction(mock.NewContext(), ast.EQ, types.NewFieldType(mysql.TypeLonglong), jsonColumn, jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// NEJson
function, err = NewFunction(mock.NewContext(), ast.NE, types.NewFieldType(mysql.TypeLonglong), jsonColumn, jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// InJson
function, err = NewFunction(mock.NewContext(), ast.In, types.NewFieldType(mysql.TypeLonglong), jsonColumn, jsonColumn, jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// json_depth
function, err = NewFunction(mock.NewContext(), ast.JSONDepth, types.NewFieldType(mysql.TypeLonglong), jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

pushed, remained = PushDownExprs(sc, exprs, client, kv.TiFlash)
require.Len(t, pushed, 0)
require.Len(t, remained, len(exprs))
}

func TestExprPushDownToFlash(t *testing.T) {
sc := new(stmtctx.StatementContext)
client := new(mock.Client)

exprs := make([]Expression, 0)

intColumn := genColumn(mysql.TypeLonglong, 2)
realColumn := genColumn(mysql.TypeDouble, 3)
decimalColumn := genColumn(mysql.TypeNewDecimal, 4)
decimalColumn.RetType.SetDecimal(mysql.MaxDecimalScale)
decimalColumn.RetType.SetFlen(mysql.MaxDecimalWidth)
stringColumn := genColumn(mysql.TypeString, 5)
datetimeColumn := genColumn(mysql.TypeDatetime, 6)
binaryStringColumn := genColumn(mysql.TypeString, 7)
binaryStringColumn.RetType.SetCollate(charset.CollationBin)
int32Column := genColumn(mysql.TypeLong, 8)
float32Column := genColumn(mysql.TypeFloat, 9)
enumColumn := genColumn(mysql.TypeEnum, 10)
durationColumn := genColumn(mysql.TypeDuration, 11)

// lpad
function, err = NewFunction(mock.NewContext(), ast.Lpad, types.NewFieldType(mysql.TypeString), stringColumn, int32Column, stringColumn)
function, err := NewFunction(mock.NewContext(), ast.Lpad, types.NewFieldType(mysql.TypeString), stringColumn, int32Column, stringColumn)
require.NoError(t, err)
exprs = append(exprs, function)

Expand Down Expand Up @@ -651,11 +738,6 @@ func TestExprPushDownToFlash(t *testing.T) {
require.NoError(t, err)
exprs = append(exprs, function)

// CastJsonAsString
function, err = NewFunction(mock.NewContext(), ast.Cast, types.NewFieldType(mysql.TypeString), jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// CastIntAsTime
function, err = NewFunction(mock.NewContext(), ast.Cast, types.NewFieldType(mysql.TypeDatetime), intColumn)
require.NoError(t, err)
Expand Down Expand Up @@ -990,10 +1072,6 @@ func TestExprPushDownToFlash(t *testing.T) {
require.NoError(t, err)
exprs = append(exprs, function)

function, err = NewFunction(mock.NewContext(), ast.JSONDepth, types.NewFieldType(mysql.TypeLonglong), jsonColumn)
require.NoError(t, err)
exprs = append(exprs, function)

// ExtractDatetimeFromString: can not be pushed
extractDatetimeFromStringUnitCol := new(Constant)
extractDatetimeFromStringUnitCol.Value = types.NewStringDatum("day_microsecond")
Expand Down
10 changes: 9 additions & 1 deletion expression/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,15 @@ func scalarExprSupportedByFlash(function *ScalarFunction) bool {
tipb.ScalarFuncSig_CoalesceDuration,
tipb.ScalarFuncSig_IfNullDuration,
tipb.ScalarFuncSig_IfDuration,
tipb.ScalarFuncSig_CaseWhenDuration:
tipb.ScalarFuncSig_CaseWhenDuration,
tipb.ScalarFuncSig_LTJson,
tipb.ScalarFuncSig_LEJson,
tipb.ScalarFuncSig_GTJson,
tipb.ScalarFuncSig_GEJson,
tipb.ScalarFuncSig_EQJson,
tipb.ScalarFuncSig_NEJson,
tipb.ScalarFuncSig_JsonIsNull,
tipb.ScalarFuncSig_InJson:
return false
case tipb.ScalarFuncSig_JsonUnquoteSig:
// TiFlash json_unquote now only supports json string generated by cast(json as string)
Expand Down

0 comments on commit eb9d3bf

Please sign in to comment.