Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 55 additions & 13 deletions go/vt/vttablet/endtoend/sequence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"reflect"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"vitess.io/vitess/go/sqltypes"
"vitess.io/vitess/go/vt/vttablet/endtoend/framework"

Expand All @@ -28,7 +30,7 @@ import (
)

func TestSequence(t *testing.T) {
want := sqltypes.Result{
want := &sqltypes.Result{
Fields: []*querypb.Field{{
Name: "nextval",
Type: sqltypes.Int64,
Expand All @@ -41,29 +43,69 @@ func TestSequence(t *testing.T) {
for wantval := int64(1); wantval < 10; wantval += 2 {
want.Rows[0][0] = sqltypes.NewInt64(wantval)
qr, err := framework.NewClient().Execute("select next 2 values from vitess_seq", nil)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(*qr, want) {
t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)
}
require.NoError(t, err)
assert.Equal(t, want, qr)
}

// Verify that the table got updated according to chunk size.
want = sqltypes.Result{
qr, err := framework.NewClient().Execute("select next_id, cache from vitess_seq", nil)
require.NoError(t, err)
qr.Fields = nil

want = &sqltypes.Result{
RowsAffected: 1,
Rows: [][]sqltypes.Value{{
sqltypes.NewInt64(13),
sqltypes.NewInt64(3),
}},
}
qr, err := framework.NewClient().Execute("select next_id, cache from vitess_seq", nil)
if err != nil {
t.Fatal(err)
assert.Equal(t, want, qr)

// Mess up the sequence by reducing next_id
_, err = framework.NewClient().Execute("update vitess_seq set next_id=1", nil)
require.NoError(t, err)
qr, err = framework.NewClient().Execute("select next 3 values from vitess_seq", nil)
require.NoError(t, err)
qr.Fields = nil

// Next value generated should be based on the LastVal
want = &sqltypes.Result{
RowsAffected: 1,
Rows: [][]sqltypes.Value{{
sqltypes.NewInt64(13),
}},
}
assert.Equal(t, want, qr)

// next_id should be reset to LastVal+cache
qr, err = framework.NewClient().Execute("select next_id, cache from vitess_seq", nil)
require.NoError(t, err)
qr.Fields = nil
if !reflect.DeepEqual(*qr, want) {
t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)

want = &sqltypes.Result{
RowsAffected: 1,
Rows: [][]sqltypes.Value{{
sqltypes.NewInt64(16),
sqltypes.NewInt64(3),
}},
}
assert.Equal(t, want, qr)

// Change next_id to a very high value
_, err = framework.NewClient().Execute("update vitess_seq set next_id=100", nil)
require.NoError(t, err)
qr, err = framework.NewClient().Execute("select next 3 values from vitess_seq", nil)
require.NoError(t, err)
qr.Fields = nil

// Next value should jump to the high value
want = &sqltypes.Result{
RowsAffected: 1,
Rows: [][]sqltypes.Value{{
sqltypes.NewInt64(100),
}},
}
assert.Equal(t, want, qr)
}

func TestResetSequence(t *testing.T) {
Expand Down
11 changes: 9 additions & 2 deletions go/vt/vttablet/tabletserver/query_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,9 +480,16 @@ func (qre *QueryExecutor) execNextval() (*sqltypes.Result, error) {
if err != nil {
return nil, vterrors.Wrapf(err, "error loading sequence %s", tableName)
}
// Initialize SequenceInfo.NextVal if it wasn't already.
if t.SequenceInfo.NextVal == 0 {
// If LastVal does not match next ID, then either:
// VTTablet just started, and we're initializing the cache, or
// Someone reset the id underneath us.
if t.SequenceInfo.LastVal != nextID {
if nextID < t.SequenceInfo.LastVal {
log.Warningf("Sequence next ID value %v is below the currently cached max %v, updating it to max", nextID, t.SequenceInfo.LastVal)
nextID = t.SequenceInfo.LastVal
}
t.SequenceInfo.NextVal = nextID
t.SequenceInfo.LastVal = nextID
}
cache, err := sqltypes.ToInt64(qr.Rows[0][1])
if err != nil {
Expand Down