org.apache.calcite.rex.RexCorrelVariable Java Examples

The following examples show how to use org.apache.calcite.rex.RexCorrelVariable. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: RelBuilderTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void testCorrelationFails() {
  final RelBuilder builder = RelBuilder.create(config().build());
  final Holder<RexCorrelVariable> v = Holder.of(null);
  try {
    builder.scan("EMP")
        .variable(v)
        .filter(builder.equals(builder.field(0), v.get()))
        .scan("DEPT")
        .join(JoinRelType.INNER, builder.literal(true),
            ImmutableSet.of(v.get().id));
    fail("expected error");
  } catch (IllegalArgumentException e) {
    assertThat(e.getMessage(),
        containsString("variable $cor0 must not be used by left input to correlation"));
  }
}
 
Example #2
Source File: RelBuilderTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void testCorrelationWithCondition() {
  final RelBuilder builder = RelBuilder.create(config().build());
  final Holder<RexCorrelVariable> v = Holder.of(null);
  RelNode root = builder.scan("EMP")
      .variable(v)
      .scan("DEPT")
      .filter(
          builder.equals(builder.field(0),
              builder.field(v.get(), "DEPTNO")))
      .join(JoinRelType.LEFT,
          builder.equals(builder.field(2, 0, "SAL"),
              builder.literal(1000)),
          ImmutableSet.of(v.get().id))
      .build();
  // Note that the join filter gets pushed to the right-hand input of
  // LogicalCorrelate
  final String expected = ""
      + "LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{7}])\n"
      + "  LogicalTableScan(table=[[scott, EMP]])\n"
      + "  LogicalFilter(condition=[=($cor0.SAL, 1000)])\n"
      + "    LogicalFilter(condition=[=($0, $cor0.DEPTNO)])\n"
      + "      LogicalTableScan(table=[[scott, DEPT]])\n";
  assertThat(root, hasTree(expected));
}
 
Example #3
Source File: RelMetadataTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void testColumnUniquenessForCorrelateWithConstantColumns() {
  final FrameworkConfig config = RelBuilderTest.config().build();
  final RelBuilder builder = RelBuilder.create(config);
  RelNode rel0 = builder.scan("EMP")
      .project(builder.field("DEPTNO"), builder.field("SAL"))
      .distinct()
      .filter(builder.equals(builder.field("SAL"), builder.literal(1)))
      .build();
  final Holder<RexCorrelVariable> v = Holder.of(null);
  final RelNode rel1 = builder.scan("EMP")
      .variable(v)
      .project(builder.field("DEPTNO"), builder.field("SAL"))
      .filter(
          builder.equals(builder.field(0), builder.field(v.get(), "DEPTNO")))
      .build();
  final RelNode correl = builder.push(rel0)
      .variable(v)
      .push(rel1)
      .correlate(JoinRelType.SEMI, v.get().id, builder.field(2, 0, "DEPTNO"))
      .build();
  final RelMetadataQuery mq = correl.getCluster().getMetadataQuery();
  assertThat(mq.areColumnsUnique(correl, ImmutableBitSet.of(0)), is(true));
}
 
Example #4
Source File: HBTQueryConvertor.java    From Mycat2 with GNU General Public License v3.0 6 votes vote down vote up
private RelNode correlate(CorrelateSchema input) {
    RelNode left = handle(input.getLeft());
    Holder<RexCorrelVariable> of = Holder.of(null);
    relBuilder.push(left);
    relBuilder.variable(of);
    correlVariableMap.put(input.getRefName(), of.get());
    RelNode right = handle(input.getRight());
    relBuilder.clear();
    final CorrelationId id = of.get().id;
    final ImmutableBitSet requiredColumns =
            RelOptUtil.correlationColumns(id, right);
    relBuilder.push(left);
    List<RexInputRef> collect = requiredColumns.asList().stream().map(i -> relBuilder.field(i)).collect(Collectors.toList());
    relBuilder.clear();
    relBuilder.push(left);
    relBuilder.push(right);
    return relBuilder.correlate(joinOp(input.getOp()), of.get().id, collect).build();
}
 
