Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle large number of predicates without timing out #13979

Merged
merged 1 commit into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading