diff --git a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json index 3560b0f323f..f1eee18b5d8 100644 --- a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.json @@ -88,7 +88,7 @@ "Sharded": true }, "FieldQuery": "select `user`.col1 as a, `user`.col2 from `user` where 1 != 1", - "Query": "select `user`.col1 as a, `user`.col2 from `user` where `user`.col1 = 1 and `user`.col1 = `user`.col2 and 1 = 1", + "Query": "select `user`.col1 as a, `user`.col2 from `user` where `user`.col1 = 1 and `user`.col1 = `user`.col2", "Table": "`user`" }, { @@ -99,7 +99,7 @@ "Sharded": true }, "FieldQuery": "select user_extra.col3 from user_extra where 1 != 1", - "Query": "select user_extra.col3 from user_extra where user_extra.col3 = 1 and 1 = 1", + "Query": "select user_extra.col3 from user_extra where user_extra.col3 = 1", "Table": "user_extra" } ] diff --git a/go/vt/vtgate/semantics/early_rewriter.go b/go/vt/vtgate/semantics/early_rewriter.go index d11d12023c4..ae433465998 100644 --- a/go/vt/vtgate/semantics/early_rewriter.go +++ b/go/vt/vtgate/semantics/early_rewriter.go @@ -47,6 +47,8 @@ func (r *earlyRewriter) down(cursor *sqlparser.Cursor) error { handleOrderBy(r, cursor, node) case *sqlparser.OrExpr: rewriteOrExpr(cursor, node) + case *sqlparser.AndExpr: + rewriteAndExpr(cursor, node) case *sqlparser.NotExpr: rewriteNotExpr(cursor, node) case sqlparser.GroupBy: @@ -138,6 +140,45 @@ func rewriteOrExpr(cursor *sqlparser.Cursor, node *sqlparser.OrExpr) { } } +// rewriteAndExpr rewrites AND expressions when either side is TRUE. +func rewriteAndExpr(cursor *sqlparser.Cursor, node *sqlparser.AndExpr) { + newNode := rewriteAndTrue(*node) + if newNode != nil { + cursor.ReplaceAndRevisit(newNode) + } +} + +func rewriteAndTrue(andExpr sqlparser.AndExpr) sqlparser.Expr { + // we are looking for the pattern `WHERE c = 1 AND 1 = 1` + isTrue := func(subExpr sqlparser.Expr) bool { + evalEnginePred, err := evalengine.Translate(subExpr, nil) + if err != nil { + return false + } + + env := evalengine.EmptyExpressionEnv() + res, err := env.Evaluate(evalEnginePred) + if err != nil { + return false + } + + boolValue, err := res.Value(collations.Default()).ToBool() + if err != nil { + return false + } + + return boolValue + } + + if isTrue(andExpr.Left) { + return andExpr.Right + } else if isTrue(andExpr.Right) { + return andExpr.Left + } + + return nil +} + // handleLiteral processes literals within the context of ORDER BY expressions. func handleLiteral(r *earlyRewriter, cursor *sqlparser.Cursor, node *sqlparser.Literal) error { newNode, err := r.rewriteOrderByExpr(node)