Example #5
Source File: RelBuilderTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void testCorrelateWithComplexFields() {
  final RelBuilder builder = RelBuilder.create(config().build());
  final Holder<RexCorrelVariable> v = Holder.of(null);
  RelNode root = builder.scan("EMP")
      .variable(v)
      .scan("DEPT")
      .filter(
          builder.equals(builder.field(0),
              builder.field(v.get(), "DEPTNO")))
      .correlate(JoinRelType.LEFT, v.get().id,
          builder.field(2, 0, "DEPTNO"),
          builder.getRexBuilder().makeCall(SqlStdOperatorTable.AS,
              builder.field(2, 0, "EMPNO"),
              builder.literal("RENAMED_EMPNO")))
      .build();

  final String expected = ""
      + "LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{0, 7}])\n"
      + "  LogicalProject(RENAMED_EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7])\n"
      + "    LogicalTableScan(table=[[scott, EMP]])\n"
      + "  LogicalFilter(condition=[=($0, $cor0.DEPTNO)])\n"
      + "    LogicalTableScan(table=[[scott, DEPT]])\n";
  assertThat(root, hasTree(expected));
}
 
Example #6
Source File: RelBuilderTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void testCorrelate() {
  final RelBuilder builder = RelBuilder.create(config().build());
  final Holder<RexCorrelVariable> v = Holder.of(null);
  RelNode root = builder.scan("EMP")
      .variable(v)
      .scan("DEPT")
      .filter(
          builder.equals(builder.field(0),
              builder.field(v.get(), "DEPTNO")))
      .correlate(JoinRelType.LEFT, v.get().id, builder.field(2, 0, "DEPTNO"))
      .build();

  final String expected = ""
      + "LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{7}])\n"
      + "  LogicalTableScan(table=[[scott, EMP]])\n"
      + "  LogicalFilter(condition=[=($0, $cor0.DEPTNO)])\n"
      + "    LogicalTableScan(table=[[scott, DEPT]])\n";
  assertThat(root, hasTree(expected));
}
 
Example #7
Source File: RelDecorrelator.java    From calcite with Apache License 2.0 6 votes vote down vote up
private boolean references(RexNode e, CorRef correlation) {
  switch (e.getKind()) {
  case CAST:
    final RexNode operand = ((RexCall) e).getOperands().get(0);
    if (isWidening(e.getType(), operand.getType())) {
      return references(operand, correlation);
    }
    return false;
  case FIELD_ACCESS:
    final RexFieldAccess f = (RexFieldAccess) e;
    if (f.getField().getIndex() == correlation.field
        && f.getReferenceExpr() instanceof RexCorrelVariable) {
      if (((RexCorrelVariable) f.getReferenceExpr()).id == correlation.corr) {
        return true;
      }
    }
    // fall through
  default:
    return false;
  }
}
 
Example #8
Source File: RelDecorrelator.java    From Bats with Apache License 2.0 6 votes vote down vote up
private boolean references(RexNode e, CorRef correlation) {
    switch (e.getKind()) {
    case CAST:
        final RexNode operand = ((RexCall) e).getOperands().get(0);
        if (isWidening(e.getType(), operand.getType())) {
            return references(operand, correlation);
        }
        return false;
    case FIELD_ACCESS:
        final RexFieldAccess f = (RexFieldAccess) e;
        if (f.getField().getIndex() == correlation.field && f.getReferenceExpr() instanceof RexCorrelVariable) {
            if (((RexCorrelVariable) f.getReferenceExpr()).getCorrelationId() == correlation.corr) {
                return true;
            }
        }
        // fall through
    default:
        return false;
    }
}
 
Example #9
Source File: RelDecorrelator.java    From flink with Apache License 2.0 6 votes vote down vote up
private boolean references(RexNode e, CorRef correlation) {
  switch (e.getKind()) {
  case CAST:
    final RexNode operand = ((RexCall) e).getOperands().get(0);
    if (isWidening(e.getType(), operand.getType())) {
      return references(operand, correlation);
    }
    return false;
  case FIELD_ACCESS:
    final RexFieldAccess f = (RexFieldAccess) e;
    if (f.getField().getIndex() == correlation.field
        && f.getReferenceExpr() instanceof RexCorrelVariable) {
      if (((RexCorrelVariable) f.getReferenceExpr()).id == correlation.corr) {
        return true;
      }
    }
    // fall through
  default:
    return false;
  }
}
 
