protected static boolean toRemoveSort(RelCollation sortCollation, RelCollation inputCollation) { if ( (inputCollation != null) && inputCollation.satisfies(sortCollation)) { return true; } return false; }
/** Returns whether a relational expression is already sorted and has fewer * rows than the sum of offset and limit. * * <p>If this is the case, it is safe to push down a * {@link org.apache.calcite.rel.core.Sort} with limit and optional offset. */ public static boolean checkInputForCollationAndLimit(RelMetadataQuery mq, RelNode input, RelCollation collation, RexNode offset, RexNode fetch) { // Check if the input is already sorted boolean alreadySorted = collation.getFieldCollations().isEmpty(); for (RelCollation inputCollation : mq.collations(input)) { if (inputCollation.satisfies(collation)) { alreadySorted = true; break; } } // Check if we are not reducing the number of tuples boolean alreadySmaller = true; final Double rowCount = mq.getMaxRowCount(input); if (rowCount != null && fetch != null) { final int offsetVal = offset == null ? 0 : RexLiteral.intValue(offset); final int limit = RexLiteral.intValue(fetch); if ((double) offsetVal + (double) limit < rowCount) { alreadySmaller = false; } } return alreadySorted && alreadySmaller; } }
/** Returns whether a relational expression is already sorted and has fewer * rows than the sum of offset and limit. * * <p>If this is the case, it is safe to push down a * {@link org.apache.calcite.rel.core.Sort} with limit and optional offset. */ public static boolean checkInputForCollationAndLimit(RelMetadataQuery mq, RelNode input, RelCollation collation, RexNode offset, RexNode fetch) { // Check if the input is already sorted boolean alreadySorted = collation.getFieldCollations().isEmpty(); for (RelCollation inputCollation : mq.collations(input)) { if (inputCollation.satisfies(collation)) { alreadySorted = true; break; } } // Check if we are not reducing the number of tuples boolean alreadySmaller = true; final Double rowCount = mq.getMaxRowCount(input); if (rowCount != null && fetch != null) { final int offsetVal = offset == null ? 0 : RexLiteral.intValue(offset); final int limit = RexLiteral.intValue(fetch); if ((double) offsetVal + (double) limit < rowCount) { alreadySmaller = false; } } return alreadySorted && alreadySmaller; } }
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; }