/** * * @param expr * @param context * @return if there is filter and expr is only in equality condition of the filter, return true */ private static boolean exprOnlyInEquality(LogicalExpression expr, IndexCallContext context) { // if there is no filter, expr wont be in equality if (context.getFilter() == null) { return false; } final Set<LogicalExpression> onlyInEquality = context.getOrigMarker().getExpressionsOnlyInEquality(); return onlyInEquality.contains(expr); } /**
public AbstractIndexPlanGenerator(IndexCallContext indexContext, RexNode indexCondition, RexNode remainderCondition, RexBuilder builder, PlannerSettings settings) { super(indexContext.getCall()); this.origProject = indexContext.getLowerProject(); this.origScan = indexContext.getScan(); this.upperProject = indexContext.getUpperProject(); this.indexCondition = indexCondition; this.remainderCondition = remainderCondition; this.indexContext = indexContext; this.builder = builder; this.settings = settings; }
private boolean requiredCollation() { if (indexContext.getCollationList() != null && indexContext.getCollationList().size() > 0) { return true; } return false; }
if (indexContext.getFilter() != null && indexContext.getUpperProject() == null) { if (!isFullQuery(indexContext)) { return false; new DrillParseContext(PrelUtil.getPlannerSettings(indexContext.getCall().rel(0).getCluster())); if (indexContext.getUpperProject() != null) { if (indexContext.getLowerProject() == null) { for (RexNode rex : indexContext.getUpperProject().getProjects()) { LogicalExpression expr = RexToExpression.toDrill(parserContext, null, indexContext.getScan(), rex); exprs.add(expr); IndexableExprMarker filterMarker = new IndexableExprMarker(indexContext.getScan()); indexContext.getFilterCondition().accept(filterMarker); for (RexNode rex : filterMarker.getIndexableExpression().keySet()) { LogicalExpression expr = RexToExpression.toDrill(parserContext, null, indexContext.getScan(), rex); exprs.add(expr); for (RexNode rex : indexContext.getUpperProject().getProjects()) { LogicalExpression expr = RexToExpression.toDrill(parserContext, indexContext.getLowerProject(), indexContext.getScan(), rex); exprs.add(expr); IndexableExprMarker filterMarker = new IndexableExprMarker(indexContext.getScan()); indexContext.getOrigCondition().accept(filterMarker); LogicalExpression expr = RexToExpression.toDrill(parserContext, null, indexContext.getScan(), rex); exprs.add(expr); else if (indexContext.getLowerProject() != null) {
new DrillParseContext(PrelUtil.getPlannerSettings(indexContext.getCall().rel(0).getCluster())); indexContext.createSortExprs(); for (RelFieldCollation collation : coll) { int idx = collation.getFieldIndex(); DrillProjectRelBase oneProject; if (indexContext.getUpperProject() != null && indexContext.getLowerProject() != null) { LogicalExpression expr = RexToExpression.toDrill(parserContext, indexContext.getLowerProject(), indexContext.getScan(), indexContext.getUpperProject().getProjects().get(idx)); indexContext.getSortExprs().add(expr); oneProject = (indexContext.getUpperProject() != null)? indexContext.getUpperProject() : indexContext.getLowerProject(); if (oneProject != null) { LogicalExpression expr = RexToExpression.toDrill(parserContext, null, indexContext.getScan(), getProjects(oneProject).get(idx)); indexContext.getSortExprs().add(expr); RelDataTypeField f = indexContext.getScan().getRowType().getFieldList().get(idx); String pathSeg = f.getName().replaceAll("`", ""); final String[] segs = pathSeg.split("\\."); path = SchemaPath.getCompoundPath(segs); indexContext.getSortExprs().add(path);
private boolean buildAndCheckCollation(IndexProperties indexProps) { IndexDescriptor indexDesc = indexProps.getIndexDesc(); FunctionalIndexInfo functionInfo = indexDesc.getFunctionalInfo(); RelCollation inputCollation; // for the purpose of collation we can assume that a covering index scan would provide // the collation property that would be relevant for non-covering as well ScanPrel indexScanPrel = IndexPlanUtils.buildCoveringIndexScan(indexContext.getScan(), indexDesc.getIndexGroupScan(), indexContext, indexDesc); inputCollation = indexScanPrel.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE); // we don't create collation for Filter because it will inherit the child's collation if (indexContext.hasLowerProject()) { inputCollation = IndexPlanUtils.buildCollationProject(indexContext.getLowerProject().getProjects(), null, indexContext.getScan(), functionInfo,indexContext); } if (indexContext.hasUpperProject()) { inputCollation = IndexPlanUtils.buildCollationProject(indexContext.getUpperProject().getProjects(), indexContext.getLowerProject(), indexContext.getScan(), functionInfo, indexContext); } if ((inputCollation != null) && (inputCollation.satisfies(indexContext.getCollation()))) { return true; } return false; }
origScan, indexContext.getOrigMarker(), indexGroupScan, functionInfo); indexScanPrel, convertedIndexCondition); double finalRowCount = indexGroupScan.getRowCount(indexContext.getOrigCondition(), origScan); origScan.getTable(), origScan.getRowType(), indexContext.getScanColumns()); double rightIdxRowCount = indexGroupScan.getRowCount(indexCondition, rightIdxRel); restrictedGroupScan.setRowCount(null, rightIdxRowCount, rightIdxRowCount); if (indexDesc.isAsyncIndex()) { leftIndexFilterPrel = new FilterPrel(dbScan.getCluster(), dbScan.getTraitSet(), dbScan, indexContext.getOrigCondition()); lastLeft = leftIndexFilterPrel; if (indexContext.getSort() != null) { if (toRemoveSort(indexContext.getCollation(), newRel.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE))) { ((IndexGroupScan)indexScanPrel.getGroupScan()).setParallelizationWidth(1);
public RelNode convertChild() throws InvalidRelException { Preconditions.checkNotNull(indexContext.getSort()); if (indexGroupScan == null) { logger.error("Null indexgroupScan in CoveringIndexPlanGenerator.convertChild"); IndexPlanUtils.updateSortExpression(indexContext, indexContext.getSort() != null ? indexContext.getCollation().getFieldCollations() : null); if (indexContext.getLowerProject() != null) { RelCollation collation = IndexPlanUtils.buildCollationProject(indexContext.getLowerProject().getProjects(), null, indexContext.getScan(), functionInfo, indexContext); finalRel = new ProjectPrel(indexContext.getScan().getCluster(), indexScanTraitSet.plus(collation), indexScanPrel, indexContext.getLowerProject().getProjects(), indexContext.getLowerProject().getRowType()); finalRel = getSortNode(indexContext, finalRel, true, isSingletonSortedStream, indexContext.getExchange() != null); if (finalRel == null) { return null; finalRel.toString(), indexContext.getScan().toString(), indexContext.getLowerProject()!=null?indexContext.getLowerProject().getDigest(): indexContext.getScan().getDigest(), finalRel.getDigest()); return finalRel;
baseConditionMap = new HashMap<>(); for (IndexDescriptor idx : firstKeyIdxConditionMap.keySet()) { if(IndexPlanUtils.conditionIndexed(context.getOrigMarker(), idx) == IndexPlanUtils.ConditionIndexed.NONE) { continue; if(IndexPlanUtils.conditionIndexed(context.getOrigMarker(), idx) == IndexPlanUtils.ConditionIndexed.NONE) { continue;
public static RelNode getSortNode(IndexCallContext indexContext, RelNode newRel, boolean donotGenerateSort, boolean isSingleton, boolean isExchangeRequired) { OrderedRel rel = indexContext.getSort(); DrillDistributionTrait hashDistribution = new DrillDistributionTrait(DrillDistributionTrait.DistributionType.HASH_DISTRIBUTED, ImmutableList.copyOf(indexContext.getDistributionFields())); if ( toRemoveSort(indexContext.getCollation(), newRel.getTraitSet().getTrait(RelCollationTraitDef.INSTANCE))) { newRel.getTraitSet().plus(indexContext.getCollation()).plus(Prel.DRILL_PHYSICAL), newRel, IndexPlanUtils.getOffset(rel), IndexPlanUtils.getFetch(rel)); RelTraitSet traits = newRel.getTraitSet().plus(indexContext.getCollation()).plus(Prel.DRILL_PHYSICAL); newRel = Prule.convert(newRel, traits); newRel = getExchange(newRel.getCluster(), isSingleton, isExchangeRequired, return null; RelTraitSet traits = newRel.getTraitSet().plus(indexContext.getCollation()).plus(Prel.DRILL_PHYSICAL); newRel = getSortOrTopN(indexContext, rel, newRel, Prule.convert(newRel, newRel.getTraitSet().replace(Prel.DRILL_PHYSICAL)));
public IndexSelector(RexNode indexCondition, RexNode otherRemainderCondition, IndexCallContext indexContext, IndexCollection collection, RexBuilder rexBuilder, double totalRows) { this.indexCondition = indexCondition; this.otherRemainderCondition = otherRemainderCondition; this.indexContext = indexContext; this.totalRows = totalRows; this.stats = indexContext.getGroupScan().getStatistics(); this.rexBuilder = rexBuilder; this.builder = IndexConditionInfo.newBuilder(indexCondition, collection, rexBuilder, indexContext.getScan()); this.primaryTableScan = indexContext.getScan(); this.indexPropList = Lists.newArrayList(); }
static private boolean isFullQuery(IndexCallContext indexContext) { RelNode rootInCall = indexContext.getCall().rel(0); // check if the tip of the operator stack we have is also the top of the whole query, if yes, return true if (indexContext.getCall().getPlanner().getRoot() instanceof RelSubset) { final RelSubset rootSet = (RelSubset) indexContext.getCall().getPlanner().getRoot(); if (rootSet.getRelList().contains(rootInCall)) { return true; } } else { if (indexContext.getCall().getPlanner().getRoot().equals(rootInCall)) { return true; } } return false; }
private static RelNode getSortOrTopN(IndexCallContext indexContext, RelNode sortNode, RelNode newRel, RelNode child) { if (sortNode instanceof TopNPrel) { return new TopNPrel(sortNode.getCluster(), newRel.getTraitSet().replace(Prel.DRILL_PHYSICAL).plus(indexContext.getCollation()), child, ((TopNPrel)sortNode).getLimit(), indexContext.getCollation()); } return new SortPrel(sortNode.getCluster(), newRel.getTraitSet().replace(Prel.DRILL_PHYSICAL).plus(indexContext.getCollation()), child, indexContext.getCollation()); }
boolean generateDistribution; int curIdx = 0; RexNode remnant = indexContext.getFilterCondition(); for (Map.Entry<IndexDescriptor, RexNode> pair : idxConditionMap.entrySet()) {
IndexGroupScan indexScan = index.getIndexGroupScan(); RelDataType indexScanRowType = FunctionalIndexHelper.convertRowTypeForIndexScan( origScan, indexContext.getOrigMarker(), indexScan, functionInfo); DrillDistributionTrait partition = IndexPlanUtils.scanIsPartition(IndexPlanUtils.getGroupScan(origScan))? DrillDistributionTrait.RANDOM_DISTRIBUTED : DrillDistributionTrait.SINGLETON;
/** * This constructor is to build selector for no index condition case (no filter) * @param indexContext */ public IndexSelector(IndexCallContext indexContext) { this.indexCondition = null; this.otherRemainderCondition = null; this.indexContext = indexContext; this.totalRows = Statistics.ROWCOUNT_UNKNOWN; this.stats = indexContext.getGroupScan().getStatistics(); this.rexBuilder = indexContext.getScan().getCluster().getRexBuilder(); this.builder = null; this.primaryTableScan = indexContext.getScan(); this.indexPropList = Lists.newArrayList(); }
public RelTraitSet newTraitSet(RelTrait... traits) { RelTraitSet set = indexContext.getCall().getPlanner().emptyTraitSet(); for (RelTrait t : traits) { if(t != null) { set = set.plus(t); } } return set; }
public static RelNode getExchange(RelOptCluster cluster, boolean isSingleton, boolean isExchangeRequired, RelTraitSet traits, DrillDistributionTrait distributionTrait, IndexCallContext indexContext, RelNode input) { if (!isExchangeRequired) { return input; } if (isSingleton) { return new SingleMergeExchangePrel(cluster, traits.replace(DrillDistributionTrait.SINGLETON), input, indexContext.getCollation()); } else { return new HashToMergeExchangePrel(cluster, traits.replace(distributionTrait), input, distributionTrait.getFields(), indexContext.getCollation(), PrelUtil.getSettings(cluster).numEndPoints()); } }
baseConditionMap = new HashMap<>(); for (IndexDescriptor idx : firstKeyIdxConditionMap.keySet()) { if(IndexPlanUtils.conditionIndexed(context.getOrigMarker(), idx) == IndexPlanUtils.ConditionIndexed.NONE) { continue; if(IndexPlanUtils.conditionIndexed(context.getOrigMarker(), idx) == IndexPlanUtils.ConditionIndexed.NONE) { continue;