diff --git a/client/tablet.go b/client/tablet.go index 04d828b..d694d6f 100644 --- a/client/tablet.go +++ b/client/tablet.go @@ -108,6 +108,19 @@ func (t *Tablet) SetTimestamp(timestamp int64, rowIndex int) { t.timestamps[rowIndex] = timestamp } +// SetTimestampAt is a bounds-checked alternative to SetTimestamp. It validates +// rowIndex and returns an "illegal argument rowIndex" error instead of +// panicking with an index-out-of-range when rowIndex is negative or beyond the +// tablet's capacity, consistent with SetValueAt and GetValueAt. The existing +// SetTimestamp is preserved unchanged for source compatibility. +func (t *Tablet) SetTimestampAt(timestamp int64, rowIndex int) error { + if rowIndex < 0 || rowIndex >= t.maxRowNumber { + return fmt.Errorf("illegal argument rowIndex %d", rowIndex) + } + t.timestamps[rowIndex] = timestamp + return nil +} + func (t *Tablet) SetValueAt(value interface{}, columnIndex, rowIndex int) error { if columnIndex < 0 || columnIndex >= len(t.measurementSchemas) { diff --git a/client/tablet_test.go b/client/tablet_test.go index cd01d72..d6f701d 100644 --- a/client/tablet_test.go +++ b/client/tablet_test.go @@ -173,6 +173,24 @@ func TestTablet_SetTimestamp(t *testing.T) { } } +func TestTablet_SetTimestampAtRowIndexBounds(t *testing.T) { + tablet, err := createTablet(1) // maxRowNumber == 1, so only row index 0 is valid + if err != nil { + t.Fatal(err) + } + // A valid row index returns no error. + if err := tablet.SetTimestampAt(1608268702769, 0); err != nil { + t.Errorf("SetTimestampAt(_, 0) on a 1-row tablet returned error: %v", err) + } + // Out-of-range row indices return an error instead of panicking with an + // index-out-of-range, matching SetValueAt/GetValueAt. + for _, rowIndex := range []int{1, -1} { + if err := tablet.SetTimestampAt(1, rowIndex); err == nil { + t.Errorf("SetTimestampAt(_, %d) on a 1-row tablet should return an error, got nil", rowIndex) + } + } +} + func TestTablet_SetValueAt(t *testing.T) { type args struct { value interface{}