See https://issues.apache.org/jira/browse/CALCITE-4166. 

> On Jul 19, 2024, at 6:28 AM, Gonzalo Ortiz Jaureguizar <[email protected]> 
> wrote:
> 
> Hi there,
> 
> Fixing an issue in Apache Pinot I've found something that may be a bug in
> Apache Calcite, although probably is a misunderstanding from my side.
> 
> In Pinot we are not (yet) using the standard MetadataHandler (which I'm
> having issues to understand, but that is not the topic here) to calculate
> the distribution of each node. Instead, we add our own distribution in a
> trait and process that by ourselves in our own rules. That may not be the
> best in terms of DRY, but it is working.
> 
> We have found an issue when using projections that are not mapping.
> Probably a more expert eye will see in PinotRelDistributionTraitRule#L113
> <http://PinotRelDistributionTraitRule.java#L113> that our naive way to
> calculate the new distribution fails in that case
> because project.getMapping() returns null.
> 
> I planned to solve that by using project.getPartialMapping() in the same
> way done by Calcite in RelMdDistribution#L165
> <https://github.com/apache/calcite/blob/e371b336a8b404ed36955f517196a5e8606455d7/core/src/main/java/org/apache/calcite/rel/metadata/RelMdDistribution.java#L165C17-L165C34>,
> but when I tried to do that, I found the following runtime exception:
> 
> java.lang.UnsupportedOperationException
> at
> org.apache.calcite.util.mapping.Mappings$AbstractMapping.getSourceOpt(Mappings.java:952)
> at
> org.apache.calcite.util.mapping.Mappings$InverseMapping.getTargetOpt(Mappings.java:1841)
> at
> org.apache.calcite.rel.RelDistributions$RelDistributionImpl.apply(RelDistributions.java:146)
> at
> org.apache.pinot.calcite.rel.rules.PinotRelDistributionTraitRule.deriveDistribution(PinotRelDistributionTraitRule.java:128)
> 
> Which makes me think there is a problem in the way
> Project.getPartialMapping is initializing the Mapping. My solution was to
> do something like:
> 
>          Mappings.TargetMapping mapping =
>              Project.getPartialMapping(input.getRowType().getFieldCount(),
> project.getProjects());
>          Mapping actualMapping =
> Mappings.create(MappingType.PARTIAL_FUNCTION,
> input.getRowType().getFieldCount(),
>              project.getRowType().getFieldCount());
>          for (IntPair intPair : mapping) {
>            actualMapping.set(intPair.source, intPair.target);
>          }
>          return inputRelDistribution.apply(actualMapping);
> 
> But I don't think that is the most elegant solution. I think it is fair to
> assume that the Mapping returned by Project.getPartialMapping should be
> usable to call getTargetOpt.
> 
> Is there something I am doing or understanding wrong?

Reply via email to