private RexNode convertCastForFIdx(RexCall condition, IndexDescriptor index, IndexCallContext context, RelNode origScan) { if (index == null) { return condition; } FunctionalIndexInfo functionInfo = index.getFunctionalInfo(); if (!functionInfo.hasFunctional()) { return condition; } // The functional index has a different row-type than the original scan. Use the index row-type when // converting the condition RelDataType newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(origScan, context, functionInfo); RexBuilder builder = origScan.getCluster().getRexBuilder(); return FunctionalIndexHelper.convertConditionForIndexScan(condition, origScan, newRowType, builder, functionInfo); }
/** * This function computes statistics when there is no query condition * @param jTabGrpScan - The current group scan * @param indexes - The collection of indexes to use for getting statistics * @param scanRel - The current scanRel * @param context - The index plan call context */ private void populateStatsForNoFilter(JsonTableGroupScan jTabGrpScan, IndexCollection indexes, RelNode scanRel, IndexCallContext context) { // Get the stats payload for full table (has total rows in the table) StatisticsPayload ftsPayload = jTabGrpScan.getFirstKeyEstimatedStats(null, null, scanRel); addToCache(null, null, context, ftsPayload, jTabGrpScan, scanRel, scanRel.getRowType()); addToCache(null, jTabGrpScan.getAverageRowSizeStats(null), ftsPayload); // Get the stats for all indexes for (IndexDescriptor idx: indexes) { StatisticsPayload idxPayload = jTabGrpScan.getFirstKeyEstimatedStats(null, idx, scanRel); StatisticsPayload idxRowSizePayload = jTabGrpScan.getAverageRowSizeStats(idx); RelDataType newRowType; FunctionalIndexInfo functionInfo = idx.getFunctionalInfo(); if (functionInfo.hasFunctional()) { newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(scanRel, context, functionInfo); } else { newRowType = scanRel.getRowType(); } addToCache(null, idx, context, idxPayload, jTabGrpScan, scanRel, newRowType); addToCache(idx, idxRowSizePayload, ftsPayload); } }
RelDataType indexScanRowType = FunctionalIndexHelper.convertRowTypeForIndexScan( origScan, indexContext.getOrigMarker(), indexScan, functionInfo); DrillDistributionTrait partition = IndexPlanUtils.scanIsPartition(IndexPlanUtils.getGroupScan(origScan))? origScan.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(partition), indexScan, indexScanRowType, origScan.getTable()); FilterPrel indexFilterPrel = new FilterPrel(indexScanPrel.getCluster(), indexScanPrel.getTraitSet(), indexScanPrel, FunctionalIndexHelper.convertConditionForIndexScan(condition, origScan, indexScanRowType, builder, functionInfo));
/** * * @param inputIndex * @param functionInfo functional index information that may impact rewrite * @return */ private RexNode rewriteFunctionalCondition(RexNode inputIndex, RelDataType newRowType, FunctionalIndexInfo functionInfo) { if (!functionInfo.hasFunctional()) { return inputIndex; } return FunctionalIndexHelper.convertConditionForIndexScan(inputIndex, origScan, newRowType, builder, functionInfo); }
FunctionalIndexInfo functionInfo = idx.getFunctionalInfo(); if (functionInfo.hasFunctional()) { newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(scanRel, context, functionInfo); } else { newRowType = scanRel.getRowType(); RelDataType newRowType = scanRel.getRowType(); if (functionInfo.hasFunctional()) { newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(scanRel, context, functionInfo);
RelDataType indexScanRowType = FunctionalIndexHelper.convertRowTypeForIndexScan( origScan, indexContext.getOrigMarker(), indexGroupScan, functionInfo); RexNode convertedIndexCondition = FunctionalIndexHelper.convertConditionForIndexScan(indexCondition, origScan, indexScanRowType, builder, functionInfo); FilterPrel rightIndexFilterPrel = new FilterPrel(indexScanPrel.getCluster(), indexScanPrel.getTraitSet(),
private RexNode convertCastForFIdx(RexCall condition, IndexDescriptor index, IndexCallContext context, RelNode origScan) { if (index == null) { return condition; } FunctionalIndexInfo functionInfo = index.getFunctionalInfo(); if (!functionInfo.hasFunctional()) { return condition; } // The functional index has a different row-type than the original scan. Use the index row-type when // converting the condition RelDataType newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(origScan, context, functionInfo); RexBuilder builder = origScan.getCluster().getRexBuilder(); return FunctionalIndexHelper.convertConditionForIndexScan(condition, origScan, newRowType, builder, functionInfo); }
public static RelDataType rewriteFunctionalRowType(RelNode origScan, IndexCallContext indexContext, FunctionalIndexInfo functionInfo) { return rewriteFunctionalRowType(origScan, indexContext, functionInfo, null); } /**
/** * This function computes statistics when there is no query condition * @param jTabGrpScan - The current group scan * @param indexes - The collection of indexes to use for getting statistics * @param scanRel - The current scanRel * @param context - The index plan call context */ private void populateStatsForNoFilter(JsonTableGroupScan jTabGrpScan, IndexCollection indexes, RelNode scanRel, IndexCallContext context) { // Get the stats payload for full table (has total rows in the table) StatisticsPayload ftsPayload = jTabGrpScan.getFirstKeyEstimatedStats(null, null, scanRel); addToCache(null, null, context, ftsPayload, jTabGrpScan, scanRel, scanRel.getRowType()); addToCache(null, jTabGrpScan.getAverageRowSizeStats(null), ftsPayload); // Get the stats for all indexes for (IndexDescriptor idx: indexes) { StatisticsPayload idxPayload = jTabGrpScan.getFirstKeyEstimatedStats(null, idx, scanRel); StatisticsPayload idxRowSizePayload = jTabGrpScan.getAverageRowSizeStats(idx); RelDataType newRowType; FunctionalIndexInfo functionInfo = idx.getFunctionalInfo(); if (functionInfo.hasFunctional()) { newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(scanRel, context, functionInfo); } else { newRowType = scanRel.getRowType(); } addToCache(null, idx, context, idxPayload, jTabGrpScan, scanRel, newRowType); addToCache(idx, idxRowSizePayload, ftsPayload); } }
FunctionalIndexInfo functionInfo = idx.getFunctionalInfo(); if (functionInfo.hasFunctional()) { newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(scanRel, context, functionInfo); } else { newRowType = scanRel.getRowType(); RelDataType newRowType = scanRel.getRowType(); if (functionInfo.hasFunctional()) { newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(scanRel, context, functionInfo);
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; }