public void fixSharedOlapTableScanAt(RelNode parent, int ordinalInParent) { OLAPTableScan copy = copyTableScanIfNeeded(parent.getInputs().get(ordinalInParent)); if (copy != null) parent.replaceInput(ordinalInParent, copy); }
private static RelNode introduceDerivedTable(final RelNode rel, RelNode parent) { int i = 0; int pos = -1; List<RelNode> childList = parent.getInputs(); for (RelNode child : childList) { if (child == rel) { pos = i; break; } i++; } if (pos == -1) { throw new RuntimeException("Couldn't find child node in parent's inputs"); } RelNode select = introduceDerivedTable(rel); parent.replaceInput(pos, select); return select; }
private static RelNode introduceDerivedTable(final RelNode rel, RelNode parent) { int i = 0; int pos = -1; List<RelNode> childList = parent.getInputs(); for (RelNode child : childList) { if (child == rel) { pos = i; break; } i++; } if (pos == -1) { throw new RuntimeException("Couldn't find child node in parent's inputs"); } RelNode select = introduceDerivedTable(rel); parent.replaceInput(pos, select); return select; }
public static RelNode renameTopLevelSelectInResultSchema(final RelNode rootRel, Pair<RelNode, RelNode> topSelparentPair, List<FieldSchema> resultSchema) throws CalciteSemanticException { RelNode parentOforiginalProjRel = topSelparentPair.getKey(); HiveProject originalProjRel = (HiveProject) topSelparentPair.getValue(); // Assumption: top portion of tree could only be // (limit)?(OB)?(Project).... List<RexNode> rootChildExps = originalProjRel.getChildExps(); if (resultSchema.size() != rootChildExps.size()) { // Safeguard against potential issues in CBO RowResolver construction. Disable CBO for now. LOG.error(PlanModifierUtil.generateInvalidSchemaMessage(originalProjRel, resultSchema, 0)); throw new CalciteSemanticException("Result Schema didn't match Optimized Op Tree Schema"); } List<String> newSelAliases = new ArrayList<String>(); String colAlias; for (int i = 0; i < rootChildExps.size(); i++) { colAlias = resultSchema.get(i).getName(); colAlias = getNewColAlias(newSelAliases, colAlias); newSelAliases.add(colAlias); } HiveProject replacementProjectRel = HiveProject.create(originalProjRel.getInput(), originalProjRel.getChildExps(), newSelAliases); if (rootRel == originalProjRel) { return replacementProjectRel; } else { parentOforiginalProjRel.replaceInput(0, replacementProjectRel); return rootRel; } }
public static RelNode renameTopLevelSelectInResultSchema(final RelNode rootRel, Pair<RelNode, RelNode> topSelparentPair, List<FieldSchema> resultSchema) throws CalciteSemanticException { RelNode parentOforiginalProjRel = topSelparentPair.getKey(); HiveProject originalProjRel = (HiveProject) topSelparentPair.getValue(); // Assumption: top portion of tree could only be // (limit)?(OB)?(Project).... List<RexNode> rootChildExps = originalProjRel.getChildExps(); if (resultSchema.size() != rootChildExps.size()) { // Safeguard against potential issues in CBO RowResolver construction. Disable CBO for now. LOG.error(PlanModifierUtil.generateInvalidSchemaMessage(originalProjRel, resultSchema, 0)); throw new CalciteSemanticException("Result Schema didn't match Optimized Op Tree Schema"); } List<String> newSelAliases = new ArrayList<String>(); String colAlias; for (int i = 0; i < rootChildExps.size(); i++) { colAlias = resultSchema.get(i).getName(); colAlias = getNewColAlias(newSelAliases, colAlias); newSelAliases.add(colAlias); } HiveProject replacementProjectRel = HiveProject.create(originalProjRel.getInput(), originalProjRel.getChildExps(), newSelAliases); if (rootRel == originalProjRel) { return replacementProjectRel; } else { parentOforiginalProjRel.replaceInput(0, replacementProjectRel); return rootRel; } }
/** Fallback if none of the other {@code decorrelateRel} methods match. */ public Frame decorrelateRel(RelNode rel) { RelNode newRel = rel.copy(rel.getTraitSet(), rel.getInputs()); if (rel.getInputs().size() > 0) { List<RelNode> oldInputs = rel.getInputs(); List<RelNode> newInputs = Lists.newArrayList(); for (int i = 0; i < oldInputs.size(); ++i) { final Frame frame = getInvoke(oldInputs.get(i), rel); if (frame == null || !frame.corDefOutputs.isEmpty()) { // if input is not rewritten, or if it produces correlated // variables, terminate rewrite return null; } newInputs.add(frame.r); newRel.replaceInput(i, frame.r); } if (!Util.equalShallow(oldInputs, newInputs)) { newRel = rel.copy(rel.getTraitSet(), newInputs); } } // the output position should not change since there are no corVars // coming from below. return register(rel, newRel, identityMap(rel.getRowType().getFieldCount()), ImmutableSortedMap.<CorDef, Integer>of()); }
private static void replaceEmptyGroupAggr(final RelNode rel, RelNode parent) { // If this function is called, the parent should only include constant List<RexNode> exps = parent.getChildExps(); for (RexNode rexNode : exps) { if (!rexNode.accept(new HiveCalciteUtil.ConstantFinder())) { throw new RuntimeException("We expect " + parent.toString() + " to contain only constants. However, " + rexNode.toString() + " is " + rexNode.getKind()); } } HiveAggregate oldAggRel = (HiveAggregate) rel; RelDataTypeFactory typeFactory = oldAggRel.getCluster().getTypeFactory(); RelDataType longType = TypeConverter.convert(TypeInfoFactory.longTypeInfo, typeFactory); RelDataType intType = TypeConverter.convert(TypeInfoFactory.intTypeInfo, typeFactory); // Create the dummy aggregation. SqlAggFunction countFn = SqlFunctionConverter.getCalciteAggFn("count", false, ImmutableList.of(intType), longType); // TODO: Using 0 might be wrong; might need to walk down to find the // proper index of a dummy. List<Integer> argList = ImmutableList.of(0); AggregateCall dummyCall = new AggregateCall(countFn, false, argList, longType, null); Aggregate newAggRel = oldAggRel.copy(oldAggRel.getTraitSet(), oldAggRel.getInput(), oldAggRel.indicator, oldAggRel.getGroupSet(), oldAggRel.getGroupSets(), ImmutableList.of(dummyCall)); RelNode select = introduceDerivedTable(newAggRel); parent.replaceInput(0, select); } }
/** Fallback if none of the other {@code decorrelateRel} methods match. */ public Frame decorrelateRel(RelNode rel) { RelNode newRel = rel.copy(rel.getTraitSet(), rel.getInputs()); if (rel.getInputs().size() > 0) { List<RelNode> oldInputs = rel.getInputs(); List<RelNode> newInputs = Lists.newArrayList(); for (int i = 0; i < oldInputs.size(); ++i) { final Frame frame = getInvoke(oldInputs.get(i), rel); if (frame == null || !frame.corDefOutputs.isEmpty()) { // if input is not rewritten, or if it produces correlated // variables, terminate rewrite return null; } newInputs.add(frame.r); newRel.replaceInput(i, frame.r); } if (!Util.equalShallow(oldInputs, newInputs)) { newRel = rel.copy(rel.getTraitSet(), newInputs); } } // the output position should not change since there are no corVars // coming from below. return register(rel, newRel, identityMap(rel.getRowType().getFieldCount()), ImmutableSortedMap.<CorDef, Integer>of()); }
private static void replaceEmptyGroupAggr(final RelNode rel, RelNode parent) { // If this function is called, the parent should only include constant List<RexNode> exps = parent.getChildExps(); for (RexNode rexNode : exps) { if (!rexNode.accept(new HiveCalciteUtil.ConstantFinder())) { throw new RuntimeException("We expect " + parent.toString() + " to contain only constants. However, " + rexNode.toString() + " is " + rexNode.getKind()); } } HiveAggregate oldAggRel = (HiveAggregate) rel; RelDataTypeFactory typeFactory = oldAggRel.getCluster().getTypeFactory(); RelDataType longType = TypeConverter.convert(TypeInfoFactory.longTypeInfo, typeFactory); RelDataType intType = TypeConverter.convert(TypeInfoFactory.intTypeInfo, typeFactory); // Create the dummy aggregation. SqlAggFunction countFn = SqlFunctionConverter.getCalciteAggFn("count", false, ImmutableList.of(intType), longType); // TODO: Using 0 might be wrong; might need to walk down to find the // proper index of a dummy. List<Integer> argList = ImmutableList.of(0); AggregateCall dummyCall = new AggregateCall(countFn, false, argList, longType, null); Aggregate newAggRel = oldAggRel.copy(oldAggRel.getTraitSet(), oldAggRel.getInput(), oldAggRel.indicator, oldAggRel.getGroupSet(), oldAggRel.getGroupSets(), ImmutableList.of(dummyCall)); RelNode select = introduceDerivedTable(newAggRel); parent.replaceInput(0, select); } }
public void fixSharedOlapTableScanAt(RelNode parent, int ordinalInParent) { OLAPTableScan copy = copyTableScanIfNeeded(parent.getInputs().get(ordinalInParent)); if (copy != null) parent.replaceInput(ordinalInParent, copy); }
private boolean fixUpInputs(RelNode rel) { List<RelNode> inputs = rel.getInputs(); int i = -1; int changeCount = 0; for (RelNode input : inputs) { ++i; if (input instanceof RelSubset) { final RelSubset subset = (RelSubset) input; RelSubset newSubset = canonize(subset); if (newSubset != subset) { rel.replaceInput(i, newSubset); if (subset.set != newSubset.set) { subset.set.parents.remove(rel); newSubset.set.parents.add(rel); } changeCount++; } } } return changeCount > 0; }
private static RelNode introduceDerivedTable(final RelNode rel, RelNode parent) { int i = 0; int pos = -1; List<RelNode> childList = parent.getInputs(); for (RelNode child : childList) { if (child == rel) { pos = i; break; } i++; } if (pos == -1) { throw new RuntimeException("Couldn't find child node in parent's inputs"); } RelNode select = introduceDerivedTable(rel); parent.replaceInput(pos, select); return select; }
private boolean fixUpInputs(RelNode rel) { List<RelNode> inputs = rel.getInputs(); int i = -1; int changeCount = 0; for (RelNode input : inputs) { ++i; if (input instanceof RelSubset) { final RelSubset subset = (RelSubset) input; RelSubset newSubset = canonize(subset); if (newSubset != subset) { rel.replaceInput(i, newSubset); if (subset.set != newSubset.set) { subset.set.parents.remove(rel); newSubset.set.parents.add(rel); } changeCount++; } } } return changeCount > 0; }
public void rewriteGeneric(RelNode rel) { RelNode newRel = rel.copy(rel.getTraitSet(), rel.getInputs()); List<RelNode> oldInputs = rel.getInputs(); for (int i = 0; i < oldInputs.size(); ++i) { newRel.replaceInput( i, getNewForOldRel(oldInputs.get(i))); } setNewForOldRel(rel, newRel); }
public void rewriteGeneric(RelNode rel) { RelNode newRel = rel.copy(rel.getTraitSet(), rel.getInputs()); List<RelNode> oldInputs = rel.getInputs(); for (int i = 0; i < oldInputs.size(); ++i) { newRel.replaceInput( i, getNewForOldRel(oldInputs.get(i))); } setNewForOldRel(rel, newRel); }
private RelNode buildFinalPlan(HepRelVertex vertex) { RelNode rel = vertex.getCurrentRel(); notifyChosen(rel); // Recursively process children, replacing this rel's inputs // with corresponding child rels. List<RelNode> inputs = rel.getInputs(); for (int i = 0; i < inputs.size(); ++i) { RelNode child = inputs.get(i); if (!(child instanceof HepRelVertex)) { // Already replaced. continue; } child = buildFinalPlan((HepRelVertex) child); rel.replaceInput(i, child); rel.recomputeDigest(); } return rel; }
private RelNode buildFinalPlan(HepRelVertex vertex) { RelNode rel = vertex.getCurrentRel(); notifyChosen(rel); // Recursively process children, replacing this rel's inputs // with corresponding child rels. List<RelNode> inputs = rel.getInputs(); for (int i = 0; i < inputs.size(); ++i) { RelNode child = inputs.get(i); if (!(child instanceof HepRelVertex)) { // Already replaced. continue; } child = buildFinalPlan((HepRelVertex) child); rel.replaceInput(i, child); rel.recomputeDigest(); } return rel; }
private void pruneSubtree(RelNode parent, TableScan scan, int leftOrRight) { RelOptTableImpl lowLevelTable = ((RelOptTableImpl) scan.getTable()); List<String> newNames = createTableAlias(lowLevelTable.getNames()); RelNode originChild = parent.getInputs().get(leftOrRight); executePruningSubtree(originChild, scan.getTable(), newNames.get(0)); TableScan tempTableScan = createTemporaryTableScan(lowLevelTable, newNames, scan, originChild); parent.replaceInput(leftOrRight, tempTableScan); }
/** Fallback if none of the other {@code decorrelateRel} methods match. */ public Frame decorrelateRel(RelNode rel) { RelNode newRel = rel.copy(rel.getTraitSet(), rel.getInputs()); if (rel.getInputs().size() > 0) { List<RelNode> oldInputs = rel.getInputs(); List<RelNode> newInputs = new ArrayList<>(); for (int i = 0; i < oldInputs.size(); ++i) { final Frame frame = getInvoke(oldInputs.get(i)); if (frame == null || frame.c != null) { // if input is not rewritten, or if it produces correlated variables, terminate rewrite return null; } newInputs.add(frame.r); newRel.replaceInput(i, frame.r); } if (!Util.equalShallow(oldInputs, newInputs)) { newRel = rel.copy(rel.getTraitSet(), newInputs); } } // the output position should not change since there are no corVars coming from below. return new Frame(rel, newRel, null, identityMap(rel.getRowType().getFieldCount())); }
private RelNode introduceProjectIfNeeded(RelNode optimizedOptiqPlan) throws CalciteSemanticException { RelNode parent = null; RelNode input = optimizedOptiqPlan; RelNode newRoot = optimizedOptiqPlan; while (!(input instanceof Project) && (input instanceof Sort)) { parent = input; input = input.getInput(0); } if (!(input instanceof Project)) { HiveProject hpRel = HiveProject.create(input, HiveCalciteUtil.getProjsFromBelowAsInputRef(input), input.getRowType().getFieldNames()); if (input == optimizedOptiqPlan) { newRoot = hpRel; } else { parent.replaceInput(0, hpRel); } } return newRoot; }