Skip to content

Commit

Permalink
distsql: support pushing isnull down (pingcap#2069)
Browse files Browse the repository at this point in the history
  • Loading branch information
XuHuaiyu authored and zimulala committed Nov 23, 2016
1 parent f4b78e4 commit 951f882
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 4 deletions.
16 changes: 16 additions & 0 deletions distsql/xeval/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ func (e *Evaluator) Eval(expr *tipb.Expr) (types.Datum, error) {
return e.evalControlFuncs(expr)
case tipb.ExprType_Coalesce:
return e.evalCoalesce(expr)
case tipb.ExprType_IsNull:
return e.evalIsNull(expr)
}
return types.Datum{}, nil
}
Expand All @@ -94,3 +96,17 @@ func (e *Evaluator) evalTwoChildren(expr *tipb.Expr) (left, right types.Datum, e
}
return
}

func (e *Evaluator) evalIsNull(expr *tipb.Expr) (types.Datum, error) {
if len(expr.Children) != 1 {
return types.Datum{}, ErrInvalid.Gen("ISNULL need 1 operand, got %d", len(expr.Children))
}
d, err := e.Eval(expr.Children[0])
if err != nil {
return types.Datum{}, errors.Trace(err)
}
if d.IsNull() {
return types.NewIntDatum(1), nil
}
return types.NewIntDatum(0), nil
}
33 changes: 33 additions & 0 deletions distsql/xeval/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,39 @@ func (s *testEvalSuite) TestWhereIn(c *C) {
}
}

func (s *testEvalSuite) TestEvalIsNull(c *C) {
colID := int64(1)
row := make(map[int64]types.Datum)
row[colID] = types.NewIntDatum(100)
xevaluator := &Evaluator{Row: row}
null, trueAns, falseAns := types.Datum{}, types.NewIntDatum(1), types.NewIntDatum(0)
cases := []struct {
expr *tipb.Expr
result types.Datum
}{
{
expr: buildExpr(tipb.ExprType_IsNull, types.NewStringDatum("abc")),
result: falseAns,
},
{
expr: buildExpr(tipb.ExprType_IsNull, null),
result: trueAns,
},
{
expr: buildExpr(tipb.ExprType_IsNull, types.NewIntDatum(0)),
result: falseAns,
},
}
for _, ca := range cases {
result, err := xevaluator.Eval(ca.expr)
c.Assert(err, IsNil)
c.Assert(result.Kind(), Equals, ca.result.Kind())
cmp, err := result.CompareDatum(ca.result)
c.Assert(err, IsNil)
c.Assert(cmp, Equals, 0)
}
}

func inExpr(target interface{}, list ...interface{}) *tipb.Expr {
targetDatum := types.NewDatum(target)
var listDatums []types.Datum
Expand Down
6 changes: 4 additions & 2 deletions plan/expr_to_pb.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func scalarFuncToPBExpr(client kv.Client, expr *expression.ScalarFunction) *tipb
return logicalOpsToPBExpr(client, expr)
case ast.And, ast.Or, ast.BitNeg, ast.Xor, ast.LeftShift, ast.RightShift:
return bitwiseFuncToPBExpr(client, expr)
case ast.Case, ast.Coalesce, ast.If:
case ast.Case, ast.Coalesce, ast.If, ast.IsNull:
return builtinFuncToPBExpr(client, expr)
default:
return nil
Expand Down Expand Up @@ -363,7 +363,7 @@ func builtinFuncToPBExpr(client kv.Client, expr *expression.ScalarFunction) *tip
switch expr.FuncName.L {
case ast.Case, ast.If:
return controlFuncsToPBExpr(client, expr)
case ast.Coalesce:
case ast.Coalesce, ast.IsNull:
return otherFuncsToPBExpr(client, expr)
default:
return nil
Expand All @@ -375,6 +375,8 @@ func otherFuncsToPBExpr(client kv.Client, expr *expression.ScalarFunction) *tipb
switch expr.FuncName.L {
case ast.Coalesce:
tp = tipb.ExprType_Coalesce
case ast.IsNull:
tp = tipb.ExprType_IsNull
}
return convertToPBExpr(client, expr, tp)
}
Expand Down
2 changes: 1 addition & 1 deletion plan/logcial_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func supportExpr(exprType tipb.ExprType) bool {
case tipb.ExprType_Case, tipb.ExprType_If:
return true
// other functions
case tipb.ExprType_Coalesce:
case tipb.ExprType_Coalesce, tipb.ExprType_IsNull:
return true
case kv.ReqSubTypeDesc:
return true
Expand Down
5 changes: 5 additions & 0 deletions plan/physical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ func (s *testPlanSuite) TestPushDownExpression(c *C) {
sql: "a = coalesce(null, null, a, b)",
cond: "eq(test.t.a, coalesce(<nil>, <nil>, test.t.a, test.t.b))",
},
// isnull
{
sql: "b is null",
cond: "isnull(test.t.b)",
},
}
for _, ca := range cases {
sql := "select * from t where " + ca.sql
Expand Down
2 changes: 1 addition & 1 deletion store/localstore/local_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func supportExpr(exprType tipb.ExprType) bool {
case tipb.ExprType_Case, tipb.ExprType_If:
return true
// other functions
case tipb.ExprType_Coalesce:
case tipb.ExprType_Coalesce, tipb.ExprType_IsNull:
return true
case kv.ReqSubTypeDesc:
return true
Expand Down

0 comments on commit 951f882

Please sign in to comment.