IGNITE-28899 Calcite. Fix litmus error during join#13389
Conversation
| protected final boolean distributed; | ||
|
|
||
| /** Flag indicating that join is in finishing stage (one of the inputs are ended, no more rows will be produced). */ | ||
| protected boolean finishing; |
There was a problem hiding this comment.
how to check this fix : revert all these changes and run : CorrelatesIntegrationTest#testCorrelatesCollision probably need to disable rules:
//NestedLoopJoinConverterRule.INSTANCE,
//HashJoinConverterRule.INSTANCE,
or simply run on master with commented rules
There was a problem hiding this comment.
also seems JoinBuffersExecutionTest need to be expanded somehow, cause it need to catch such a cases but it does not.
| public static final double EQUI_COEFF = 0.8; | ||
|
|
||
| /** */ | ||
| public static final double FK_WITH_PK_COEFF = 0.4; |
There was a problem hiding this comment.
all these coeffs is kinda hacks which need to be removed after statistics layer will properly work
| continue; | ||
|
|
||
| // Keys can relate to affinity not pk, just assumption here. | ||
| ImmutableIntList distKeys = table.distribution().getKeys(); |
There was a problem hiding this comment.
of course we need to have 'real pk' here, but fix it right now - seems too huge.
| inputRows += mq.getRowCount(input); | ||
|
|
||
| double mem = 0.5 * inputRows * aggregateFieldsCount() * IgniteCost.AVERAGE_FIELD_SIZE; | ||
| double mem = 0.7 * inputRows * aggregateFieldsCount() * IgniteCost.AVERAGE_FIELD_SIZE; |
There was a problem hiding this comment.
empiric constants need to be fixed cause row count estimation is changed for now and some tests (2-3) are fails, all empirics need to be reevaluated during further (i hope) statistics activity changes.
|
|
||
| /** Cost of a lookup at the hash. */ | ||
| public static final double HASH_LOOKUP_COST = 10; | ||
| public static final double HASH_LOOKUP_COST = 4; |
There was a problem hiding this comment.
'1' greater than ROW_COMPARISON_COST that correlates, in common, with LN complexity search of hash map, all these empirics need to be fixed during real statistics refactoring activity and currently changed only for store as more as possible tests passed and not changed. I think we understand that tests like we expect affinity distribution some kind of fiction for now and coveres just a little scope of variants.
| prepareTables(); | ||
|
|
||
| String sql = "SELECT sum(i.price * i.amount)" + | ||
| String sql = "SELECT /*+ MERGE_JOIN */ sum(i.price * i.amount)" + |
There was a problem hiding this comment.
Sometimes i observe hashJoin here, i really don`t know what algo is more preferably here and i think it need to be discovered more accurate in further activities.
| private static final int DATE_DIM_SIZE = 73_049; | ||
|
|
||
| /** */ | ||
| private static final String SELECT = "SELECT /*+ DISABLE_RULE(" + |
There was a problem hiding this comment.
Of course it work perfectly well without this disablings, i just afraid about some king of flaky...
| * @throws Exception If failed. | ||
| */ | ||
| @Test | ||
| public void testHashTableAndUnnestJoin() throws Exception { |
There was a problem hiding this comment.
don`t know here, probably we need to remove this test cause it shows nothing for now and returns to it in further activities ?
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Updates Calcite planner metadata/costing and merge-join execution behavior to address a Calcite litmus failure seen during join planning/execution (IGNITE-28899), and adds regression tests to cover the scenario.
Changes:
- Reworked join row-count estimation and adjusted join cost formulas/constants to influence plan selection.
- Modified merge-join runtime node control flow around buffering and early termination.
- Added new planner/integration tests and updated several existing assertions to match the new behavior.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| modules/calcite/src/test/java/org/apache/ignite/testsuites/PlannerTestSuite.java | Registers the new join row-count estimation planner test in the suite. |
| modules/calcite/src/test/java/org/apache/ignite/testsuites/IntegrationTestSuite.java | Adds the new litmus regression integration test to the suite. |
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/hints/JoinTypeHintPlannerTest.java | Relaxes/adjusts hint-related plan assertions (notably around wrong-table hints). |
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/UncollectPlannerTest.java | Updates plan shape expectations for UNNEST + join planning. |
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/PlanSplitterTest.java | Refactors colocation assignments setup to reuse a single assignments instance. |
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/JoinRowCountEstimationTest.java | New planner tests validating join row-count estimation logic. |
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/CorrelatedSubqueryPlannerTest.java | Updates plan assertion for table scan condition presence. |
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/planner/AggregatePlannerTest.java | Removes an early return that skipped part of a test scenario. |
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/QueryBlockingTaskExecutorIntegrationTest.java | Adds hint to force merge join and simplifies plan matching into a single regex check. |
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/LitmusCheckIntegrationTest.java | New integration test meant to catch Calcite litmus exceptions/regressions. |
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/DistributedJoinIntegrationTest.java | Forces MERGE_JOIN via hint for deterministic join plan coverage. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/Commons.java | Adds a helper to build a target mapping from a projected bitset. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/set/IgniteSetOp.java | Adjusts memory estimation coefficient used in set-op costing. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteNestedLoopJoin.java | Revises NLJ cost computation to use metadata row-count and applies an additional penalty factor. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteMergeJoin.java | Revises merge join cost computation to use metadata row-count. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteHashJoin.java | Revises hash join cost computation to use metadata row-count. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/rel/IgniteCorrelatedNestedLoopJoin.java | Revises CNLJ cost computation to use metadata row-count. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/cost/IgniteCost.java | Changes the hash lookup cost constant affecting planner decisions. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdSelectivity.java | Updates metadata provider wiring and exposes selectivity constants for tests/consumers. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdRowCount.java | Implements custom join row-count estimation with PK/FK heuristics and new metadata provider wiring. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/metadata/IgniteMdColumnOrigins.java | Updates metadata provider wiring and minor indentation cleanup. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/MergeJoinNode.java | Reworks buffering/join scheduling and replaces “finishing” cleanup with immediate downstream end conditions. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/CalciteQueryProcessor.java | Removes a previously-added workaround disabling Correlate assertions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (requested > 0 && (leftFinished() || rightFinished(true))) { | ||
| requested = 0; | ||
| downstream().end(); | ||
|
|
||
| return; | ||
| } |
| double selectivity = mq.getSelectivity(rel, rel.getCondition()); | ||
|
|
||
| if (F.isEmpty(leftKeys) || F.isEmpty(rightKeys)) | ||
| return left * right * selectivity; | ||
| return leftRowCnt * rightRowCnt * selectivity; |
| static <T extends RelNode> Predicate<RelNode> nodeRowCount(String nodePattern, Matcher<Integer> rowCountMatcher) { | ||
| Pattern pattern = Pattern.compile(".*" + nodePattern | ||
| + "\\(.*?rowcount = (?<rowcount>\\d+).*"); | ||
|
|
||
| return node -> { | ||
| String plan = RelOptUtil.dumpPlan("", node, SqlExplainFormat.TEXT, SqlExplainLevel.ALL_ATTRIBUTES); | ||
|
|
||
| String sanitized = plan.replace("\n", ""); | ||
| java.util.regex.Matcher matcher = pattern.matcher(sanitized); |
| // Need to be removed after : | ||
| // TODO: https://issues.apache.org/jira/browse/IGNITE-28911 | ||
| assertPlan(String.format(sqlTpl, hintPref + "('UNEXISTING') */"), schema, | ||
| nodeOrAnyChild(isInstanceOf(joinRel)), disabledRules); | ||
| p -> true, disabledRules); |
| /** | ||
| * Creates mapping from given projection. | ||
| * | ||
| * <p>Projection is a list of integers representing an index of element from source | ||
| * at desired position. | ||
| * | ||
| * @param sourceSize Size of the source. | ||
| * @param bitSet Desired projection. | ||
| * @return Mapping for given projection. | ||
| */ | ||
| public static Mappings.TargetMapping projectedMapping(ImmutableBitSet bitSet, int sourceSize) { |
| * Sets the log level for logger ({@link #log}) to {@link Level#DEBUG}. The log level will be resetted to | ||
| * default in {@link #afterTest()}. |
https://issues.apache.org/jira/browse/IGNITE-28899