Example #10
Source File: RelFieldTrimmer.java    From Bats with Apache License 2.0 6 votes vote down vote up
protected TrimResult result(RelNode r, final Mapping mapping) {
    final RexBuilder rexBuilder = relBuilder.getRexBuilder();
    for (final CorrelationId correlation : r.getVariablesSet()) {
        r = r.accept(new CorrelationReferenceFinder() {
            @Override
            protected RexNode handle(RexFieldAccess fieldAccess) {
                final RexCorrelVariable v = (RexCorrelVariable) fieldAccess.getReferenceExpr();
                if (v.getCorrelationId().equals(correlation)
                        && v.getType().getFieldCount() == mapping.getSourceCount()) {
                    final int old = fieldAccess.getField().getIndex();
                    final int new_ = mapping.getTarget(old);
                    final RelDataTypeFactory.Builder typeBuilder = relBuilder.getTypeFactory().builder();
                    for (int target : Util.range(mapping.getTargetCount())) {
                        typeBuilder.add(v.getType().getFieldList().get(mapping.getSource(target)));
                    }
                    final RexNode newV = rexBuilder.makeCorrel(typeBuilder.build(), v.getCorrelationId());
                    if (old != new_) {
                        return rexBuilder.makeFieldAccess(newV, new_);
                    }
                }
                return fieldAccess;
            }
        });
    }
    return new TrimResult(r, mapping);
}
 
Example #11
Source File: RelDecorrelator.java    From flink with Apache License 2.0 6 votes vote down vote up
private boolean references(RexNode e, CorRef correlation) {
  switch (e.getKind()) {
  case CAST:
    final RexNode operand = ((RexCall) e).getOperands().get(0);
    if (isWidening(e.getType(), operand.getType())) {
      return references(operand, correlation);
    }
    return false;
  case FIELD_ACCESS:
    final RexFieldAccess f = (RexFieldAccess) e;
    if (f.getField().getIndex() == correlation.field
        && f.getReferenceExpr() instanceof RexCorrelVariable) {
      if (((RexCorrelVariable) f.getReferenceExpr()).id == correlation.corr) {
        return true;
      }
    }
    // fall through
  default:
    return false;
  }
}
 
Example #12
Source File: ToLogicalConverterTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Test void testCorrelation() {
  final RelBuilder builder = builder();
  final Holder<RexCorrelVariable> v = Holder.of(null);
  final RelNode rel = builder.scan("EMP")
      .variable(v)
      .scan("DEPT")
      .join(JoinRelType.LEFT,
          builder.equals(builder.field(2, 0, "SAL"),
              builder.literal(1000)),
          ImmutableSet.of(v.get().id))
      .build();
  String expectedPhysical = ""
      + "EnumerableCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{}])\n"
      + "  EnumerableTableScan(table=[[scott, EMP]])\n"
      + "  EnumerableFilter(condition=[=($cor0.SAL, 1000)])\n"
      + "    EnumerableTableScan(table=[[scott, DEPT]])\n";
  String expectedLogical = ""
      + "LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{5}])\n"
      + "  LogicalTableScan(table=[[scott, EMP]])\n"
      + "  LogicalFilter(condition=[=($cor0.SAL, 1000)])\n"
      + "    LogicalTableScan(table=[[scott, DEPT]])\n";
  verify(rel, expectedPhysical, expectedLogical);
}
 
Example #13
Source File: RelDecorrelator.java    From Bats with Apache License 2.0 5 votes vote down vote up
private RexVisitorImpl<Void> rexVisitor(final RelNode rel) {
    return new RexVisitorImpl<Void>(true) {
        @Override
        public Void visitFieldAccess(RexFieldAccess fieldAccess) {
            final RexNode ref = fieldAccess.getReferenceExpr();
            if (ref instanceof RexCorrelVariable) {
                final RexCorrelVariable var = (RexCorrelVariable) ref;
                if (mapFieldAccessToCorVar.containsKey(fieldAccess)) {
                    // for cases where different Rel nodes are referring to
                    // same correlation var (e.g. in case of NOT IN)
                    // avoid generating another correlation var
                    // and record the 'rel' is using the same correlation
                    mapRefRelToCorRef.put(rel, mapFieldAccessToCorVar.get(fieldAccess));
                } else {
                    final CorRef correlation = new CorRef(var.getCorrelationId(),
                            fieldAccess.getField().getIndex(), corrIdGenerator++);
                    mapFieldAccessToCorVar.put(fieldAccess, correlation);
                    mapRefRelToCorRef.put(rel, correlation);
                }
            }
            return super.visitFieldAccess(fieldAccess);
        }

        @Override
        public Void visitSubQuery(RexSubQuery subQuery) {
            subQuery.getRel().accept(CorelMapBuilder.this);
            return super.visitSubQuery(subQuery);
        }
    };
}
 
