Skip to content

Commit 881b93a

Browse files
VDiff: Copy non in_keyrange workflow filters to target tablet query (#16307)
Signed-off-by: Matt Lord <mattalord@gmail.com>
1 parent f9e613f commit 881b93a

File tree

3 files changed

+33
-10
lines changed

3 files changed

+33
-10
lines changed

go/vt/vttablet/tabletmanager/vdiff/table_plan.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,14 @@ func (td *tableDiffer) buildTablePlan(dbClient binlogplayer.DBClient, dbName str
174174
return nil, err
175175
}
176176

177-
// Remove in_keyrange. It's not understood by mysql.
178-
sourceSelect.Where = sel.Where // removeKeyrange(sel.Where)
177+
// Copy all workflow filters for the source query.
178+
sourceSelect.Where = sel.Where
179+
180+
// Copy all non-in_keyrange workflow filters to the target query.
181+
// This is important for things like multi-tenant migrations where
182+
// an additional tenant_id filter is applied in the workflow.
183+
targetSelect.Where = copyNonKeyRangeExpressions(sel.Where)
184+
179185
// The source should also perform the group by.
180186
sourceSelect.GroupBy = sel.GroupBy
181187
sourceSelect.OrderBy = tp.orderBy

go/vt/vttablet/tabletmanager/vdiff/utils.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222
"strings"
2323

24+
"vitess.io/vitess/go/vt/sqlparser"
2425
"vitess.io/vitess/go/vt/vtgate/evalengine"
2526

2627
"vitess.io/vitess/go/vt/binlog/binlogplayer"
@@ -89,3 +90,23 @@ func stringListContains(lst []string, item string) bool {
8990
}
9091
return contains
9192
}
93+
94+
// copyNonKeyRangeExpressions copies all expressions from the input WHERE clause
95+
// to the output WHERE clause except for any in_keyrange() expressions.
96+
func copyNonKeyRangeExpressions(where *sqlparser.Where) *sqlparser.Where {
97+
if where == nil {
98+
return nil
99+
}
100+
exprs := sqlparser.SplitAndExpression(nil, where.Expr)
101+
newWhere := &sqlparser.Where{}
102+
for _, expr := range exprs {
103+
switch expr := expr.(type) {
104+
case *sqlparser.FuncExpr:
105+
if expr.Name.EqualString("in_keyrange") {
106+
continue
107+
}
108+
}
109+
newWhere.Expr = sqlparser.AndExpressions(newWhere.Expr, expr)
110+
}
111+
return newWhere
112+
}

go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,6 @@ func TestBuildPlanSuccess(t *testing.T) {
364364
},
365365
}, {
366366
// in_keyrange on RHS of AND.
367-
// This is currently not a valid construct, but will be supported in the future.
368367
input: &binlogdatapb.Rule{
369368
Match: "t1",
370369
Filter: "select * from t1 where c2 = 2 and in_keyrange('-80')",
@@ -374,7 +373,7 @@ func TestBuildPlanSuccess(t *testing.T) {
374373
dbName: vdiffDBName,
375374
table: testSchema.TableDefinitions[tableDefMap["t1"]],
376375
sourceQuery: "select c1, c2 from t1 where c2 = 2 and in_keyrange('-80') order by c1 asc",
377-
targetQuery: "select c1, c2 from t1 order by c1 asc",
376+
targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc",
378377
compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}},
379378
comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}},
380379
pkCols: []int{0},
@@ -386,7 +385,6 @@ func TestBuildPlanSuccess(t *testing.T) {
386385
},
387386
}, {
388387
// in_keyrange on LHS of AND.
389-
// This is currently not a valid construct, but will be supported in the future.
390388
input: &binlogdatapb.Rule{
391389
Match: "t1",
392390
Filter: "select * from t1 where in_keyrange('-80') and c2 = 2",
@@ -396,7 +394,7 @@ func TestBuildPlanSuccess(t *testing.T) {
396394
dbName: vdiffDBName,
397395
table: testSchema.TableDefinitions[tableDefMap["t1"]],
398396
sourceQuery: "select c1, c2 from t1 where in_keyrange('-80') and c2 = 2 order by c1 asc",
399-
targetQuery: "select c1, c2 from t1 order by c1 asc",
397+
targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc",
400398
compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}},
401399
comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}},
402400
pkCols: []int{0},
@@ -408,7 +406,6 @@ func TestBuildPlanSuccess(t *testing.T) {
408406
},
409407
}, {
410408
// in_keyrange on cascaded AND expression.
411-
// This is currently not a valid construct, but will be supported in the future.
412409
input: &binlogdatapb.Rule{
413410
Match: "t1",
414411
Filter: "select * from t1 where c2 = 2 and c1 = 1 and in_keyrange('-80')",
@@ -418,7 +415,7 @@ func TestBuildPlanSuccess(t *testing.T) {
418415
dbName: vdiffDBName,
419416
table: testSchema.TableDefinitions[tableDefMap["t1"]],
420417
sourceQuery: "select c1, c2 from t1 where c2 = 2 and c1 = 1 and in_keyrange('-80') order by c1 asc",
421-
targetQuery: "select c1, c2 from t1 order by c1 asc",
418+
targetQuery: "select c1, c2 from t1 where c2 = 2 and c1 = 1 order by c1 asc",
422419
compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}},
423420
comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}},
424421
pkCols: []int{0},
@@ -430,7 +427,6 @@ func TestBuildPlanSuccess(t *testing.T) {
430427
},
431428
}, {
432429
// in_keyrange parenthesized.
433-
// This is currently not a valid construct, but will be supported in the future.
434430
input: &binlogdatapb.Rule{
435431
Match: "t1",
436432
Filter: "select * from t1 where (c2 = 2 and in_keyrange('-80'))",
@@ -440,7 +436,7 @@ func TestBuildPlanSuccess(t *testing.T) {
440436
dbName: vdiffDBName,
441437
table: testSchema.TableDefinitions[tableDefMap["t1"]],
442438
sourceQuery: "select c1, c2 from t1 where c2 = 2 and in_keyrange('-80') order by c1 asc",
443-
targetQuery: "select c1, c2 from t1 order by c1 asc",
439+
targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc",
444440
compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}},
445441
comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}},
446442
pkCols: []int{0},

0 commit comments

Comments
 (0)