[ https://issues.apache.org/jira/browse/CALCITE-4995?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Ruben Q L resolved CALCITE-4995. -------------------------------- Resolution: Fixed > AssertionError caused by RelFieldTrimmer on SEMI/ANTI join > ---------------------------------------------------------- > > Key: CALCITE-4995 > URL: https://issues.apache.org/jira/browse/CALCITE-4995 > Project: Calcite > Issue Type: Bug > Components: core > Affects Versions: 1.29.0 > Reporter: Ruben Q L > Assignee: Ruben Q L > Priority: Major > Labels: pull-request-available > Fix For: 1.30.0 > > Time Spent: 0.5h > Remaining Estimate: 0h > > It seems {{RelFieldTrimmer}} can cause an {{AssertionError}} (or later an > {{ArrayIndexOutOfBoundsException}} if assertions are disabled) on certain > plans involving SEMI/ANTI join (i.e. joins that do NOT project the RHS > fields). > The root cause seems to be the "early return" in > {{RelFieldTrimmer#trimFields(Join join, ImmutableBitSet fieldsUsed, > Set<RelDataTypeField> extraFields)}} when nothing has been trimmed inside > join's inputs (so the join itself can be return as it is): > {code:java} > if (changeCount == 0 > && mapping.isIdentity()) { > return result(join, Mappings.createIdentity(fieldCount)); > } > {code} > The problem is that this {{fieldCount}} is an addition of LHS + RHS fields (+ > system fields); but in case of a SEMI/ANTI the mappings to be returned must > not consider RHS fields (since they are not projected by these join types). > The problem only happens here (when the trimmer does not trim the join). > Notice that, a few lines below, in the "other return scenario" of the method > (when something has been trimmed), there is a special treatment of the > mapping for ANTI/SEMI, so things will work fine in this case: > {code:java} > switch (join.getJoinType()) { > case SEMI: > case ANTI: > // For SemiJoins and AntiJoins only map fields from the left-side > if (join.getJoinType() == JoinRelType.SEMI) { > relBuilder.semiJoin(newConditionExpr); > } else { > relBuilder.antiJoin(newConditionExpr); > } > Mapping inputMapping = inputMappings.get(0); > mapping = Mappings.create(MappingType.INVERSE_SURJECTION, > join.getRowType().getFieldCount(), > newSystemFieldCount + inputMapping.getTargetCount()); > for (int i = 0; i < newSystemFieldCount; ++i) { > mapping.set(i, i); > } > offset = systemFieldCount; > newOffset = newSystemFieldCount; > for (IntPair pair : inputMapping) { > mapping.set(pair.source + offset, pair.target + newOffset); > } > break; > default: > relBuilder.join(join.getJoinType(), newConditionExpr); > } > relBuilder.hints(join.getHints()); > return result(relBuilder.build(), mapping); > {code} -- This message was sent by Atlassian Jira (v8.20.1#820001)