public static ScanPrel buildCoveringIndexScan(DrillScanRelBase origScan, IndexGroupScan indexGroupScan, IndexCallContext indexContext, IndexDescriptor indexDesc) { FunctionalIndexInfo functionInfo = indexDesc.getFunctionalInfo(); //to record the new (renamed)paths added List<SchemaPath> rewrittenPaths = Lists.newArrayList(); DbGroupScan dbGroupScan = (DbGroupScan) getGroupScan(origScan); indexGroupScan.setColumns( rewriteFunctionColumn(dbGroupScan.getColumns(), functionInfo, rewrittenPaths)); DrillDistributionTrait partition = scanIsPartition(getGroupScan(origScan))? DrillDistributionTrait.RANDOM_DISTRIBUTED : DrillDistributionTrait.SINGLETON; RelDataType newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(origScan, indexContext, functionInfo, rewrittenPaths); // add a default collation trait otherwise Calcite runs into a ClassCastException, which at first glance // seems like a Calcite bug RelTraitSet indexScanTraitSet = origScan.getTraitSet().plus(Prel.DRILL_PHYSICAL). plus(RelCollationTraitDef.INSTANCE.getDefault()).plus(partition); // Create the collation traits for index scan based on the index columns under the // condition that the index actually has collation property (e.g hash indexes don't) if (indexDesc.getCollation() != null) { RelCollation collationTrait = buildCollationCoveringIndexScan(indexDesc, indexContext); indexScanTraitSet = indexScanTraitSet.plus(collationTrait); } ScanPrel indexScanPrel = new ScanPrel(origScan.getCluster(), indexScanTraitSet, indexGroupScan, newRowType, origScan.getTable()); return indexScanPrel; }