@Override public RelNode run( RelOptPlanner planner, RelNode rel, RelTraitSet requiredOutputTraits, List<RelOptMaterialization> materializations, List<RelOptLattice> lattices ) { final RelNode decorrelatedRel = RelDecorrelator.decorrelateQuery(rel); final RelBuilder relBuilder = RelFactories.LOGICAL_BUILDER.create(decorrelatedRel.getCluster(), null); return new RelFieldTrimmer(null, relBuilder).trim(decorrelatedRel); } }
@Override public TrimResult trimFields(TableScan tableAccessRel, ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) { final TrimResult result = super.trimFields(tableAccessRel, fieldsUsed, extraFields); if (fetchStats) { fetchColStats(result.getKey(), tableAccessRel, fieldsUsed, extraFields); } return result; }
public static RelNode trimFields(final RelNode relNode, boolean shouldLog) { final Stopwatch w = Stopwatch.createStarted(); final RelFieldTrimmer trimmer = DremioFieldTrimmer.of(relNode.getCluster()); final RelNode trimmed = trimmer.trim(relNode); if(shouldLog) { log(PlannerType.HEP, PlannerPhase.FIELD_TRIMMING, trimmed, logger, w); } return trimmed; }
/** * Creates a RelFieldTrimmer. * * @return Field trimmer */ protected RelFieldTrimmer newFieldTrimmer() { return new RelFieldTrimmer(validator, relBuilder); }
return trimFields( (RelNode) tableAccessRel, fieldsUsed, extraFields); return dummyProject(fieldCount, input); final Mapping mapping = createMapping(fieldsUsed, fieldCount); return result(newTableAccessRel, mapping);
trimChild(project, input, inputFieldsUsed, inputExtraFields); RelNode newInput = trimResult.left; final Mapping inputMapping = trimResult.right; return result(project, Mappings.createIdentity(fieldCount)); return dummyProject(fieldCount, newInput); return result(relBuilder.build(), mapping);
final Mapping mapping = createMapping(fieldsUsed, fieldCount); trimChild(setOp, input, fieldsUsed, extraFields); relBuilder.build(); return result(setOp, mapping); throw new AssertionError("unknown setOp " + setOp); return result(relBuilder.build(), mapping);
Collections.emptySet(); TrimResult trimResult = trimChildRestore( tabFun, input, inputFieldsUsed, inputExtraFields); assert trimResult.right.isIdentity(); return result(newTabFun, mapping);
return result(values, mapping); final Mapping mapping = createMapping(fieldsUsed, fieldCount); final RelDataType newRowType = RelOptUtil.permute(values.getCluster().getTypeFactory(), rowType, LogicalValues.create(values.getCluster(), newRowType, newTuples.build()); return result(newValues, mapping);
/** Creates a project with a dummy column, to protect the parts of the system * that cannot handle a relational expression with no columns. * * @param fieldCount Number of fields in the original relational expression * @param input Trimmed input * @return Dummy project, or null if no dummy is required */ protected TrimResult dummyProject(int fieldCount, RelNode input) { final RelOptCluster cluster = input.getCluster(); final Mapping mapping = Mappings.create(MappingType.INVERSE_SURJECTION, fieldCount, 1); if (input.getRowType().getFieldCount() == 1) { // Input already has one field (and may in fact be a dummy project we // created for the child). We can't do better. return result(input, mapping); } final RexLiteral expr = cluster.getRexBuilder().makeExactLiteral(BigDecimal.ZERO); relBuilder.push(input); relBuilder.project(ImmutableList.<RexNode>of(expr), ImmutableList.of("DUMMY")); return result(relBuilder.build(), mapping); }
/** * Trims unused fields from a relational expression. * * <p>We presume that all fields of the relational expression are wanted by * its consumer, so only trim fields that are not used within the tree. * * @param root Root node of relational expression * @return Trimmed relational expression */ public RelNode trim(RelNode root) { final int fieldCount = root.getRowType().getFieldCount(); final ImmutableBitSet fieldsUsed = ImmutableBitSet.range(fieldCount); final Set<RelDataTypeField> extraFields = Collections.emptySet(); final TrimResult trimResult = dispatchTrimFields(root, fieldsUsed, extraFields); if (!trimResult.right.isIdentity()) { throw new IllegalArgumentException(); } if (SqlToRelConverter.SQL2REL_LOGGER.isDebugEnabled()) { SqlToRelConverter.SQL2REL_LOGGER.debug( RelOptUtil.dumpPlan("Plan after trimming unused fields", trimResult.left, SqlExplainFormat.TEXT, SqlExplainLevel.EXPPLAN_ATTRIBUTES)); } return trimResult.left; }
final List<RelCollation> collations = rootRel.getTraitSet().getTraits(RelCollationTraitDef.INSTANCE); rootRel = trimmer.trim(rootRel); if (!ordered && collations != null
/** * Creates a RelFieldTrimmer. * * @return Field trimmer */ protected RelFieldTrimmer newFieldTrimmer() { return new RelFieldTrimmer(validator, relBuilder); }
return trimFields( (RelNode) tableAccessRel, fieldsUsed, extraFields); return dummyProject(fieldCount, input); final Mapping mapping = createMapping(fieldsUsed, fieldCount); return result(newTableAccessRel, mapping);
trimChild(project, input, inputFieldsUsed, inputExtraFields); RelNode newInput = trimResult.left; final Mapping inputMapping = trimResult.right; return result(project, Mappings.createIdentity(fieldCount)); return dummyProject(fieldCount, newInput); return result(relBuilder.build(), mapping);
final Mapping mapping = createMapping(fieldsUsed, fieldCount); trimChild(setOp, input, fieldsUsed, extraFields); relBuilder.build(); return result(setOp, mapping); throw new AssertionError("unknown setOp " + setOp); return result(relBuilder.build(), mapping);
Collections.emptySet(); TrimResult trimResult = trimChildRestore( tabFun, input, inputFieldsUsed, inputExtraFields); assert trimResult.right.isIdentity(); return result(newTabFun, mapping);
return result(values, mapping); final Mapping mapping = createMapping(fieldsUsed, fieldCount); final RelDataType newRowType = RelOptUtil.permute(values.getCluster().getTypeFactory(), rowType, LogicalValues.create(values.getCluster(), newRowType, newTuples.build()); return result(newValues, mapping);