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

Avoid rewriting unsharded queries and split semantic analysis in two #15217

Merged
merged 12 commits into from
Feb 14, 2024
3 changes: 3 additions & 0 deletions go/vt/sqlparser/impossible_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ package sqlparser
func FormatImpossibleQuery(buf *TrackedBuffer, node SQLNode) {
switch node := node.(type) {
case *Select:
if node.With != nil {
node.With.Format(buf)
}
buf.Myprintf("select %v from ", node.SelectExprs)
var prefix string
for _, n := range node.From {
Expand Down
5 changes: 1 addition & 4 deletions go/vt/vtgate/planbuilder/operators/aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@ func (a *Aggregator) SetInputs(operators []Operator) {
}

func (a *Aggregator) AddPredicate(_ *plancontext.PlanningContext, expr sqlparser.Expr) Operator {
return &Filter{
Source: a,
Predicates: []sqlparser.Expr{expr},
}
return newFilter(a, expr)
}

func (a *Aggregator) addColumnWithoutPushing(_ *plancontext.PlanningContext, expr *sqlparser.AliasedExpr, addToGroupBy bool) int {
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operators/apply_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (aj *ApplyJoin) Clone(inputs []Operator) Operator {
}

func (aj *ApplyJoin) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator {
return AddPredicate(ctx, aj, expr, false, newFilter)
return AddPredicate(ctx, aj, expr, false, newFilterSinglePredicate)
}

// Inputs implements the Operator interface
Expand Down
8 changes: 6 additions & 2 deletions go/vt/vtgate/planbuilder/operators/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ type Filter struct {
Truncate int
}

func newFilter(op Operator, expr sqlparser.Expr) Operator {
func newFilterSinglePredicate(op Operator, expr sqlparser.Expr) Operator {
return newFilter(op, expr)
}

func newFilter(op Operator, expr ...sqlparser.Expr) Operator {
return &Filter{
Source: op, Predicates: []sqlparser.Expr{expr},
Source: op, Predicates: expr,
}
}

Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operators/hash_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
}

func (hj *HashJoin) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator {
return AddPredicate(ctx, hj, expr, false, newFilter)
return AddPredicate(ctx, hj, expr, false, newFilterSinglePredicate)

Check warning on line 109 in go/vt/vtgate/planbuilder/operators/hash_join.go

View check run for this annotation

Codecov / codecov/patch

go/vt/vtgate/planbuilder/operators/hash_join.go#L109

Added line #L109 was not covered by tests
}

func (hj *HashJoin) AddColumn(ctx *plancontext.PlanningContext, reuseExisting bool, addToGroupBy bool, expr *sqlparser.AliasedExpr) int {
Expand Down
7 changes: 2 additions & 5 deletions go/vt/vtgate/planbuilder/operators/horizon.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,17 +94,14 @@ func (h *Horizon) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.
tableInfo, err := ctx.SemTable.TableInfoForExpr(expr)
if err != nil {
if errors.Is(err, semantics.ErrNotSingleTable) {
return &Filter{
Source: h,
Predicates: []sqlparser.Expr{expr},
}
return newFilter(h, expr)
}
panic(err)
}

newExpr := semantics.RewriteDerivedTableExpression(expr, tableInfo)
if sqlparser.ContainsAggregation(newExpr) {
return &Filter{Source: h, Predicates: []sqlparser.Expr{expr}}
return newFilter(h, expr)
}
h.Source = h.Source.AddPredicate(ctx, newExpr)
return h
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operators/join.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func createInnerJoin(ctx *plancontext.PlanningContext, tableExpr *sqlparser.Join
}

func (j *Join) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Expr) Operator {
return AddPredicate(ctx, j, expr, false, newFilter)
return AddPredicate(ctx, j, expr, false, newFilterSinglePredicate)
}

var _ JoinOp = (*Join)(nil)
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/operators/route_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ func pushJoinPredicates(ctx *plancontext.PlanningContext, exprs []sqlparser.Expr
}

for _, expr := range exprs {
AddPredicate(ctx, op, expr, true, newFilter)
AddPredicate(ctx, op, expr, true, newFilterSinglePredicate)
}

return op
Expand Down
5 changes: 1 addition & 4 deletions go/vt/vtgate/planbuilder/operators/subquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,7 @@ func (sq *SubQuery) settleFilter(ctx *plancontext.PlanningContext, outer Operato
predicates = append(predicates, rhsPred)
sq.SubqueryValueName = sq.ArgName
}
return &Filter{
Source: outer,
Predicates: predicates,
}
return newFilter(outer, predicates...)
}

func dontEnterSubqueries(node, _ sqlparser.SQLNode) bool {
Expand Down
14 changes: 4 additions & 10 deletions go/vt/vtgate/planbuilder/operators/subquery_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ func tryMergeSubqueriesRecursively(
finalResult = finalResult.Merge(res)
}

op.Source = &Filter{Source: outer.Source, Predicates: []sqlparser.Expr{subQuery.Original}}
op.Source = newFilter(outer.Source, subQuery.Original)
return op, finalResult.Merge(Rewrote("merge outer of two subqueries"))
}

Expand All @@ -477,7 +477,7 @@ func tryMergeSubqueryWithOuter(ctx *plancontext.PlanningContext, subQuery *SubQu
return outer, NoRewrite
}
if !subQuery.IsProjection {
op.Source = &Filter{Source: outer.Source, Predicates: []sqlparser.Expr{subQuery.Original}}
op.Source = newFilter(outer.Source, subQuery.Original)
}
ctx.MergedSubqueries = append(ctx.MergedSubqueries, subQuery.originalSubquery)
return op, Rewrote("merged subquery with outer")
Expand Down Expand Up @@ -582,10 +582,7 @@ func (s *subqueryRouteMerger) merge(ctx *plancontext.PlanningContext, inner, out
if isSharded {
src = s.outer.Source
if !s.subq.IsProjection {
src = &Filter{
Source: s.outer.Source,
Predicates: []sqlparser.Expr{s.original},
}
src = newFilter(s.outer.Source, s.original)
}
} else {
src = s.rewriteASTExpression(ctx, inner)
Expand Down Expand Up @@ -655,10 +652,7 @@ func (s *subqueryRouteMerger) rewriteASTExpression(ctx *plancontext.PlanningCont
cursor.Replace(subq)
}
}, ctx.SemTable.CopySemanticInfo).(sqlparser.Expr)
src = &Filter{
Source: s.outer.Source,
Predicates: []sqlparser.Expr{sQuery},
}
src = newFilter(s.outer.Source, sQuery)
}
return src
}
Expand Down
5 changes: 1 addition & 4 deletions go/vt/vtgate/planbuilder/operators/union.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,7 @@ func (u *Union) AddPredicate(ctx *plancontext.PlanningContext, expr sqlparser.Ex

needsFilter, exprPerSource := u.predicatePerSource(expr, offsets)
if needsFilter {
return &Filter{
Source: u,
Predicates: []sqlparser.Expr{expr},
}
return newFilter(u, expr)
}

for i, src := range u.Sources {
Expand Down
31 changes: 27 additions & 4 deletions go/vt/vtgate/planbuilder/testdata/cte_cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -1369,8 +1369,8 @@
"Name": "main",
"Sharded": false
},
"FieldQuery": "select u.* from (select * from unsharded where 1 != 1) as u where 1 != 1",
"Query": "select u.* from (select * from unsharded) as u",
"FieldQuery": "with u as (select * from unsharded where 1 != 1) select u.* from u where 1 != 1",
"Query": "with u as (select * from unsharded) select u.* from u",
"Table": "unsharded"
},
"TablesUsed": [
Expand Down Expand Up @@ -1709,8 +1709,8 @@
"Name": "main",
"Sharded": false
},
"FieldQuery": "select col from (select col from unsharded join unsharded_b where 1 != 1) as u join unsharded_a as ua where 1 != 1",
"Query": "select col from (select col from unsharded join unsharded_b) as u join unsharded_a as ua limit 1",
"FieldQuery": "with u as (select col from unsharded join unsharded_b where 1 != 1) select col from u join unsharded_a as ua where 1 != 1",
"Query": "with u as (select col from unsharded join unsharded_b) select col from u join unsharded_a as ua limit 1",
"Table": "unsharded, unsharded_a, unsharded_b"
},
"TablesUsed": [
Expand Down Expand Up @@ -1840,5 +1840,28 @@
"user.user"
]
}
},
{
"comment": "recursive WITH against an unsharded database",
"query": "WITH RECURSIVE cte (n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 5 ) SELECT cte.n FROM unsharded join cte on unsharded.id = cte.n ",
"plan": {
"QueryType": "SELECT",
"Original": "WITH RECURSIVE cte (n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM cte WHERE n < 5 ) SELECT cte.n FROM unsharded join cte on unsharded.id = cte.n ",
"Instructions": {
"OperatorType": "Route",
"Variant": "Unsharded",
"Keyspace": {
"Name": "main",
"Sharded": false
},
"FieldQuery": "with recursive cte(n) as (select 1 from dual where 1 != 1 union all select n + 1 from cte where 1 != 1) select cte.n from unsharded join cte on unsharded.id = cte.n where 1 != 1",
"Query": "with recursive cte(n) as (select 1 from dual union all select n + 1 from cte where n < 5) select cte.n from unsharded join cte on unsharded.id = cte.n",
"Table": "dual, unsharded"
},
"TablesUsed": [
"main.dual",
"main.unsharded"
]
}
}
]
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/testdata/ddl_cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@
"Name": "main",
"Sharded": false
},
"Query": "create view view_a as select col1, col2 from (select col1, col2 from unsharded where id = 1 union select col1, col2 from unsharded where id = 3) as a"
"Query": "create view view_a as select * from (select col1, col2 from unsharded where id = 1 union select col1, col2 from unsharded where id = 3) as a"
},
"TablesUsed": [
"main.view_a"
Expand Down
2 changes: 1 addition & 1 deletion go/vt/vtgate/planbuilder/testdata/filter_cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -4086,7 +4086,7 @@
"Sharded": false
},
"FieldQuery": "select col + 2 as a from unsharded where 1 != 1",
"Query": "select col + 2 as a from unsharded having col + 2 = 42",
"Query": "select col + 2 as a from unsharded having a = 42",
"Table": "unsharded"
},
"TablesUsed": [
Expand Down
24 changes: 12 additions & 12 deletions go/vt/vtgate/planbuilder/testdata/foreignkey_cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@
"Sharded": false
},
"FieldQuery": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = cast(u_tbl2.col1 + 'bar' as CHAR) where 1 != 1",
"Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = cast(u_tbl2.col1 + 'bar' as CHAR) where cast(u_tbl2.col1 + 'bar' as CHAR) is not null and not (u_tbl2.col2) <=> (cast(u_tbl2.col1 + 'bar' as CHAR)) and u_tbl2.id = 1 and u_tbl1.col1 is null limit 1 for share",
"Query": "select 1 from u_tbl2 left join u_tbl1 on u_tbl1.col1 = cast(u_tbl2.col1 + 'bar' as CHAR) where u_tbl1.col1 is null and cast(u_tbl2.col1 + 'bar' as CHAR) is not null and not (u_tbl2.col2) <=> (cast(u_tbl2.col1 + 'bar' as CHAR)) and u_tbl2.id = 1 limit 1 for share",
"Table": "u_tbl1, u_tbl2"
},
{
Expand Down Expand Up @@ -1523,7 +1523,7 @@
"Sharded": false
},
"FieldQuery": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = cast('foo' as CHAR) where 1 != 1",
"Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = cast('foo' as CHAR) where not (u_tbl8.col8) <=> (cast('foo' as CHAR)) and (u_tbl8.col8) in ::fkc_vals and u_tbl9.col9 is null limit 1 for share nowait",
"Query": "select 1 from u_tbl8 left join u_tbl9 on u_tbl9.col9 = cast('foo' as CHAR) where u_tbl9.col9 is null and cast('foo' as CHAR) is not null and not (u_tbl8.col8) <=> (cast('foo' as CHAR)) and (u_tbl8.col8) in ::fkc_vals limit 1 for share nowait",
systay marked this conversation as resolved.
Show resolved Hide resolved
"Table": "u_tbl8, u_tbl9"
},
{
Expand Down Expand Up @@ -1599,7 +1599,7 @@
"Sharded": false
},
"FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast('foo' as CHAR) where 1 != 1",
"Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast('foo' as CHAR) where not (u_tbl4.col4) <=> (cast('foo' as CHAR)) and (u_tbl4.col4) in ::fkc_vals and u_tbl3.col3 is null limit 1 for share",
"Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast('foo' as CHAR) where u_tbl3.col3 is null and cast('foo' as CHAR) is not null and not (u_tbl4.col4) <=> (cast('foo' as CHAR)) and (u_tbl4.col4) in ::fkc_vals limit 1 for share",
systay marked this conversation as resolved.
Show resolved Hide resolved
"Table": "u_tbl3, u_tbl4"
},
{
Expand All @@ -1611,7 +1611,7 @@
"Sharded": false
},
"FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1",
"Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (u_tbl9.col9) not in ((cast('foo' as CHAR))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share",
"Query": "select 1 from u_tbl4, u_tbl9 where u_tbl4.col4 = u_tbl9.col9 and (u_tbl4.col4) in ::fkc_vals and (cast('foo' as CHAR) is null or (u_tbl9.col9) not in ((cast('foo' as CHAR)))) limit 1 for share",
"Table": "u_tbl4, u_tbl9"
},
{
Expand Down Expand Up @@ -1688,7 +1688,7 @@
"Sharded": false
},
"FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:v1 as CHAR) where 1 != 1",
"Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:v1 as CHAR) where not (u_tbl4.col4) <=> (cast(:v1 as CHAR)) and (u_tbl4.col4) in ::fkc_vals and cast(:v1 as CHAR) is not null and u_tbl3.col3 is null limit 1 for share",
"Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:v1 as CHAR) where u_tbl3.col3 is null and cast(:v1 as CHAR) is not null and not (u_tbl4.col4) <=> (cast(:v1 as CHAR)) and (u_tbl4.col4) in ::fkc_vals limit 1 for share",
"Table": "u_tbl3, u_tbl4"
},
{
Expand All @@ -1700,7 +1700,7 @@
"Sharded": false
},
"FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1",
"Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (cast(:v1 as CHAR) is null or (u_tbl9.col9) not in ((cast(:v1 as CHAR)))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share",
"Query": "select 1 from u_tbl4, u_tbl9 where u_tbl4.col4 = u_tbl9.col9 and (u_tbl4.col4) in ::fkc_vals and (cast(:v1 as CHAR) is null or (u_tbl9.col9) not in ((cast(:v1 as CHAR)))) limit 1 for share",
"Table": "u_tbl4, u_tbl9"
},
{
Expand Down Expand Up @@ -2362,7 +2362,7 @@
"Sharded": false
},
"FieldQuery": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:fkc_upd as CHAR) where 1 != 1",
"Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:fkc_upd as CHAR) where not (u_tbl4.col4) <=> (cast(:fkc_upd as CHAR)) and (u_tbl4.col4) in ::fkc_vals and cast(:fkc_upd as CHAR) is not null and u_tbl3.col3 is null limit 1 for share",
"Query": "select 1 from u_tbl4 left join u_tbl3 on u_tbl3.col3 = cast(:fkc_upd as CHAR) where u_tbl3.col3 is null and cast(:fkc_upd as CHAR) is not null and not (u_tbl4.col4) <=> (cast(:fkc_upd as CHAR)) and (u_tbl4.col4) in ::fkc_vals limit 1 for share",
"Table": "u_tbl3, u_tbl4"
},
{
Expand All @@ -2374,7 +2374,7 @@
"Sharded": false
},
"FieldQuery": "select 1 from u_tbl4, u_tbl9 where 1 != 1",
"Query": "select 1 from u_tbl4, u_tbl9 where (u_tbl4.col4) in ::fkc_vals and (cast(:fkc_upd as CHAR) is null or (u_tbl9.col9) not in ((cast(:fkc_upd as CHAR)))) and u_tbl4.col4 = u_tbl9.col9 limit 1 for share",
"Query": "select 1 from u_tbl4, u_tbl9 where u_tbl4.col4 = u_tbl9.col9 and (u_tbl4.col4) in ::fkc_vals and (cast(:fkc_upd as CHAR) is null or (u_tbl9.col9) not in ((cast(:fkc_upd as CHAR)))) limit 1 for share",
"Table": "u_tbl4, u_tbl9"
},
{
Expand Down Expand Up @@ -2537,7 +2537,7 @@
"Sharded": false
},
"FieldQuery": "select 1 from u_multicol_tbl2 left join u_multicol_tbl1 on u_multicol_tbl1.cola = 2 and u_multicol_tbl1.colb = u_multicol_tbl2.colc - 2 where 1 != 1",
"Query": "select 1 from u_multicol_tbl2 left join u_multicol_tbl1 on u_multicol_tbl1.cola = 2 and u_multicol_tbl1.colb = u_multicol_tbl2.colc - 2 where u_multicol_tbl2.colc - 2 is not null and not (u_multicol_tbl2.cola, u_multicol_tbl2.colb) <=> (2, u_multicol_tbl2.colc - 2) and u_multicol_tbl2.id = 7 and u_multicol_tbl1.cola is null and u_multicol_tbl1.colb is null limit 1 for share",
"Query": "select 1 from u_multicol_tbl2 left join u_multicol_tbl1 on u_multicol_tbl1.cola = 2 and u_multicol_tbl1.colb = u_multicol_tbl2.colc - 2 where u_multicol_tbl1.cola is null and 2 is not null and u_multicol_tbl1.colb is null and u_multicol_tbl2.colc - 2 is not null and not (u_multicol_tbl2.cola, u_multicol_tbl2.colb) <=> (2, u_multicol_tbl2.colc - 2) and u_multicol_tbl2.id = 7 limit 1 for share",
"Table": "u_multicol_tbl1, u_multicol_tbl2"
},
{
Expand Down Expand Up @@ -3139,7 +3139,7 @@
"Sharded": false
},
"FieldQuery": "select u_tbl6.col6 from u_tbl6 as u, u_tbl5 as m where 1 != 1",
"Query": "select u_tbl6.col6 from u_tbl6 as u, u_tbl5 as m where u.col2 = 4 and m.col3 = 6 and u.col = m.col for update",
"Query": "select u_tbl6.col6 from u_tbl6 as u, u_tbl5 as m where u.col = m.col and u.col2 = 4 and m.col3 = 6 for update",
"Table": "u_tbl5, u_tbl6"
},
{
Expand Down Expand Up @@ -3197,7 +3197,7 @@
"Sharded": false
},
"FieldQuery": "select u_tbl10.col from u_tbl10, u_tbl11 where 1 != 1",
"Query": "select u_tbl10.col from u_tbl10, u_tbl11 where u_tbl10.id = 5 and u_tbl10.id = u_tbl11.id for update",
"Query": "select u_tbl10.col from u_tbl10, u_tbl11 where u_tbl10.id = u_tbl11.id and u_tbl10.id = 5 for update",
"Table": "u_tbl10, u_tbl11"
},
{
Expand Down Expand Up @@ -3479,7 +3479,7 @@
"Sharded": false
},
"FieldQuery": "select 1 from u_tbl4 left join u_tbl1 on u_tbl1.col14 = cast(:__sq1 as SIGNED) where 1 != 1",
"Query": "select /*+ SET_VAR(foreign_key_checks=OFF) */ 1 from u_tbl4 left join u_tbl1 on u_tbl1.col14 = cast(:__sq1 as SIGNED) where not (u_tbl4.col41) <=> (cast(:__sq1 as SIGNED)) and u_tbl4.col4 = 3 and cast(:__sq1 as SIGNED) is not null and u_tbl1.col14 is null limit 1 lock in share mode",
"Query": "select /*+ SET_VAR(foreign_key_checks=OFF) */ 1 from u_tbl4 left join u_tbl1 on u_tbl1.col14 = cast(:__sq1 as SIGNED) where u_tbl1.col14 is null and cast(:__sq1 as SIGNED) is not null and not (u_tbl4.col41) <=> (cast(:__sq1 as SIGNED)) and u_tbl4.col4 = 3 limit 1 lock in share mode",
"Table": "u_tbl1, u_tbl4"
},
{
Expand Down
Loading
Loading