[core] Validate global-index schema compatibility before reader and coverage - #9402
[core] Validate global-index schema compatibility before reader and coverage#9402QuakeWang wants to merge 5 commits into
Conversation
…overage Global indexes are serialized with the indexed field types from their build schema, while readers use the current table schema. Reusing an incompatible index can miss matches, and counting it in coverage can skip the required data scan. Persist the build schema ID in global-index metadata and compare indexed field types before reader grouping and coverage. Fail closed for legacy metadata and preserve the field across serializers and row-id reassignment. Signed-off-by: QuakeWang <wangfuzheng0814@foxmail.com>
JingsongLi
left a comment
There was a problem hiding this comment.
We should introduce schemaId to IndexManifestEntry, just like DataFileMeta.
|
Agree. I will persist the nullable schema ID on IndexManifestEntry and perform compatibility filtering on manifest entries. To preserve the build-time identity across long-running Flink/Spark index builds, I plan to carry schemaId in IndexFileMeta only as committable transport, copy it to the top-level IndexManifestEntry field in ManifestEntryChanges, and restore it to the transport when an entry is read for delete, copy, or recommit flows. The index manifest will persist it only on IndexManifestEntry, not inside GlobalIndexMeta. Legacy entries will remain null and fail closed. Does this match your intent? |
I think it is OK. |
Persist schema identity on top-level IndexManifestEntry while keeping IndexFileMeta as committable transport. Restore it for delete, copy, and recommit flows, and fail closed for legacy entries. Signed-off-by: QuakeWang <wangfuzheng0814@foxmail.com>
|
Global Index schema compatibility issue: The |
|
[P1] Make the rebuild path replace legacy/incompatible indexes This change makes every pre-upgrade global-index entry ( Filtering those entries out of coverage alone is insufficient: the manifest combiner rejects adding overlapping global-index ranges while the old entries remain. Please partition current entries into compatible/incompatible sets, compute coverage only from compatible entries, add each incompatible range to Please add upgrade tests for both Generic and Sorted planners (and Python): start with a legacy null-schema entry covering the whole table, assert an incremental build schedules the full range plus deletion, commit successfully, and verify the replacement carries the current schema ID. Also cover a non-null entry whose indexed type changed. |
| sourceTable, indexManifestEntries)); | ||
| for (IndexManifestEntry indexManifestEntry : indexManifestEntries) { | ||
| boolean globalIndex = indexManifestEntry.indexFile().globalIndexMeta() != null; | ||
| if (globalIndex && !compatibleGlobalIndexes.contains(indexManifestEntry)) { |
There was a problem hiding this comment.
[P2] Preserve primary-key global-index payloads during copy
This filter applies to every entry with globalIndexMeta() != null, but the production PK payload builders still create their IndexFileMeta without a schema id (PkFullTextIndexFile, PkSortedIndexFile, and PkVectorAnnSegmentFile). ManifestEntryChanges only propagates that null value, so filterCompatible rejects all of these payloads and this branch silently omits them from copy_files. Before this PR they were copied. The target data can generally fall back to raw/exact reads, but the copied table loses all PK sorted/full-text/vector acceleration, and FAST-mode behavior can change.
Please either stamp the build schema id in those PK payload builders and validate them on read, or scope this compatibility filter to index families that actually carry schema identity. A copy test should assert each PK payload remains in the target manifest and produces equivalent queries.
|
[P2] Apply schema compatibility to the explicit-file scanner overload too
Java metas now transport |
# Conflicts: # paimon-spark/paimon-spark-common/src/test/java/org/apache/paimon/spark/copy/CopyFilesUtilTest.java
Purpose
Global indexes are written with serializers derived from the build schema, while readers use the current table schema. After an indexed field type evolves, reusing an old index can miss matches, and counting that index in coverage can incorrectly skip the required data scan.
This change records the build schema ID in global-index metadata and centrally compares the indexed fields' logical types before reader grouping and coverage calculation. Legacy metadata without a build schema ID fails closed, and the new field is preserved across builders, serializers, and row-ID reassignment.
Tests