Example #14
Source File: DeduplicateCorrelateVariables.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public RexNode visitCorrelVariable(RexCorrelVariable variable) {
  if (!alternateIds.contains(variable.id)) {
    return variable;
  }

  return builder.makeCorrel(variable.getType(), canonicalId);
}
 
Example #15
Source File: RelFieldTrimmer.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Trims the fields of an input relational expression.
 *
 * @param rel        Relational expression
 * @param input      Input relational expression, whose fields to trim
 * @param fieldsUsed Bitmap of fields needed by the consumer
 * @return New relational expression and its field mapping
 */
protected TrimResult trimChild(RelNode rel, RelNode input, final ImmutableBitSet fieldsUsed,
        Set<RelDataTypeField> extraFields) {
    final ImmutableBitSet.Builder fieldsUsedBuilder = fieldsUsed.rebuild();

    // Fields that define the collation cannot be discarded.
    final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
    final ImmutableList<RelCollation> collations = mq.collations(input);
    for (RelCollation collation : collations) {
        for (RelFieldCollation fieldCollation : collation.getFieldCollations()) {
            fieldsUsedBuilder.set(fieldCollation.getFieldIndex());
        }
    }

    // Correlating variables are a means for other relational expressions to use
    // fields.
    for (final CorrelationId correlation : rel.getVariablesSet()) {
        rel.accept(new CorrelationReferenceFinder() {
            @Override
            protected RexNode handle(RexFieldAccess fieldAccess) {
                final RexCorrelVariable v = (RexCorrelVariable) fieldAccess.getReferenceExpr();
                if (v.getCorrelationId().equals(correlation)) {
                    fieldsUsedBuilder.set(fieldAccess.getField().getIndex());
                }
                return fieldAccess;
            }
        });
    }

    return dispatchTrimFields(input, fieldsUsedBuilder.build(), extraFields);
}
 
Example #16
Source File: RelDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
private RexVisitorImpl<Void> rexVisitor(final RelNode rel) {
  return new RexVisitorImpl<Void>(true) {
    @Override public Void visitFieldAccess(RexFieldAccess fieldAccess) {
      final RexNode ref = fieldAccess.getReferenceExpr();
      if (ref instanceof RexCorrelVariable) {
        final RexCorrelVariable var = (RexCorrelVariable) ref;
        if (mapFieldAccessToCorVar.containsKey(fieldAccess)) {
          // for cases where different Rel nodes are referring to
          // same correlation var (e.g. in case of NOT IN)
          // avoid generating another correlation var
          // and record the 'rel' is using the same correlation
          mapRefRelToCorRef.put(rel,
              mapFieldAccessToCorVar.get(fieldAccess));
        } else {
          final CorRef correlation =
              new CorRef(var.id, fieldAccess.getField().getIndex(),
                  corrIdGenerator++);
          mapFieldAccessToCorVar.put(fieldAccess, correlation);
          mapRefRelToCorRef.put(rel, correlation);
        }
      }
      return super.visitFieldAccess(fieldAccess);
    }

    @Override public Void visitSubQuery(RexSubQuery subQuery) {
      subQuery.rel.accept(CorelMapBuilder.this);
      return super.visitSubQuery(subQuery);
    }
  };
}
 
Example #17
Source File: CorrelationReferenceFinder.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override
public RexNode visitFieldAccess(RexFieldAccess fieldAccess) {
    if (fieldAccess.getReferenceExpr() instanceof RexCorrelVariable) {
        return finder.handle(fieldAccess);
    }
    return super.visitFieldAccess(fieldAccess);
}
 
