Skip to content

Commit

Permalink
wip - change AndExpr to contain arbitrary many predicates
Browse files Browse the repository at this point in the history
Signed-off-by: Andres Taylor <[email protected]>
  • Loading branch information
systay committed Aug 28, 2024
1 parent 773a216 commit de1262e
Show file tree
Hide file tree
Showing 19 changed files with 292 additions and 229 deletions.
8 changes: 4 additions & 4 deletions go/vt/sqlparser/analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,10 @@ func TestAndExpressions(t *testing.T) {
equalExpr,
equalExpr,
},
expectedOutput: &AndExpr{
Left: greaterThanExpr,
Right: equalExpr,
},
expectedOutput: &AndExpr{Predicates: Exprs{
greaterThanExpr,
equalExpr,
}},
},
{
name: "two equal inputs",
Expand Down
4 changes: 1 addition & 3 deletions go/vt/sqlparser/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -2263,9 +2263,7 @@ type (
}

// AndExpr represents an AND expression.
AndExpr struct {
Left, Right Expr
}
AndExpr struct{ Predicates []Expr }

// OrExpr represents an OR expression.
OrExpr struct {
Expand Down
27 changes: 13 additions & 14 deletions go/vt/sqlparser/ast_clone.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 11 additions & 5 deletions go/vt/sqlparser/ast_copy_on_rewrite.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 14 additions & 15 deletions go/vt/sqlparser/ast_equals.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion go/vt/sqlparser/ast_format.go
Original file line number Diff line number Diff line change
Expand Up @@ -1297,7 +1297,13 @@ func (node Exprs) Format(buf *TrackedBuffer) {

// Format formats the node.
func (node *AndExpr) Format(buf *TrackedBuffer) {
buf.astPrintf(node, "%l and %r", node.Left, node.Right)
for idx, expr := range node.Predicates {
if idx == len(node.Predicates)-1 {
buf.astPrintf(node, "%r", expr)
continue
}
buf.astPrintf(node, "%l and ", expr)
}
}

// Format formats the node.
Expand Down
11 changes: 8 additions & 3 deletions go/vt/sqlparser/ast_format_fast.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 42 additions & 20 deletions go/vt/sqlparser/ast_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,27 @@ func Append(buf *strings.Builder, node SQLNode) {
node.FormatFast(tbuf)
}

func createAndExpr(exprL, exprR Expr) *AndExpr {
leftAnd, isLeftAnd := exprL.(*AndExpr)
rightAnd, isRightAnd := exprR.(*AndExpr)
if isLeftAnd && isRightAnd {
return &AndExpr{
Predicates: append(leftAnd.Predicates, rightAnd.Predicates...),
}
}
if isLeftAnd {
leftAnd.Predicates = append(leftAnd.Predicates, exprR)
return leftAnd
}
if isRightAnd {
rightAnd.Predicates = append([]Expr{exprL}, rightAnd.Predicates...)
return rightAnd
}
return &AndExpr{
Predicates: Exprs{exprL, exprR},
}
}

// IndexColumn describes a column or expression in an index definition with optional length (for column)
type IndexColumn struct {
// Only one of Column or Expression can be specified
Expand Down Expand Up @@ -1239,10 +1260,8 @@ func addPredicate(where *Where, pred Expr) *Where {
Expr: pred,
}
}
where.Expr = &AndExpr{
Left: where.Expr,
Right: pred,
}

where.Expr = createAndExpr(where.Expr, pred)
return where
}

Expand Down Expand Up @@ -2336,8 +2355,7 @@ func SplitAndExpression(filters []Expr, node Expr) []Expr {
}
switch node := node.(type) {
case *AndExpr:
filters = SplitAndExpression(filters, node.Left)
return SplitAndExpression(filters, node.Right)
return append(filters, node.Predicates...)
}
return append(filters, node)
}
Expand All @@ -2350,26 +2368,30 @@ func AndExpressions(exprs ...Expr) Expr {
case 1:
return exprs[0]
default:
result := (Expr)(nil)
outer:
var unique Exprs
// we'll loop and remove any duplicates
for i, expr := range exprs {
if expr == nil {
continue
}
if result == nil {
result = expr
continue outer
uniqueAdd := func(e Expr) {
for _, existing := range unique {
if Equals.Expr(e, existing) {
return
}
}
unique = append(unique, e)
}

for j := 0; j < i; j++ {
if Equals.Expr(expr, exprs[j]) {
continue outer
for _, expr := range exprs {
switch expr := expr.(type) {
case *AndExpr:
for _, p := range expr.Predicates {
uniqueAdd(p)
}
case nil:
continue
default:
uniqueAdd(expr)
}
result = &AndExpr{Left: result, Right: expr}
}
return result
return &AndExpr{Predicates: unique}
}
}

Expand Down
17 changes: 8 additions & 9 deletions go/vt/sqlparser/ast_rewrite.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 4 additions & 5 deletions go/vt/sqlparser/ast_visit.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 9 additions & 7 deletions go/vt/sqlparser/cached_size.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions go/vt/sqlparser/precedence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,24 @@ package sqlparser

import (
"fmt"
"strings"
"testing"
"time"

"github.com/stretchr/testify/require"

"vitess.io/vitess/go/slice"
)

func readable(node Expr) string {
switch node := node.(type) {
case *OrExpr:
return fmt.Sprintf("(%s or %s)", readable(node.Left), readable(node.Right))
case *AndExpr:
return fmt.Sprintf("(%s and %s)", readable(node.Left), readable(node.Right))
predicates := slice.Map(node.Predicates, func(from Expr) string {
return readable(from)
})
return fmt.Sprintf("(%s)", strings.Join(predicates, " and "))
case *XorExpr:
return fmt.Sprintf("(%s xor %s)", readable(node.Left), readable(node.Right))
case *BinaryExpr:
Expand Down Expand Up @@ -153,7 +159,7 @@ func TestParens(t *testing.T) {
{in: "((((((1000))))))", expected: "1000"},
{in: "100 - (50 + 10)", expected: "100 - (50 + 10)"},
{in: "100 - 50 + 10", expected: "100 - 50 + 10"},
{in: "true and (true and true)", expected: "true and (true and true)"},
{in: "true and (true and true)", expected: "true and true and true"},
{in: "10 - 2 - 1", expected: "10 - 2 - 1"},
{in: "(10 - 2) - 1", expected: "10 - 2 - 1"},
{in: "10 - (2 - 1)", expected: "10 - (2 - 1)"},
Expand Down Expand Up @@ -193,6 +199,6 @@ func TestRandom(t *testing.T) {

// Then the unparsing should be the same as the input query
outputOfParseResult := String(parsedInput)
require.Equal(t, outputOfParseResult, inputQ)
require.Equal(t, inputQ, outputOfParseResult)
}
}
Loading

0 comments on commit de1262e

Please sign in to comment.