From 8a6fe42fc0f9d34980d1bf23df3d077bf4adb693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Sat, 23 Mar 2024 08:00:17 +0100 Subject: [PATCH] bugfix: handling of ANDed join predicates (#15551) Signed-off-by: Andres Taylor --- .../planbuilder/operators/apply_join.go | 11 ++++++--- .../planbuilder/operators/expressions.go | 1 - .../planbuilder/testdata/select_cases.json | 24 +++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/go/vt/vtgate/planbuilder/operators/apply_join.go b/go/vt/vtgate/planbuilder/operators/apply_join.go index 2e72f2eae57..043e76b5e15 100644 --- a/go/vt/vtgate/planbuilder/operators/apply_join.go +++ b/go/vt/vtgate/planbuilder/operators/apply_join.go @@ -156,9 +156,14 @@ func (aj *ApplyJoin) AddJoinPredicate(ctx *plancontext.PlanningContext, expr sql if expr == nil { return } - col := breakExpressionInLHSandRHSForApplyJoin(ctx, expr, TableID(aj.LHS)) - aj.JoinPredicates.add(col) - rhs := aj.RHS.AddPredicate(ctx, col.RHSExpr) + rhs := aj.RHS + predicates := sqlparser.SplitAndExpression(nil, expr) + for _, pred := range predicates { + col := breakExpressionInLHSandRHSForApplyJoin(ctx, pred, TableID(aj.LHS)) + aj.JoinPredicates.add(col) + ctx.AddJoinPredicates(pred, col.RHSExpr) + rhs = rhs.AddPredicate(ctx, col.RHSExpr) + } aj.RHS = rhs } diff --git a/go/vt/vtgate/planbuilder/operators/expressions.go b/go/vt/vtgate/planbuilder/operators/expressions.go index 1b9194c35fa..612c1e7ec08 100644 --- a/go/vt/vtgate/planbuilder/operators/expressions.go +++ b/go/vt/vtgate/planbuilder/operators/expressions.go @@ -51,7 +51,6 @@ func breakExpressionInLHSandRHSForApplyJoin( cursor.Replace(arg) }, nil).(sqlparser.Expr) - ctx.AddJoinPredicates(expr, rewrittenExpr) col.RHSExpr = rewrittenExpr col.Original = expr return diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json index bfae85a08b2..9707fa68d2c 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.json +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json @@ -2658,6 +2658,30 @@ ] } }, + { + "comment": "Complex join with multiple conditions merged into single route", + "query": "select 0 from user as u join user_extra as s on u.id = s.user_id join music as m on m.user_id = u.id and (s.foo or m.bar)", + "plan": { + "QueryType": "SELECT", + "Original": "select 0 from user as u join user_extra as s on u.id = s.user_id join music as m on m.user_id = u.id and (s.foo or m.bar)", + "Instructions": { + "OperatorType": "Route", + "Variant": "Scatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select 0 from `user` as u, user_extra as s, music as m where 1 != 1", + "Query": "select 0 from `user` as u, user_extra as s, music as m where u.id = s.user_id and m.user_id = u.id and (s.foo or m.bar)", + "Table": "`user`, music, user_extra" + }, + "TablesUsed": [ + "user.music", + "user.user", + "user.user_extra" + ] + } + }, { "comment": "union as a derived table", "query": "select found from (select id as found from user union all (select id from unsharded)) as t",