Example #18
Source File: ProjectCorrelateTransposeRule.java    From Bats with Apache License 2.0 5 votes vote down vote up
public RexFieldAccessReplacer(CorrelationId rexCorrelVariableToReplace, RexCorrelVariable rexCorrelVariable,
        RexBuilder builder, Map<Integer, Integer> requiredColsMap) {
    this.rexCorrelVariableToReplace = rexCorrelVariableToReplace;
    this.rexCorrelVariable = rexCorrelVariable;
    this.builder = builder;
    this.requiredColsMap = requiredColsMap;
}
 
Example #19
Source File: RelBuilder.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** Creates a correlation variable for the current input, and writes it into
 * a Holder. */
public RelBuilder variable(Holder<RexCorrelVariable> v) {
  v.set((RexCorrelVariable)
      getRexBuilder().makeCorrel(peek().getRowType(),
          cluster.createCorrel()));
  return this;
}
 
Example #20
Source File: DremioFieldTrimmer.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
@Override
protected TrimResult result(RelNode r, final Mapping mapping) {
  final RexBuilder rexBuilder = builder.getRexBuilder();
  for (final CorrelationId correlation : r.getVariablesSet()) {
    r = r.accept(
            new CorrelationReferenceFinder() {
              protected RexNode handle(RexFieldAccess fieldAccess) {
                final RexCorrelVariable v =
                        (RexCorrelVariable) fieldAccess.getReferenceExpr();
                if (v.id.equals(correlation)) {
                  final int old = fieldAccess.getField().getIndex();
                  final int new_ = mapping.getTarget(old);
                  final RelDataTypeFactory.Builder typeBuilder =
                          builder.getTypeFactory().builder();
                  for (IntPair pair : mapping) {
                    if (pair.source < v.getType().getFieldCount()) {
                      typeBuilder.add(v.getType().getFieldList().get(pair.source));
                    }
                  }
                  final RexNode newV =
                          rexBuilder.makeCorrel(typeBuilder.build(), v.id);
                  if (old != new_) {
                    return rexBuilder.makeFieldAccess(newV, new_);
                  }
                }
                return fieldAccess;
              }
            });
  }
  return new TrimResult(r, mapping);
}
 
Example #21
Source File: RelBuilderTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** Tests filter builder with correlation variables */
@Test void testFilterWithCorrelationVariables() {
  final RelBuilder builder = RelBuilder.create(config().build());
  final Holder<RexCorrelVariable> v = Holder.of(null);
  RelNode root = builder.scan("EMP")
      .variable(v)
      .scan("DEPT")
      .filter(Collections.singletonList(v.get().id),
          builder.call(SqlStdOperatorTable.OR,
              builder.call(SqlStdOperatorTable.AND,
                  builder.call(SqlStdOperatorTable.LESS_THAN,
                      builder.field(v.get(), "DEPTNO"),
                      builder.literal(30)),
                  builder.call(SqlStdOperatorTable.GREATER_THAN,
                      builder.field(v.get(), "DEPTNO"),
                      builder.literal(20))),
              builder.isNull(builder.field(2))))
      .join(JoinRelType.LEFT,
          builder.equals(builder.field(2, 0, "SAL"),
              builder.literal(1000)),
          ImmutableSet.of(v.get().id))
      .build();

  final String expected = ""
      + "LogicalCorrelate(correlation=[$cor0], joinType=[left], requiredColumns=[{7}])\n"
      + "  LogicalTableScan(table=[[scott, EMP]])\n"
      + "  LogicalFilter(condition=[=($cor0.SAL, 1000)])\n"
      + "    LogicalFilter(condition=[OR(AND(<($cor0.DEPTNO, 30), >($cor0.DEPTNO, 20)), "
      + "IS NULL($2))], variablesSet=[[$cor0]])\n"
      + "      LogicalTableScan(table=[[scott, DEPT]])\n";

  assertThat(root, hasTree(expected));
}
 
Example #22
Source File: ProjectCorrelateTransposeRule.java    From calcite with Apache License 2.0 5 votes vote down vote up
public RexFieldAccessReplacer(
    CorrelationId rexCorrelVariableToReplace,
    RexCorrelVariable rexCorrelVariable,
    RexBuilder builder,
    Map<Integer, Integer> requiredColsMap) {
  this.rexCorrelVariableToReplace = rexCorrelVariableToReplace;
  this.rexCorrelVariable = rexCorrelVariable;
  this.builder = builder;
  this.requiredColsMap = requiredColsMap;
}
 
