Skip to content

fix(table): return scanner memoization errors#1333

Open
fallintoplace wants to merge 2 commits into
apache:mainfrom
fallintoplace:fix/scanner-memoization-error-propagation
Open

fix(table): return scanner memoization errors#1333
fallintoplace wants to merge 2 commits into
apache:mainfrom
fallintoplace:fix/scanner-memoization-error-propagation

Conversation

@fallintoplace

Copy link
Copy Markdown
Contributor

Summary

replace the panic-wrapping memoized factory helper with an error-carrying cache
propagate cached factory errors through scanner planning, filtered overwrite classification, and conflict validation
add regression coverage for cached factory failures and an invalid-spec manifest path that used to panic

Why

The scanner code memoized several per-spec builders using newKeyDefaultMapWrapErr, which converted any factory error into a panic. That meant ordinary failures like unknown partition spec ids or projection/evaluator build errors could crash the process instead of being returned to the caller.

The shared helper is also reused in transaction-side manifest classification and conflict validation, so the same panic behavior leaked there too.

Testing

go test ./table -run 'Test(KeyDefaultMapWrapErrCachesError|FetchPartitionSpecFilteredManifests_InvalidSpecIDDoesNotPanic|BuildPartitionProjectionWithInvalidSpecID|BuildManifestEvaluatorWithInvalidSpecID|BuildPartitionEvaluatorWithInvalidSpecID|FetchPartitionSpecFilteredManifests_PropagatesEvalError)$' -count=1
go test ./table -count=1
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.11.4 run --timeout=10m ./table/...
git diff --check

@fallintoplace fallintoplace requested a review from zeroshade as a code owner June 27, 2026 14:59

@tanmayrauth tanmayrauth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean fix, turning these memoization panics into propagated errors is the right call, and reusing the existing double-checked-locking pattern keeps the concurrency behavior identical. Just two nits and one confirmation, all inline.

Comment thread table/transaction.go Outdated
if err != nil {
return fmt.Errorf("failed to build manifest evaluator for spec %d: %w", manifest.PartitionSpecID(), err)
}
if manifestEval != nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if manifestEval != nil guard is dead now that the err != nil return runs first, buildManifestEvaluator only ever returns a nil func alongside a non-nil error, so past line 1548 this is always true. Harmless, but could be dropped to make the intent clearer.

Comment thread table/conflict_validation.go Outdated
mEval := manifestEvals.Get(int(mf.PartitionSpecID()))
mEval, err := manifestEvals.Get(int(mf.PartitionSpecID()))
if err != nil {
return fmt.Errorf("building manifest evaluator for spec %d: %w", mf.PartitionSpecID(), err)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tiny consistency nit: here the wrap is "building manifest evaluator for spec %d" (and "building partition evaluator..." on 393), but the equivalent wraps in scanner.go:626 and transaction.go:1547 say "failed to build ...". Worth aligning the prefix across the three so the messages read uniformly.

Comment thread table/scanner.go
}

k.mx.RUnlock()
k.mx.Lock()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just confirming the intent: caching the error means a failing factory is never retried for that spec id (the new TestKeyDefaultMapWrapErrCachesError pins this). That's fine for these deterministic errors, unknown spec id, projection build failure but wanted to flag it explicitly since it's a behavior the helper now guarantees, not just an implementation detail.

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