Beispiel #1
0
  public void onMatch(RelOptRuleCall call) {
    assert matches(call);
    final JoinRel join = (JoinRel) call.rels[0];
    final List<Integer> leftKeys = new ArrayList<Integer>();
    final List<Integer> rightKeys = new ArrayList<Integer>();
    RelNode right = join.getRight();
    final RelNode left = join.getLeft();
    RexNode remainingCondition =
        RelOptUtil.splitJoinCondition(left, right, join.getCondition(), leftKeys, rightKeys);
    assert leftKeys.size() == rightKeys.size();
    final List<CorrelatorRel.Correlation> correlationList =
        new ArrayList<CorrelatorRel.Correlation>();
    if (leftKeys.size() > 0) {
      final RelOptCluster cluster = join.getCluster();
      final RexBuilder rexBuilder = cluster.getRexBuilder();
      int k = 0;
      RexNode condition = null;
      for (Integer leftKey : leftKeys) {
        Integer rightKey = rightKeys.get(k++);
        final String dyn_inIdStr = cluster.getQuery().createCorrel();
        final int dyn_inId = RelOptQuery.getCorrelOrdinal(dyn_inIdStr);

        // Create correlation to say 'each row, set variable #id
        // to the value of column #leftKey'.
        correlationList.add(new CorrelatorRel.Correlation(dyn_inId, leftKey));
        condition =
            RelOptUtil.andJoinFilters(
                rexBuilder,
                condition,
                rexBuilder.makeCall(
                    SqlStdOperatorTable.equalsOperator,
                    rexBuilder.makeInputRef(
                        right.getRowType().getFieldList().get(rightKey).getType(), rightKey),
                    rexBuilder.makeCorrel(
                        left.getRowType().getFieldList().get(leftKey).getType(), dyn_inIdStr)));
      }
      right = CalcRel.createFilter(right, condition);
    }
    RelNode newRel =
        new CorrelatorRel(
            join.getCluster(),
            left,
            right,
            remainingCondition,
            correlationList,
            join.getJoinType());
    call.transformTo(newRel);
  }
Beispiel #2
0
 /**
  * Returns whether the type of an array of expressions is compatible with a struct type.
  *
  * @param exprs Array of expressions
  * @param type Type
  * @param fail Whether to fail if there is a mismatch
  * @return Whether every expression has the same type as the corresponding member of the struct
  *     type
  * @see RelOptUtil#eq(String, RelDataType, String, RelDataType, boolean)
  */
 public static boolean compatibleTypes(RexNode[] exprs, RelDataType type, boolean fail) {
   final RelDataTypeField[] fields = type.getFields();
   if (exprs.length != fields.length) {
     assert !fail : "rowtype mismatches expressions";
     return false;
   }
   for (int i = 0; i < fields.length; i++) {
     final RelDataType exprType = exprs[i].getType();
     final RelDataType fieldType = fields[i].getType();
     if (!RelOptUtil.eq("type1", exprType, "type2", fieldType, fail)) {
       return false;
     }
   }
   return true;
 }
Beispiel #3
0
    public void assertConvertsTo(String sql, String plan, boolean trim) {
      String sql2 = getDiffRepos().expand("sql", sql);
      RelNode rel = convertSqlToRel(sql2);

      assertTrue(rel != null);
      assertValid(rel);

      if (trim) {
        final RelFieldTrimmer trimmer = createFieldTrimmer();
        rel = trimmer.trim(rel);
        assertTrue(rel != null);
        assertValid(rel);
      }

      // NOTE jvs 28-Mar-2006:  insert leading newline so
      // that plans come out nicely stacked instead of first
      // line immediately after CDATA start
      String actual = NL + RelOptUtil.toString(rel);
      diffRepos.assertEquals("plan", plan, actual);
    }
Beispiel #4
0
 /**
  * Returns whether the leading edge of a given array of expressions is wholly {@link RexInputRef}
  * objects with types corresponding to the underlying datatype.
  */
 public static boolean containIdentity(RexNode[] exprs, RelDataType rowType, boolean fail) {
   final RelDataTypeField[] fields = rowType.getFields();
   if (exprs.length < fields.length) {
     assert !fail : "exprs/rowType length mismatch";
     return false;
   }
   for (int i = 0; i < fields.length; i++) {
     if (!(exprs[i] instanceof RexInputRef)) {
       assert !fail : "expr[" + i + "] is not a RexInputRef";
       return false;
     }
     RexInputRef inputRef = (RexInputRef) exprs[i];
     if (inputRef.getIndex() != i) {
       assert !fail : "expr[" + i + "] has ordinal " + inputRef.getIndex();
       return false;
     }
     if (!RelOptUtil.eq("type1", exprs[i].getType(), "type2", fields[i].getType(), fail)) {
       return false;
     }
   }
   return true;
 }