Skip to content

Commit

Permalink
VDiff: Copy non in_keyrange workflow filters to target tablet query (#…
Browse files Browse the repository at this point in the history
…16307)

Signed-off-by: Matt Lord <[email protected]>
  • Loading branch information
mattlord authored Jul 2, 2024
1 parent e827f6b commit 05d7e76
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 10 deletions.
10 changes: 8 additions & 2 deletions go/vt/vttablet/tabletmanager/vdiff/table_plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,14 @@ func (td *tableDiffer) buildTablePlan(dbClient binlogplayer.DBClient, dbName str
return nil, err
}

// Remove in_keyrange. It's not understood by mysql.
sourceSelect.Where = sel.Where // removeKeyrange(sel.Where)
// Copy all workflow filters for the source query.
sourceSelect.Where = sel.Where

// Copy all non-in_keyrange workflow filters to the target query.
// This is important for things like multi-tenant migrations where
// an additional tenant_id filter is applied in the workflow.
targetSelect.Where = copyNonKeyRangeExpressions(sel.Where)

// The source should also perform the group by.
sourceSelect.GroupBy = sel.GroupBy
sourceSelect.OrderBy = tp.orderBy
Expand Down
21 changes: 21 additions & 0 deletions go/vt/vttablet/tabletmanager/vdiff/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"strings"

"vitess.io/vitess/go/vt/sqlparser"
"vitess.io/vitess/go/vt/vtgate/evalengine"

"vitess.io/vitess/go/vt/binlog/binlogplayer"
Expand Down Expand Up @@ -89,3 +90,23 @@ func stringListContains(lst []string, item string) bool {
}
return contains
}

// copyNonKeyRangeExpressions copies all expressions from the input WHERE clause
// to the output WHERE clause except for any in_keyrange() expressions.
func copyNonKeyRangeExpressions(where *sqlparser.Where) *sqlparser.Where {
if where == nil {
return nil
}
exprs := sqlparser.SplitAndExpression(nil, where.Expr)
newWhere := &sqlparser.Where{}
for _, expr := range exprs {
switch expr := expr.(type) {
case *sqlparser.FuncExpr:
if expr.Name.EqualString("in_keyrange") {
continue
}
}
newWhere.Expr = sqlparser.AndExpressions(newWhere.Expr, expr)
}
return newWhere
}
12 changes: 4 additions & 8 deletions go/vt/vttablet/tabletmanager/vdiff/workflow_differ_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,6 @@ func TestBuildPlanSuccess(t *testing.T) {
},
}, {
// in_keyrange on RHS of AND.
// This is currently not a valid construct, but will be supported in the future.
input: &binlogdatapb.Rule{
Match: "t1",
Filter: "select * from t1 where c2 = 2 and in_keyrange('-80')",
Expand All @@ -374,7 +373,7 @@ func TestBuildPlanSuccess(t *testing.T) {
dbName: vdiffDBName,
table: testSchema.TableDefinitions[tableDefMap["t1"]],
sourceQuery: "select c1, c2 from t1 where c2 = 2 and in_keyrange('-80') order by c1 asc",
targetQuery: "select c1, c2 from t1 order by c1 asc",
targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc",
compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}},
comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}},
pkCols: []int{0},
Expand All @@ -386,7 +385,6 @@ func TestBuildPlanSuccess(t *testing.T) {
},
}, {
// in_keyrange on LHS of AND.
// This is currently not a valid construct, but will be supported in the future.
input: &binlogdatapb.Rule{
Match: "t1",
Filter: "select * from t1 where in_keyrange('-80') and c2 = 2",
Expand All @@ -396,7 +394,7 @@ func TestBuildPlanSuccess(t *testing.T) {
dbName: vdiffDBName,
table: testSchema.TableDefinitions[tableDefMap["t1"]],
sourceQuery: "select c1, c2 from t1 where in_keyrange('-80') and c2 = 2 order by c1 asc",
targetQuery: "select c1, c2 from t1 order by c1 asc",
targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc",
compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}},
comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}},
pkCols: []int{0},
Expand All @@ -408,7 +406,6 @@ func TestBuildPlanSuccess(t *testing.T) {
},
}, {
// in_keyrange on cascaded AND expression.
// This is currently not a valid construct, but will be supported in the future.
input: &binlogdatapb.Rule{
Match: "t1",
Filter: "select * from t1 where c2 = 2 and c1 = 1 and in_keyrange('-80')",
Expand All @@ -418,7 +415,7 @@ func TestBuildPlanSuccess(t *testing.T) {
dbName: vdiffDBName,
table: testSchema.TableDefinitions[tableDefMap["t1"]],
sourceQuery: "select c1, c2 from t1 where c2 = 2 and c1 = 1 and in_keyrange('-80') order by c1 asc",
targetQuery: "select c1, c2 from t1 order by c1 asc",
targetQuery: "select c1, c2 from t1 where c2 = 2 and c1 = 1 order by c1 asc",
compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}},
comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}},
pkCols: []int{0},
Expand All @@ -430,7 +427,6 @@ func TestBuildPlanSuccess(t *testing.T) {
},
}, {
// in_keyrange parenthesized.
// This is currently not a valid construct, but will be supported in the future.
input: &binlogdatapb.Rule{
Match: "t1",
Filter: "select * from t1 where (c2 = 2 and in_keyrange('-80'))",
Expand All @@ -440,7 +436,7 @@ func TestBuildPlanSuccess(t *testing.T) {
dbName: vdiffDBName,
table: testSchema.TableDefinitions[tableDefMap["t1"]],
sourceQuery: "select c1, c2 from t1 where c2 = 2 and in_keyrange('-80') order by c1 asc",
targetQuery: "select c1, c2 from t1 order by c1 asc",
targetQuery: "select c1, c2 from t1 where c2 = 2 order by c1 asc",
compareCols: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}, {1, collations.MySQL8().LookupByName(sqltypes.NULL.String()), false, "c2"}},
comparePKs: []compareColInfo{{0, collations.MySQL8().LookupByName(sqltypes.NULL.String()), true, "c1"}},
pkCols: []int{0},
Expand Down

0 comments on commit 05d7e76

Please sign in to comment.