Esempio n. 1
0
  /**
   * 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);
  }
Esempio n. 2
0
 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;
 }
Esempio n. 3
0
 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);
 }
Esempio n. 4
0
 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);
 }
Esempio n. 5
0
    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());
    }
Esempio n. 6
0
 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());
 }
Esempio n. 7
0
    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());
    }
Esempio n. 8
0
 /** 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);
 }
Esempio n. 9
0
    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());
    }
Esempio n. 10
0
  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;
  }
Esempio n. 11
0
 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;
   }
 }
Esempio n. 12
0
  /**
   * 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;
  }
Esempio n. 13
0
 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);
 }
Esempio n. 14
0
 @Override
 protected RelNode visitChild(RelNode parent, int i, RelNode child) {
   child.accept(this);
   parent.getCluster().setMetadataProvider(metadataProvider);
   return parent;
 }