Example #23
Source File: LateralUnnestRowIDVisitor.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override
public Prel visitLateral(LateralJoinPrel prel, Boolean isRightOfLateral) throws RuntimeException {
  List<RelNode> children = Lists.newArrayList();
  children.add(((Prel) prel.getInput(0)).accept(this, isRightOfLateral));
  children.add(((Prel) prel.getInput(1)).accept(this, true));

  if (!isRightOfLateral) {
    return (Prel) prel.copy(prel.getTraitSet(), children);
  } else {
    //Adjust the column numbering due to an additional column "$drill_implicit_field$" is added to the inputs.
    Map<Integer, Integer> requiredColsMap = new HashMap<>();
    for (Integer corrColIndex : prel.getRequiredColumns()) {
      requiredColsMap.put(corrColIndex, corrColIndex + 1);
    }
    ImmutableBitSet requiredColumns = prel.getRequiredColumns().shift(1);

    CorrelationId corrId = prel.getCluster().createCorrel();
    RexCorrelVariable updatedCorrel =
            (RexCorrelVariable) prel.getCluster().getRexBuilder().makeCorrel(
                    children.get(0).getRowType(),
                    corrId);
    RelNode rightChild = children.get(1).accept(
            new CorrelateVarReplacer(
                    new ProjectCorrelateTransposeRule.RexFieldAccessReplacer(prel.getCorrelationId(),
                            updatedCorrel, prel.getCluster().getRexBuilder(), requiredColsMap)));
    return (Prel) prel.copy(prel.getTraitSet(), children.get(0), rightChild,
            corrId, requiredColumns, prel.getJoinType());
  }
}
 
Example #24
Source File: SubQueryDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * check whether the project has correlation expressions.
 * e.g. SELECT * FROM l WHERE a IN (SELECT l.b FROM r)
 */
private void checkCorCondition(final LogicalProject project) {
	if (!hasUnsupportedCorCondition) {
		for (RexNode node : project.getProjects()) {
			node.accept(new RexVisitorImpl<Void>(true) {
				@Override
				public Void visitCorrelVariable(RexCorrelVariable correlVariable) {
					hasUnsupportedCorCondition = true;
					return super.visitCorrelVariable(correlVariable);
				}
			});
		}
	}
}
 
Example #25
Source File: RelDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
private RexVisitorImpl<Void> rexVisitor(final RelNode rel) {
  return new RexVisitorImpl<Void>(true) {
    @Override public Void visitFieldAccess(RexFieldAccess fieldAccess) {
      final RexNode ref = fieldAccess.getReferenceExpr();
      if (ref instanceof RexCorrelVariable) {
        final RexCorrelVariable var = (RexCorrelVariable) ref;
        if (mapFieldAccessToCorVar.containsKey(fieldAccess)) {
          // for cases where different Rel nodes are referring to
          // same correlation var (e.g. in case of NOT IN)
          // avoid generating another correlation var
          // and record the 'rel' is using the same correlation
          mapRefRelToCorRef.put(rel,
              mapFieldAccessToCorVar.get(fieldAccess));
        } else {
          final CorRef correlation =
              new CorRef(var.id, fieldAccess.getField().getIndex(),
                  corrIdGenerator++);
          mapFieldAccessToCorVar.put(fieldAccess, correlation);
          mapRefRelToCorRef.put(rel, correlation);
        }
      }
      return super.visitFieldAccess(fieldAccess);
    }

    @Override public Void visitSubQuery(RexSubQuery subQuery) {
      subQuery.rel.accept(CorelMapBuilder.this);
      return super.visitSubQuery(subQuery);
    }
  };
}
 
Example #26
Source File: SubQueryDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * check whether the predicate on join has unsupported correlation condition.
 * e.g. SELECT * FROM l WHERE a IN (SELECT c FROM r WHERE l.b IN (SELECT e FROM t))
 */
private void checkCorCondition(final LogicalJoin join) {
	if (!hasUnsupportedCorCondition) {
		join.getCondition().accept(new RexVisitorImpl<Void>(true) {
			@Override
			public Void visitCorrelVariable(RexCorrelVariable correlVariable) {
				hasUnsupportedCorCondition = true;
				return super.visitCorrelVariable(correlVariable);
			}
		});
	}
}
 
Example #27
Source File: SubQueryDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * check whether the project has correlation expressions.
 * e.g. SELECT * FROM l WHERE a IN (SELECT l.b FROM r)
 */
private void checkCorCondition(final LogicalProject project) {
	if (!hasUnsupportedCorCondition) {
		for (RexNode node : project.getProjects()) {
			node.accept(new RexVisitorImpl<Void>(true) {
				@Override
				public Void visitCorrelVariable(RexCorrelVariable correlVariable) {
					hasUnsupportedCorCondition = true;
					return super.visitCorrelVariable(correlVariable);
				}
			});
		}
	}
}
 
Example #28
Source File: SubQueryDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * check whether a node has some input which have correlation condition.
 * e.g. SELECT * FROM l WHERE EXISTS (SELECT * FROM r LEFT JOIN (SELECT * FROM t WHERE t.j=l.b) t1 ON r.f=t1.k)
 * the above sql can not be converted to semi-join plan,
 * because the right input of Left-Join has the correlation condition(t.j=l.b).
 */
private void checkCorConditionOfInput(final RelNode input) {
	final RelShuttleImpl shuttle = new RelShuttleImpl() {
		final RexVisitor<Void> visitor = new RexVisitorImpl<Void>(true) {
			@Override
			public Void visitCorrelVariable(RexCorrelVariable correlVariable) {
				hasUnsupportedCorCondition = true;
				return super.visitCorrelVariable(correlVariable);
			}
		};

		@Override
		public RelNode visit(LogicalFilter filter) {
			filter.getCondition().accept(visitor);
			return super.visit(filter);
		}

		@Override
		public RelNode visit(LogicalProject project) {
			for (RexNode rex : project.getProjects()) {
				rex.accept(visitor);
			}
			return super.visit(project);
		}

		@Override
		public RelNode visit(LogicalJoin join) {
			join.getCondition().accept(visitor);
			return super.visit(join);
		}
	};
	input.accept(shuttle);
}
 
Example #29
Source File: SubQueryDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * check whether the predicate on join has unsupported correlation condition.
 * e.g. SELECT * FROM l WHERE a IN (SELECT c FROM r WHERE l.b IN (SELECT e FROM t))
 */
private void checkCorCondition(final LogicalJoin join) {
	if (!hasUnsupportedCorCondition) {
		join.getCondition().accept(new RexVisitorImpl<Void>(true) {
			@Override
			public Void visitCorrelVariable(RexCorrelVariable correlVariable) {
				hasUnsupportedCorCondition = true;
				return super.visitCorrelVariable(correlVariable);
			}
		});
	}
}
 
Example #30
Source File: SubQueryDecorrelator.java    From flink with Apache License 2.0 5 votes vote down vote up
/**
 * check whether a node has some input which have correlation condition.
 * e.g. SELECT * FROM l WHERE EXISTS (SELECT * FROM r LEFT JOIN (SELECT * FROM t WHERE t.j=l.b) t1 ON r.f=t1.k)
 * the above sql can not be converted to semi-join plan,
 * because the right input of Left-Join has the correlation condition(t.j=l.b).
 */
private void checkCorConditionOfInput(final RelNode input) {
	final RelShuttleImpl shuttle = new RelShuttleImpl() {
		final RexVisitor<Void> visitor = new RexVisitorImpl<Void>(true) {
			@Override
			public Void visitCorrelVariable(RexCorrelVariable correlVariable) {
				hasUnsupportedCorCondition = true;
				return super.visitCorrelVariable(correlVariable);
			}
		};

		@Override
		public RelNode visit(LogicalFilter filter) {
			filter.getCondition().accept(visitor);
			return super.visit(filter);
		}

		@Override
		public RelNode visit(LogicalProject project) {
			for (RexNode rex : project.getProjects()) {
				rex.accept(visitor);
			}
			return super.visit(project);
		}

		@Override
		public RelNode visit(LogicalJoin join) {
			join.getCondition().accept(visitor);
			return super.visit(join);
		}
	};
	input.accept(shuttle);
}