Skip to content

Validate rowIndex in Tablet.SetTimestamp#169

Open
PDGGK wants to merge 1 commit into
apache:mainfrom
PDGGK:fix/set-timestamp-bounds
Open

Validate rowIndex in Tablet.SetTimestamp#169
PDGGK wants to merge 1 commit into
apache:mainfrom
PDGGK:fix/set-timestamp-bounds

Conversation

@PDGGK

@PDGGK PDGGK commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Problem

Thanks @HTHou — you noted in #168 that Tablet.SetTimestamp writes to
t.timestamps[rowIndex] without validating rowIndex, so an out-of-range
row panics with an index-out-of-range error instead of returning one. For
example, with a tablet created via NewTablet(..., 1) (only row index 0 is
valid), SetTimestamp(ts, 1) panics.

Fix

Apply the same bounds check SetValueAt and GetValueAt already use,
returning an illegal argument rowIndex error for a negative or
out-of-range row:

func (t *Tablet) SetTimestamp(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
}

You noted this needs an API decision, since SetTimestamp has no error
return. I've taken the consistency direction your comment pointed to:
SetTimestamp now returns an error, matching SetValueAt / GetValueAt.
It is a signature change, but source-compatible for the common
statement-form call — the examples already invoke SetValueAt that way —
and go build ./... passes unchanged. If you'd prefer a non-breaking shape
instead, I'm happy to switch.

Tests

Added TestTablet_SetTimestampRowIndexBounds: a valid row index returns no
error; out-of-range indices (1 on a one-row tablet, and -1) return an error
instead of panicking. go build ./... and go test ./client/ pass.

Follow-up to #168.

SetTimestamp wrote to t.timestamps[rowIndex] without validating rowIndex,
so a call with an out-of-range row (e.g. SetTimestamp(ts, 1) on a tablet
created with NewTablet(..., 1)) panicked with an index-out-of-range error
instead of returning an error. Apply the same bounds check that
SetValueAt and GetValueAt use so it returns an "illegal argument rowIndex"
error, and add a regression test.

Follow-up to apache#168.

Signed-off-by: Zihan Dai <99155080+PDGGK@users.noreply.github.com>
@HTHou

HTHou commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Could we preserve the existing SetTimestamp(timestamp int64, rowIndex int) signature and introduce a checked API such as SetTimestampAt(timestamp int64, rowIndex int) error instead?

Adding an error result to the existing exported method is not fully source-compatible. Statement-form calls still compile, but consumers using an interface or method value will break, for example:

type TimestampSetter interface {
    SetTimestamp(int64, int)
}

var _ TimestampSetter = (*client.Tablet)(nil)
var setter func(int64, int) = tablet.SetTimestamp

Since this module already has v2 releases, keeping SetTimestamp unchanged would preserve compatibility, while SetTimestampAt can perform the new bounds validation and return illegal argument rowIndex errors. The existing method could be deprecated in documentation later if callers should migrate to the checked API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants