/** * Creates a relational expression that projects the given fields of the input. * * <p>Optimizes if the fields are the identity projection. * * @param relBuilder RelBuilder * @param child Input relational expression * @param posList Source of each projected field * @return Relational expression that projects given fields */ public static RelNode createProject( final RelBuilder relBuilder, final RelNode child, final List<Integer> posList) { RelDataType rowType = child.getRowType(); final List<String> fieldNames = rowType.getFieldNames(); final RexBuilder rexBuilder = child.getCluster().getRexBuilder(); return createProject( child, new AbstractList<RexNode>() { public int size() { return posList.size(); } public RexNode get(int index) { final int pos = posList.get(index); return rexBuilder.makeInputRef(child, pos); } }, new AbstractList<String>() { public int size() { return posList.size(); } public String get(int index) { final int pos = posList.get(index); return fieldNames.get(pos); } }, true, relBuilder); }
public static List<ExprNodeDesc> getExprNodes( List<Integer> inputRefs, RelNode inputRel, String inputTabAlias) { List<ExprNodeDesc> exprNodes = new ArrayList<ExprNodeDesc>(); List<RexNode> rexInputRefs = getInputRef(inputRefs, inputRel); List<RexNode> exprs = inputRel.getChildExps(); // TODO: Change ExprNodeConverter to be independent of Partition Expr ExprNodeConverter exprConv = new ExprNodeConverter( inputTabAlias, inputRel.getRowType(), new HashSet<Integer>(), inputRel.getCluster().getTypeFactory()); for (int index = 0; index < rexInputRefs.size(); index++) { // The following check is only a guard against failures. // TODO: Knowing which expr is constant in GBY's aggregation function // arguments could be better done using Metadata provider of Calcite. if (exprs != null && index < exprs.size() && exprs.get(index) instanceof RexLiteral) { ExprNodeDesc exprNodeDesc = exprConv.visitLiteral((RexLiteral) exprs.get(index)); exprNodes.add(exprNodeDesc); } else { RexNode iRef = rexInputRefs.get(index); exprNodes.add(iRef.accept(exprConv)); } } return exprNodes; }
public RelNode convert(RelNode rel) { final LogicalMinus minus = (LogicalMinus) rel; if (minus.all) { return null; // EXCEPT ALL not implemented } final RelTraitSet traitSet = rel.getTraitSet().replace(out); return new JdbcMinus(rel.getCluster(), traitSet, convertList(minus.getInputs(), out), false); }
public RelNode convert(RelNode rel) { final LogicalIntersect intersect = (LogicalIntersect) rel; if (intersect.all) { return null; // INTERSECT ALL not implemented } final RelTraitSet traitSet = intersect.getTraitSet().replace(out); return new JdbcIntersect( rel.getCluster(), traitSet, convertList(intersect.getInputs(), out), false); }
public RelNode convert(RelNode rel) { final LogicalFilter filter = (LogicalFilter) rel; return new JdbcFilter( rel.getCluster(), rel.getTraitSet().replace(out), convert(filter.getInput(), filter.getInput().getTraitSet().replace(out)), filter.getCondition()); }
public RelNode convert(RelNode rel) { final Sort sort = (Sort) rel; if (sort.offset != null || sort.fetch != null) { // Cannot implement "OFFSET n FETCH n" currently. return null; } final RelTraitSet traitSet = sort.getTraitSet().replace(out); return new JdbcSort( rel.getCluster(), traitSet, convert(sort.getInput(), traitSet), sort.getCollation()); }
public RelNode convert(RelNode rel) { final LogicalProject project = (LogicalProject) rel; return new JdbcProject( rel.getCluster(), rel.getTraitSet().replace(out), convert(project.getInput(), project.getInput().getTraitSet().replace(out)), project.getProjects(), project.getRowType()); }
/** Creates a SemiJoin. */ public static SemiJoin create( RelNode left, RelNode right, RexNode condition, ImmutableIntList leftKeys, ImmutableIntList rightKeys) { final RelOptCluster cluster = left.getCluster(); return new SemiJoin( cluster, cluster.traitSetOf(Convention.NONE), left, right, condition, leftKeys, rightKeys); }
public RelNode convert(RelNode rel) { final LogicalCalc calc = (LogicalCalc) rel; // If there's a multiset, let FarragoMultisetSplitter work on it // first. if (RexMultisetUtil.containsMultiset(calc.getProgram())) { return null; } return new JdbcCalc( rel.getCluster(), rel.getTraitSet().replace(out), convert(calc.getInput(), calc.getTraitSet().replace(out)), calc.getProgram()); }
private RelNode convertToRel(SqlNode node) throws RelConversionException { final RelNode convertedNode = planner.convert(node); final RelMetadataProvider provider = convertedNode.getCluster().getMetadataProvider(); // Register RelMetadataProvider with HepPlanner. final List<RelMetadataProvider> list = Lists.newArrayList(provider); hepPlanner.registerMetadataProviders(list); final RelMetadataProvider cachingMetaDataProvider = new CachingRelMetadataProvider(ChainedRelMetadataProvider.of(list), hepPlanner); convertedNode.accept(new MetaDataProviderModifier(cachingMetaDataProvider)); // HepPlanner is specifically used for Window Function planning only. hepPlanner.setRoot(convertedNode); RelNode rel = hepPlanner.findBestExp(); rel.accept(new MetaDataProviderModifier(provider)); return rel; }
public RelNode convert(RelNode rel) { final LogicalAggregate agg = (LogicalAggregate) rel; if (agg.getGroupSets().size() != 1) { // GROUPING SETS not supported; see // [CALCITE-734] Push GROUPING SETS to underlying SQL via JDBC adapter return null; } final RelTraitSet traitSet = agg.getTraitSet().replace(out); try { return new JdbcAggregate( rel.getCluster(), traitSet, convert(agg.getInput(), out), agg.indicator, agg.getGroupSet(), agg.getGroupSets(), agg.getAggCallList()); } catch (InvalidRelException e) { LOGGER.fine(e.toString()); return null; } }
/** * Push any equi join conditions that are not column references as Projections on top of the * children. * * @param factory Project factory to use. * @param inputRels inputs to a join * @param leftJoinKeys expressions for LHS of join key * @param rightJoinKeys expressions for RHS of join key * @param systemColCount number of system columns, usually zero. These columns are projected at * the leading edge of the output row. * @param leftKeys on return this contains the join key positions from the new project rel on the * LHS. * @param rightKeys on return this contains the join key positions from the new project rel on the * RHS. * @return the join condition after the equi expressions pushed down. */ public static RexNode projectNonColumnEquiConditions( ProjectFactory factory, RelNode[] inputRels, List<RexNode> leftJoinKeys, List<RexNode> rightJoinKeys, int systemColCount, List<Integer> leftKeys, List<Integer> rightKeys) { RelNode leftRel = inputRels[0]; RelNode rightRel = inputRels[1]; RexBuilder rexBuilder = leftRel.getCluster().getRexBuilder(); RexNode outJoinCond = null; int origLeftInputSize = leftRel.getRowType().getFieldCount(); int origRightInputSize = rightRel.getRowType().getFieldCount(); List<RexNode> newLeftFields = new ArrayList<RexNode>(); List<String> newLeftFieldNames = new ArrayList<String>(); List<RexNode> newRightFields = new ArrayList<RexNode>(); List<String> newRightFieldNames = new ArrayList<String>(); int leftKeyCount = leftJoinKeys.size(); int i; for (i = 0; i < origLeftInputSize; i++) { final RelDataTypeField field = leftRel.getRowType().getFieldList().get(i); newLeftFields.add(rexBuilder.makeInputRef(field.getType(), i)); newLeftFieldNames.add(field.getName()); } for (i = 0; i < origRightInputSize; i++) { final RelDataTypeField field = rightRel.getRowType().getFieldList().get(i); newRightFields.add(rexBuilder.makeInputRef(field.getType(), i)); newRightFieldNames.add(field.getName()); } int newKeyCount = 0; List<Pair<Integer, Integer>> origColEqConds = new ArrayList<Pair<Integer, Integer>>(); for (i = 0; i < leftKeyCount; i++) { RexNode leftKey = leftJoinKeys.get(i); RexNode rightKey = rightJoinKeys.get(i); if (leftKey instanceof RexInputRef && rightKey instanceof RexInputRef) { origColEqConds.add( Pair.of(((RexInputRef) leftKey).getIndex(), ((RexInputRef) rightKey).getIndex())); } else { newLeftFields.add(leftKey); newLeftFieldNames.add(null); newRightFields.add(rightKey); newRightFieldNames.add(null); newKeyCount++; } } for (i = 0; i < origColEqConds.size(); i++) { Pair<Integer, Integer> p = origColEqConds.get(i); RexNode leftKey = leftJoinKeys.get(i); RexNode rightKey = rightJoinKeys.get(i); leftKeys.add(p.left); rightKeys.add(p.right); RexNode cond = rexBuilder.makeCall( SqlStdOperatorTable.EQUALS, rexBuilder.makeInputRef(leftKey.getType(), systemColCount + p.left), rexBuilder.makeInputRef( rightKey.getType(), systemColCount + origLeftInputSize + newKeyCount + p.right)); if (outJoinCond == null) { outJoinCond = cond; } else { outJoinCond = rexBuilder.makeCall(SqlStdOperatorTable.AND, outJoinCond, cond); } } if (newKeyCount == 0) { return outJoinCond; } int newLeftOffset = systemColCount + origLeftInputSize; int newRightOffset = systemColCount + origLeftInputSize + origRightInputSize + newKeyCount; for (i = 0; i < newKeyCount; i++) { leftKeys.add(origLeftInputSize + i); rightKeys.add(origRightInputSize + i); RexNode cond = rexBuilder.makeCall( SqlStdOperatorTable.EQUALS, rexBuilder.makeInputRef( newLeftFields.get(origLeftInputSize + i).getType(), newLeftOffset + i), rexBuilder.makeInputRef( newRightFields.get(origRightInputSize + i).getType(), newRightOffset + i)); if (outJoinCond == null) { outJoinCond = cond; } else { outJoinCond = rexBuilder.makeCall(SqlStdOperatorTable.AND, outJoinCond, cond); } } // added project if need to produce new keys than the original input // fields if (newKeyCount > 0) { leftRel = factory.createProject( leftRel, newLeftFields, SqlValidatorUtil.uniquify(newLeftFieldNames)); rightRel = factory.createProject( rightRel, newRightFields, SqlValidatorUtil.uniquify(newRightFieldNames)); } inputRels[0] = leftRel; inputRels[1] = rightRel; return outJoinCond; }
public RelNode convert(RelNode rel) { final LogicalUnion union = (LogicalUnion) rel; final RelTraitSet traitSet = union.getTraitSet().replace(out); return new JdbcUnion( rel.getCluster(), traitSet, convertList(union.getInputs(), out), union.all); }
@Override protected RelNode visitChild(RelNode parent, int i, RelNode child) { child.accept(this); parent.getCluster().setMetadataProvider(metadataProvider); return parent; }