diff --git a/go/vt/vtctl/workflow/sequences.go b/go/vt/vtctl/workflow/sequences.go index 5c1e2ca7fa6..e1a13b96b72 100644 --- a/go/vt/vtctl/workflow/sequences.go +++ b/go/vt/vtctl/workflow/sequences.go @@ -166,18 +166,21 @@ func (ts *trafficSwitcher) getMaxSequenceValue(ctx context.Context, seq *sequenc Query: []byte(query.Query), MaxRows: 1, }) - if terr != nil || len(qr.Rows) != 1 { + if terr != nil { return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "failed to get the max used sequence value for target table %s.%s on tablet %s in order to initialize the backing sequence table: %v", ts.targetKeyspace, seq.usingTableName, topoproto.TabletAliasString(primary.Alias), terr) } - rawVal := sqltypes.Proto3ToResult(qr).Rows[0][0] maxID := int64(0) - if !rawVal.IsNull() { // If it's NULL then there are no rows and 0 remains the max - maxID, terr = rawVal.ToInt64() - if terr != nil { - return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "failed to get the max used sequence value for target table %s.%s on tablet %s in order to initialize the backing sequence table: %v", - ts.targetKeyspace, seq.usingTableName, topoproto.TabletAliasString(primary.Alias), terr) + // If no rows are returned, max remains 0. + if len(qr.Rows) != 0 { + rawVal := sqltypes.Proto3ToResult(qr).Rows[0][0] + if !rawVal.IsNull() { // If it's NULL then 0 remains the max + maxID, terr = rawVal.ToInt64() + if terr != nil { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "failed to get the max used sequence value for target table %s.%s on tablet %s in order to initialize the backing sequence table: %v", + ts.targetKeyspace, seq.usingTableName, topoproto.TabletAliasString(primary.Alias), terr) + } } } setMaxSequenceValue(maxID) @@ -352,9 +355,6 @@ func (ts *trafficSwitcher) initializeTargetSequences(ctx context.Context, sequen } for _, sm := range sequencesByBackingTable { maxValue := maxValues[sm.backingTableName] - if maxValue == 0 { - continue - } if err := ts.updateSequenceValue(ctx, sm, maxValue); err != nil { return err } diff --git a/go/vt/vtctl/workflow/sequences_test.go b/go/vt/vtctl/workflow/sequences_test.go index 61b020c1e2a..3822e2822a3 100644 --- a/go/vt/vtctl/workflow/sequences_test.go +++ b/go/vt/vtctl/workflow/sequences_test.go @@ -28,12 +28,13 @@ import ( "vitess.io/vitess/go/sqlescape" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/mysqlctl/tmutils" - tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" "vitess.io/vitess/go/vt/proto/vschema" - vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vttablet/tabletmanager/vreplication" + + tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) func TestInitializeTargetSequences(t *testing.T) { @@ -89,16 +90,48 @@ func TestInitializeTargetSequences(t *testing.T) { }, } - env.tmc.expectVRQuery(200, "/select max.*", sqltypes.MakeTestResult(sqltypes.MakeTestFields("maxval", "int64"), "34")) - // Expect the insert query to be executed with 35 as a params, since we provide a maxID of 34 in the last query - env.tmc.expectVRQuery(100, "/insert into.*35.*", &sqltypes.Result{RowsAffected: 1}) + type testCase struct { + name string + selectMaxQuery string + selectMaxResult *sqltypes.Result + insertQuery string + } - err = sw.initializeTargetSequences(ctx, sequencesByBackingTable) - assert.NoError(t, err) + testCases := []testCase{ + { + name: "initialize sequences", + selectMaxQuery: "/select max.*", + selectMaxResult: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("maxval", "int64"), + "34", + ), + insertQuery: "/insert into.*35.*", + }, + { + name: "initialize sequences for empty tables", + selectMaxQuery: "/select max.*", + selectMaxResult: sqltypes.MakeTestResult( + sqltypes.MakeTestFields("maxval", "int64"), + ), + insertQuery: "/insert into.*1.*", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Expect the select max query to be executed + env.tmc.expectVRQuery(200, tc.selectMaxQuery, tc.selectMaxResult) + // Expect the insert query to be executed + env.tmc.expectVRQuery(100, tc.insertQuery, &sqltypes.Result{RowsAffected: 1}) + + err = sw.initializeTargetSequences(ctx, sequencesByBackingTable) + assert.NoError(t, err) - // Expect the queries to be cleared - assert.Emptyf(t, env.tmc.vrQueries[100], "expected no queries to be executed, found: %q", env.tmc.vrQueries[100]) - assert.Empty(t, env.tmc.vrQueries[200], "expected no queries to be executed, found: %q", env.tmc.vrQueries[200]) + // Expect the queries to be cleared + assert.Emptyf(t, env.tmc.vrQueries[100], "expected no queries to be executed, found: %q", env.tmc.vrQueries[100]) + assert.Empty(t, env.tmc.vrQueries[200], "expected no queries to be executed, found: %q", env.tmc.vrQueries[200]) + }) + } } func TestGetTargetSequenceMetadata(t *testing.T) {