Skip to content

[common] Do not drop a partition on contradictory partition-key equals - #9632

Open
LuciferYang wants to merge 1 commit into
apache:masterfrom
LuciferYang:fix/partition-key-equal-contradiction
Open

[common] Do not drop a partition on contradictory partition-key equals#9632
LuciferYang wants to merge 1 commit into
apache:masterfrom
LuciferYang:fix/partition-key-equal-contradiction

Conversation

@LuciferYang

Copy link
Copy Markdown
Contributor

Purpose

close #9631

OnlyPartitionKeyEqualVisitor decides whether a DELETE can be turned into a partition drop, and it collects the equality literals into a Map<String, String> keyed by partition key. Two equals on the same key overwrite each other, so pt = 'a' AND pt = 'b' reported "droppable" with partitions() returning {pt=b}: the Flink sink would drop that partition for a predicate that matches no row.

visitEqual now notices when a key already carries a different literal, and visitAnd reports non-droppable in that case. The delete then goes down the normal row-level path, which is what every other predicate shape this visitor does not understand already gets.

Worth stating plainly, because it changes how you may want to prioritize this: I could not construct a SQL statement that reaches it. Calcite folds pt = 'a' AND pt = 'b' to FALSE before applyDeleteFilters sees it, and PredicateBuilder.and does not merge equality predicates on its own. So the protection exists today, but it lives in the planner rather than here, and it does not cover a caller that builds the predicate directly or a future engine binding. Given the consequence is deleting a partition, keeping the decision honest inside the visitor seemed worth the six lines.

Tests

OnlyPartitionKeyEqualVisitorTest covers the three shapes: two conflicting equals on one key report non-droppable, equals on two different keys stay droppable and produce both partition values, and an equal on a non-partition column is not droppable and contributes nothing.

Against the unfixed visitor the first of those fails, reporting droppable.

mvn -pl paimon-common -Dtest=OnlyPartitionKeyEqualVisitorTest,DeletePushDownVisitorTest test on JDK 8: 4 tests, 0 failures. spotless:check and checkstyle:check on paimon-common are clean.

OnlyPartitionKeyEqualVisitor collected partition-key equals into a map,
so pt = 'a' AND pt = 'b' overwrote the first literal and still reported
droppable: the Flink sink would drop partition pt='b' for a predicate
matching no row.

Track the conflict in visitEqual and report non-droppable from
visitAnd. Reaching this from SQL needs a planner that forwards the
contradiction unfolded, which Calcite does not, so this hardens the
contract rather than fixing an observed failure.
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.

[Bug] Contradictory partition-key equals are treated as a partition drop

1 participant