fix(scan): share bucket pruning across append and key-value scans - #284
fix(scan): share bucket pruning across append and key-value scans#284wangyong9999 wants to merge 4 commits into
Conversation
|
C++ already performs predicate-to-bucket conversion for |
|
@lxy-9602 Fixed in 9aca26d. I reproduced the KV bug: with the current option set to 4 buckets, a matching file written with 2 buckets was discarded. Selector setup and entry filtering now live in Explicit bucket filters still take precedence. Different schema IDs retain the conservative fallback. Inferred KV scans now also skip the manifest-level bucket optimization and bucket-specific cache, since a single inferred bucket is unsafe across rescaling. The description calls out this tradeoff. Added regressions for both scans and extended the real-file scan/read tests to current bucket options of 2, 4, 8 and 17. The two unit regressions failed before the fix; 46 unit tests and 81 integration tests pass now. The build and pre-commit checks pass too. |
|
The four workflows for the latest commit, |
Purpose
Linked issue: N/A.
Fixed-bucket append scans retain other buckets even when equality predicates fully specify the bucket key. The existing KV scan has the opposite problem after rescaling: it applies a single bucket computed from the current table option to files written with other bucket counts, which can drop matching data.
Both scans now use a shared selector in
FileStoreScan. The converter builds the key row and bucket function once; each manifest entry is checked using its ownTotalBuckets(). Explicit bucket filters keep their existing semantics and take precedence. Historical schemas remain eligible when their ordered bucket-key field IDs, Arrow types and bucket function match. Only incompatible bucket schemas or nonpositive total bucket counts fall back to the existing filtering behavior. Incomplete/non-equality predicates and bucket-unaware tables do not enable inference.Inferred pruning runs at the manifest-entry level for both scan types. Manifest min/max-bucket skipping still requires an explicit filter. Inferred scans now also use the snapshot live-entry cache: its key includes the selected bucket, current bucket count and current schema ID, and its candidates retain files from other counts or schemas. Query predicates and the selector run after cache lookup. This restores repeated-lookup caching without losing historical files or leaking one query's filtering into another.
Bucket-schema compatibility is memoized per file schema ID. Historical schema reads use the existing
ConcurrentHashMaputility because manifest filtering runs in parallel.Decimal literals are converted to the field's precision and scale only when their value is preserved exactly. NaN literals disable inference because equal NaNs can have different stored hashes.
Tests
9aca26dbbefore this follow-up.The incremental build passed with GCC 8, C++17 and default
-Wall, without warnings. All pre-commit hooks passed. The full test suite, aarch64 and downstream KV RPC E2E were not run. Upstream CI requires maintainer approval; local checks are not a substitute for it.Earlier measurement at
5ebbaf33, before the shared-selector follow-up (Release, local disk, warm OS cache, Parquet, prefetch off): 64 buckets, 4 manifests, 256 files, 16,384 rows with 512-byte seeded random values. Both versions used the same persisted table; each configuration warmed up for 40 lookups and measured 40. All lookups returned the expected four rows. The baseline restores only the append scan implementation fromead92078; the fixed version was measured both before and after baseline with similar results.5ebbaf335ebbaf33The improvement is in data-file reads. Planning time is essentially unchanged. This is a small local comparison with four manifests, not a many-manifest or downstream RPC benchmark.
API and Format
Added an overload of
CacheKey::ForSnapshotLiveManifestEntriesfor inferred candidates scoped by bucket count and schema ID. The existing exported three-argument factory remains available. No protocol or storage format changes. Explicit bucket filtering retains its existing semantics.Documentation
Updated
docs/source/api/scan.rstwith shared pruning, per-entry bucket counts, compatible historical schemas and inferred cache behavior.Generative AI tooling
Generated-by: Codex (GPT-6)