Skip to content

Commit

Permalink
handle large number of predicates without timing out
Browse files Browse the repository at this point in the history
Signed-off-by: Andres Taylor <andres@planetscale.com>
  • Loading branch information
systay committed Sep 14, 2023
1 parent 5f18cb3 commit 3899d89
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 82 deletions.
51 changes: 15 additions & 36 deletions go/vt/sqlparser/ast_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1103,29 +1103,14 @@ func (node *Select) GetParsedComments() *ParsedComments {
// AddWhere adds the boolean expression to the
// WHERE clause as an AND condition.
func (node *Select) AddWhere(expr Expr) {
if node.Where == nil {
node.Where = &Where{
Type: WhereClause,
Expr: expr,
}
return
}
exprs := SplitAndExpression(nil, node.Where.Expr)
node.Where.Expr = AndExpressions(append(exprs, expr)...)
node.Where = addPredicate(node.Where, expr)
}

// AddHaving adds the boolean expression to the
// HAVING clause as an AND condition.
func (node *Select) AddHaving(expr Expr) {
if node.Having == nil {
node.Having = &Where{
Type: HavingClause,
Expr: expr,
}
return
}
exprs := SplitAndExpression(nil, node.Having.Expr)
node.Having.Expr = AndExpressions(append(exprs, expr)...)
node.Having = addPredicate(node.Having, expr)
node.Having.Type = HavingClause
}

// AddGroupBy adds a grouping expression, unless it's already present
Expand All @@ -1142,33 +1127,27 @@ func (node *Select) AddGroupBy(expr Expr) {
// AddWhere adds the boolean expression to the
// WHERE clause as an AND condition.
func (node *Update) AddWhere(expr Expr) {
if node.Where == nil {
node.Where = &Where{
node.Where = addPredicate(node.Where, expr)
}

func addPredicate(where *Where, pred Expr) *Where {
if where == nil {
return &Where{
Type: WhereClause,
Expr: expr,
Expr: pred,
}
return
}
node.Where.Expr = &AndExpr{
Left: node.Where.Expr,
Right: expr,
where.Expr = &AndExpr{
Left: where.Expr,
Right: pred,
}
return where
}

// AddWhere adds the boolean expression to the
// WHERE clause as an AND condition.
func (node *Delete) AddWhere(expr Expr) {
if node.Where == nil {
node.Where = &Where{
Type: WhereClause,
Expr: expr,
}
return
}
node.Where.Expr = &AndExpr{
Left: node.Where.Expr,
Right: expr,
}
node.Where = addPredicate(node.Where, expr)
}

// AddOrder adds an order by element
Expand Down
61 changes: 25 additions & 36 deletions go/vt/sqlparser/ast_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,46 +49,35 @@ func TestAppend(t *testing.T) {
}

func TestSelect(t *testing.T) {
tree, err := Parse("select * from t where a = 1")
e1, err := ParseExpr("a = 1")
require.NoError(t, err)
expr := tree.(*Select).Where.Expr

sel := &Select{}
sel.AddWhere(expr)
buf := NewTrackedBuffer(nil)
sel.Where.Format(buf)
assert.Equal(t, " where a = 1", buf.String())
sel.AddWhere(expr)
buf = NewTrackedBuffer(nil)
sel.Where.Format(buf)
assert.Equal(t, " where a = 1", buf.String())

sel = &Select{}
sel.AddHaving(expr)
buf = NewTrackedBuffer(nil)
sel.Having.Format(buf)
assert.Equal(t, " having a = 1", buf.String())

sel.AddHaving(expr)
buf = NewTrackedBuffer(nil)
sel.Having.Format(buf)
assert.Equal(t, " having a = 1", buf.String())

tree, err = Parse("select * from t where a = 1 or b = 1")
e2, err := ParseExpr("b = 2")
require.NoError(t, err)
expr = tree.(*Select).Where.Expr
sel = &Select{}
sel.AddWhere(expr)
buf = NewTrackedBuffer(nil)
sel.Where.Format(buf)
assert.Equal(t, " where a = 1 or b = 1", buf.String())
t.Run("single predicate where", func(t *testing.T) {
sel := &Select{}
sel.AddWhere(e1)
assert.Equal(t, " where a = 1", String(sel.Where))
})

sel = &Select{}
sel.AddHaving(expr)
buf = NewTrackedBuffer(nil)
sel.Having.Format(buf)
assert.Equal(t, " having a = 1 or b = 1", buf.String())
t.Run("single predicate having", func(t *testing.T) {
sel := &Select{}
sel.AddHaving(e1)
assert.Equal(t, " having a = 1", String(sel.Having))
})

t.Run("double predicate where", func(t *testing.T) {
sel := &Select{}
sel.AddWhere(e1)
sel.AddWhere(e2)
assert.Equal(t, " where a = 1 and b = 2", String(sel.Where))
})

t.Run("double predicate having", func(t *testing.T) {
sel := &Select{}
sel.AddHaving(e1)
sel.AddHaving(e2)
assert.Equal(t, " having a = 1 and b = 2", String(sel.Having))
})
}

func TestUpdate(t *testing.T) {
Expand Down
30 changes: 30 additions & 0 deletions go/vt/vtgate/planbuilder/testdata/filter_cases.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions go/vt/vtgate/planbuilder/testdata/info_schema57_cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@
"Sharded": false
},
"FieldQuery": "select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, `ENGINE`, VERSION, `ROW_FORMAT`, TABLE_ROWS, `AVG_ROW_LENGTH`, DATA_LENGTH, MAX_DATA_LENGTH, INDEX_LENGTH, DATA_FREE, `AUTO_INCREMENT`, CREATE_TIME, UPDATE_TIME, CHECK_TIME, TABLE_COLLATION, `CHECKSUM`, CREATE_OPTIONS, TABLE_COMMENT from INFORMATION_SCHEMA.`TABLES` where 1 != 1",
"Query": "select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, `ENGINE`, VERSION, `ROW_FORMAT`, TABLE_ROWS, `AVG_ROW_LENGTH`, DATA_LENGTH, MAX_DATA_LENGTH, INDEX_LENGTH, DATA_FREE, `AUTO_INCREMENT`, CREATE_TIME, UPDATE_TIME, CHECK_TIME, TABLE_COLLATION, `CHECKSUM`, CREATE_OPTIONS, TABLE_COMMENT from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */",
"Query": "select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, `ENGINE`, VERSION, `ROW_FORMAT`, TABLE_ROWS, `AVG_ROW_LENGTH`, DATA_LENGTH, MAX_DATA_LENGTH, INDEX_LENGTH, DATA_FREE, `AUTO_INCREMENT`, CREATE_TIME, UPDATE_TIME, CHECK_TIME, TABLE_COLLATION, `CHECKSUM`, CREATE_OPTIONS, TABLE_COMMENT from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and TABLE_SCHEMA = :__vtschemaname /* VARCHAR */",
"SysTableTableSchema": "[VARCHAR(\"user\"), VARCHAR(\"main\")]",
"Table": "INFORMATION_SCHEMA.`TABLES`"
}
Expand Down Expand Up @@ -874,7 +874,7 @@
"Sharded": false
},
"FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1",
"Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */",
"Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */ and table_schema = :__vtschemaname /* VARCHAR */",
"SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"Music\")]",
"Table": "information_schema.`tables`"
},
Expand All @@ -886,7 +886,7 @@
"Sharded": false
},
"FieldQuery": "select 1 as found from information_schema.views where 1 != 1",
"Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ limit 1",
"Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ and table_schema = :__vtschemaname /* VARCHAR */ limit 1",
"SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"user\")]",
"Table": "information_schema.views"
}
Expand All @@ -911,7 +911,7 @@
"Sharded": false
},
"FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1",
"Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */",
"Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */ and table_schema = :__vtschemaname /* VARCHAR */",
"SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"Music\")]",
"Table": "information_schema.`tables`"
},
Expand All @@ -923,7 +923,7 @@
"Sharded": false
},
"FieldQuery": "select 1 as found from information_schema.views where 1 != 1",
"Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ limit 1",
"Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ and table_schema = :__vtschemaname /* VARCHAR */ limit 1",
"SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"user\")]",
"Table": "information_schema.views"
}
Expand Down
10 changes: 5 additions & 5 deletions go/vt/vtgate/planbuilder/testdata/info_schema80_cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@
"Sharded": false
},
"FieldQuery": "select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, `ENGINE`, VERSION, `ROW_FORMAT`, TABLE_ROWS, `AVG_ROW_LENGTH`, DATA_LENGTH, MAX_DATA_LENGTH, INDEX_LENGTH, DATA_FREE, `AUTO_INCREMENT`, CREATE_TIME, UPDATE_TIME, CHECK_TIME, TABLE_COLLATION, `CHECKSUM`, CREATE_OPTIONS, TABLE_COMMENT from INFORMATION_SCHEMA.`TABLES` where 1 != 1",
"Query": "select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, `ENGINE`, VERSION, `ROW_FORMAT`, TABLE_ROWS, `AVG_ROW_LENGTH`, DATA_LENGTH, MAX_DATA_LENGTH, INDEX_LENGTH, DATA_FREE, `AUTO_INCREMENT`, CREATE_TIME, UPDATE_TIME, CHECK_TIME, TABLE_COLLATION, `CHECKSUM`, CREATE_OPTIONS, TABLE_COMMENT from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */",
"Query": "select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE, `ENGINE`, VERSION, `ROW_FORMAT`, TABLE_ROWS, `AVG_ROW_LENGTH`, DATA_LENGTH, MAX_DATA_LENGTH, INDEX_LENGTH, DATA_FREE, `AUTO_INCREMENT`, CREATE_TIME, UPDATE_TIME, CHECK_TIME, TABLE_COLLATION, `CHECKSUM`, CREATE_OPTIONS, TABLE_COMMENT from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname /* VARCHAR */ and TABLE_SCHEMA = :__vtschemaname /* VARCHAR */",
"SysTableTableSchema": "[VARCHAR(\"user\"), VARCHAR(\"main\")]",
"Table": "INFORMATION_SCHEMA.`TABLES`"
}
Expand Down Expand Up @@ -939,7 +939,7 @@
"Sharded": false
},
"FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1",
"Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */",
"Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */ and table_schema = :__vtschemaname /* VARCHAR */",
"SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"Music\")]",
"Table": "information_schema.`tables`"
},
Expand All @@ -951,7 +951,7 @@
"Sharded": false
},
"FieldQuery": "select 1 as found from information_schema.views where 1 != 1",
"Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ limit 1",
"Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ and table_schema = :__vtschemaname /* VARCHAR */ limit 1",
"SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"user\")]",
"Table": "information_schema.views"
}
Expand All @@ -976,7 +976,7 @@
"Sharded": false
},
"FieldQuery": "select 1 as found from information_schema.`tables` where 1 != 1",
"Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */",
"Query": "select 1 as found from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */ and table_schema = :__vtschemaname /* VARCHAR */",
"SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"Music\")]",
"Table": "information_schema.`tables`"
},
Expand All @@ -988,7 +988,7 @@
"Sharded": false
},
"FieldQuery": "select 1 as found from information_schema.views where 1 != 1",
"Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ limit 1",
"Query": "select 1 as found from information_schema.views where table_schema = :__vtschemaname /* VARCHAR */ and table_schema = :__vtschemaname /* VARCHAR */ limit 1",
"SysTableTableSchema": "[VARCHAR(\"music\"), VARCHAR(\"user\")]",
"Table": "information_schema.views"
}
Expand Down

0 comments on commit 3899d89

Please sign in to comment.