fix bugs when push logic ops and bit ops down (#1838)
This commit is contained in:
@ -125,7 +125,7 @@ func scalarFuncToPBExpr(client kv.Client, expr *expression.ScalarFunction) *tipb
|
||||
return compareFuncToPBExpr(client, expr)
|
||||
case ast.Plus, ast.Minus, ast.Mul, ast.Div, ast.Mod, ast.IntDiv:
|
||||
return arithmeticalFuncToPBExpr(client, expr)
|
||||
case ast.And, ast.Or, ast.UnaryNot:
|
||||
case ast.AndAnd, ast.OrOr, ast.UnaryNot:
|
||||
return logicalFuncToPBExpr(client, expr)
|
||||
default:
|
||||
return nil
|
||||
@ -224,9 +224,9 @@ func arithmeticalFuncToPBExpr(client kv.Client, expr *expression.ScalarFunction)
|
||||
func logicalFuncToPBExpr(client kv.Client, expr *expression.ScalarFunction) *tipb.Expr {
|
||||
var tp tipb.ExprType
|
||||
switch expr.FuncName.L {
|
||||
case ast.And:
|
||||
case ast.AndAnd:
|
||||
tp = tipb.ExprType_And
|
||||
case ast.Or:
|
||||
case ast.OrOr:
|
||||
tp = tipb.ExprType_Or
|
||||
case ast.UnaryNot:
|
||||
return notToPBExpr(client, expr)
|
||||
|
||||
@ -273,6 +273,81 @@ func (s *testPlanSuite) TestTopnPushDown(c *C) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestLogicOpsPushDown tests whether logic operators been pushed down successfully.
|
||||
func (s *testPlanSuite) TestLogicOpsPushDown(c *C) {
|
||||
defer testleak.AfterTest(c)()
|
||||
cases := []struct {
|
||||
sql string
|
||||
cond string // readable expressions.
|
||||
exprPB string // Marshall result of conditions been pushed down.
|
||||
}{
|
||||
{
|
||||
sql: "a and b",
|
||||
cond: "and(test.t.a, test.t.b)",
|
||||
exprPB: "\b\xc9\x01\x12\b\x80\x00\x00\x00\x00\x00\x00\x02",
|
||||
},
|
||||
{
|
||||
sql: "a or b",
|
||||
cond: "or(test.t.a, test.t.b)",
|
||||
exprPB: "\b\xfe\x11\x1a\r\b\xc9\x01\x12\b\x80\x00\x00\x00\x00\x00\x00\x01\x1a\r\b\xc9\x01\x12\b\x80\x00\x00\x00\x00\x00\x00\x02",
|
||||
},
|
||||
{
|
||||
sql: "a and (b or c)",
|
||||
cond: "and(test.t.a, or(test.t.b, test.t.c))",
|
||||
exprPB: "\b\xfe\x11\x1a\r\b\xc9\x01\x12\b\x80\x00\x00\x00\x00\x00\x00\x02\x1a\r\b\xc9\x01\x12\b\x80\x00\x00\x00\x00\x00\x00\x03",
|
||||
},
|
||||
{
|
||||
sql: "not a",
|
||||
cond: "not(test.t.a)",
|
||||
exprPB: "\b\xe9\a\x1a\r\b\xc9\x01\x12\b\x80\x00\x00\x00\x00\x00\x00\x01",
|
||||
},
|
||||
}
|
||||
for _, ca := range cases {
|
||||
sql := "select * from t where " + ca.sql
|
||||
comment := Commentf("for %s", sql)
|
||||
stmt, err := s.ParseOneStmt(sql, "", "")
|
||||
c.Assert(err, IsNil, comment)
|
||||
ast.SetFlag(stmt)
|
||||
|
||||
err = mockResolve(stmt)
|
||||
c.Assert(err, IsNil)
|
||||
builder := &planBuilder{
|
||||
allocator: new(idAllocator),
|
||||
ctx: mockContext(),
|
||||
colMapper: make(map[*ast.ColumnNameExpr]int),
|
||||
}
|
||||
p := builder.build(stmt)
|
||||
c.Assert(builder.err, IsNil)
|
||||
lp := p.(LogicalPlan)
|
||||
|
||||
_, lp, err = lp.PredicatePushDown(nil)
|
||||
c.Assert(err, IsNil)
|
||||
_, err = lp.PruneColumnsAndResolveIndices(lp.GetSchema())
|
||||
c.Assert(err, IsNil)
|
||||
lp = EliminateProjection(lp)
|
||||
info, err := lp.convert2PhysicalPlan(&requiredProperty{})
|
||||
c.Assert(err, IsNil)
|
||||
p = info.p
|
||||
// loop util reaching the DataSource node of a physical plan to get the conditions been pushed down.
|
||||
loop:
|
||||
for {
|
||||
switch x := p.(type) {
|
||||
case *PhysicalTableScan:
|
||||
c.Assert(fmt.Sprintf("%s", expression.ComposeCNFCondition(x.conditions).String()), Equals, ca.cond, Commentf("for %s", sql))
|
||||
pbStr, _ := x.ConditionPBExpr.Marshal()
|
||||
c.Assert(fmt.Sprintf("%s", pbStr), Equals, ca.exprPB, Commentf("for %s", sql))
|
||||
break loop
|
||||
case *PhysicalIndexScan:
|
||||
c.Assert(fmt.Sprintf("%s", expression.ComposeCNFCondition(x.conditions).String()), Equals, ca.cond, Commentf("for %s", sql))
|
||||
pbStr, _ := x.ConditionPBExpr.Marshal()
|
||||
c.Assert(fmt.Sprintf("%s", pbStr), Equals, ca.exprPB, Commentf("for %s", sql))
|
||||
break loop
|
||||
}
|
||||
p = p.GetChildByIndex(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *testPlanSuite) TestPredicatePushDown(c *C) {
|
||||
defer testleak.AfterTest(c)()
|
||||
cases := []struct {
|
||||
|
||||
Reference in New Issue
Block a user