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); }
RelDataType newRowType, FunctionalIndexInfo functionInfo) { if (!functionInfo.hasFunctional()) { return toRewriteRex; LogicalExpression expr = toRewriteRex.accept(rexToDrill); final Map<LogicalExpression, Set<SchemaPath>> exprPathMap = functionInfo.getPathsInFunctionExpr(); PathInExpr exprSearch = new PathInExpr(exprPathMap); expr.accept(exprSearch, null); for (LogicalExpression functionExpr: functionInfo.getExprMap().keySet()) { if (exprToRex.containsKey(functionExpr)) { Set<RexNode> rexs = exprToRex.get(functionExpr); remap.setExpressionMap(functionInfo.getExprMap()); return remap.rewriteWithMap(toRewriteRex, mapRexExpr);
FunctionalIndexInfo functionInfo, Collection<SchemaPath> addedPaths) { RelDataType origRowType = origScan.getRowType(); if (!functionInfo.hasFunctional()) { return origRowType; for (SchemaPath path: functionInfo.allPathsInFunction()) { fieldInFunctions.add(path.getRootSegmentPath()); final Collection<SchemaPath> toAddToRowType = (addedPaths == null)? functionInfo.allNewSchemaPaths() : addedPaths;
/** * For a particular table scan for table T1 and an index on that table, find out if it is a covering index * @return */ static public boolean isCoveringIndex(IndexCallContext indexContext, FunctionalIndexInfo functionInfo) { if (functionInfo.hasFunctional()) { // need info from full query return queryCoveredByIndex(indexContext, functionInfo); } DbGroupScan groupScan = (DbGroupScan) getGroupScan(indexContext.getScan()); List<LogicalExpression> tableCols = Lists.newArrayList(); tableCols.addAll(groupScan.getColumns()); return functionInfo.getIndexDesc().isCoveringIndex(tableCols); }
FunctionalIndexInfo functionInfo, List<SchemaPath> addedPaths) { if (!functionInfo.hasFunctional()) { return paths; SchemaPath newPath = functionInfo.getNewPath(paths.get(i)); if (newPath == null) { continue;
idxCondition.accept(marker); SimpleRexRemap remap = new SimpleRexRemap(origScan, idxRowType, builder); remap.setExpressionMap(functionInfo.getExprMap()); if (functionInfo.supportEqualCharConvertToLike()) { final Map<LogicalExpression, LogicalExpression> indexedExprs = functionInfo.getExprMap();
Map<LogicalExpression, Set<SchemaPath>> exprPathMap = functionInfo.getPathsInFunctionExpr(); PathInExpr exprSearch = new PathInExpr(exprPathMap); return functionInfo.getIndexDesc().isCoveringIndex(leftPaths);
public CoveringIndexPlanGenerator(IndexLogicalPlanCallContext indexContext, FunctionalIndexInfo functionInfo, IndexGroupScan indexGroupScan, RexNode indexCondition, RexNode remainderCondition, RexBuilder builder, PlannerSettings settings) { super(indexContext, indexCondition, remainderCondition, builder, settings); this.indexGroupScan = indexGroupScan; this.functionInfo = functionInfo; this.indexDesc = functionInfo.getIndexDesc(); }
SchemaPath newPath = functionInfo.getNewPathFromExpr(indexedExpr); if(newPath != null) { rowPaths.add(newPath);
if (!indexInfo.hasFunctional()) { Map<LogicalExpression, Integer> projectExprs = Maps.newLinkedHashMap(); DrillParseContext parserContext = new DrillParseContext(PrelUtil.getPlannerSettings(input.getCluster())); for (LogicalExpression expr : indexInfo.getIndexDesc().getIndexColumns()) { if (!projectExprs.containsKey(expr)) { break; RelFieldCollation.Direction dir = indexInfo.getIndexDesc().getCollation().getFieldCollations().get(idxFieldCount).direction; if ( dir == null) { break;
public CoveringPlanNoFilterGenerator(IndexCallContext indexContext, FunctionalIndexInfo functionInfo, boolean isSingleton, PlannerSettings settings) { super(indexContext, null, null, null, settings); this.functionInfo = functionInfo; this.indexDesc = functionInfo == null ? null : functionInfo.getIndexDesc(); this.indexGroupScan = functionInfo == null ? null : functionInfo.getIndexDesc().getIndexGroupScan(); this.isSingletonSortedStream = isSingleton; }
/** * 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); } }
/** * Build collation property for project, the one closer to the Scan * @param projectRexs the expressions to project * @param project the project between projectRexs and input, it could be null if no such intermediate project(lower project) * @param input the input RelNode to the project, usually it is the scan operator. * @param indexInfo the index for which we are building index plan * @param context the context of this index planning process * @return the output RelCollation */ public static RelCollation buildCollationProject(List<RexNode> projectRexs, DrillProjectRelBase project, RelNode input, FunctionalIndexInfo indexInfo, IndexCallContext context) { Map<LogicalExpression, Integer> projectExprs = getProjectExprs(projectRexs, project, input); return buildCollationForExpressions(projectExprs, indexInfo.getIndexDesc(), context); }
RelDataType newRowType; FunctionalIndexInfo functionInfo = idx.getFunctionalInfo(); if (functionInfo.hasFunctional()) { newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(scanRel, context, functionInfo); } else { FunctionalIndexInfo functionInfo = idx.getFunctionalInfo(); RelDataType newRowType = scanRel.getRowType(); if (functionInfo.hasFunctional()) { newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(scanRel, context, 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); }
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); }
if (!indexInfo.hasFunctional()) { for (int projectExprIdx = 0; projectExprIdx < projectRexs.size(); projectExprIdx++) { RexNode n = projectRexs.get(projectExprIdx);
/** * 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 newRowType; FunctionalIndexInfo functionInfo = idx.getFunctionalInfo(); if (functionInfo.hasFunctional()) { newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(scanRel, context, functionInfo); } else { FunctionalIndexInfo functionInfo = idx.getFunctionalInfo(); RelDataType newRowType = scanRel.getRowType(); if (functionInfo.hasFunctional()) { newRowType = FunctionalIndexHelper.rewriteFunctionalRowType(scanRel, context, functionInfo);
indexScanPrel, indexContext.getLowerProject().getProjects(), indexContext.getLowerProject().getRowType()); if (functionInfo.hasFunctional()) {