use of org.apache.calcite.rex.RexSubQuery in project flink by apache.
the class HiveParserUtils method rexSubQueryIn.
/**
* Proxy to {@link RexSubQuery#in(RelNode, com.google.common.collect.ImmutableList)}.
*/
public static RexSubQuery rexSubQueryIn(RelNode relNode, Collection<RexNode> rexNodes) {
Class[] argTypes = new Class[] { RelNode.class, null };
argTypes[1] = useShadedImmutableList ? shadedImmutableListClz : immutableListClz;
Method method = HiveReflectionUtils.tryGetMethod(RexSubQuery.class, "in", argTypes);
Preconditions.checkState(method != null, "Cannot get the method to create an IN sub-query");
try {
return (RexSubQuery) method.invoke(null, relNode, toImmutableList(rexNodes));
} catch (IllegalAccessException | InvocationTargetException e) {
throw new FlinkHiveException("Failed to create RexSubQuery", e);
}
}
use of org.apache.calcite.rex.RexSubQuery in project flink by apache.
the class SubQueryDecorrelator method analyzeCorConditions.
private static void analyzeCorConditions(final Set<CorrelationId> variableSet, final RexNode condition, final RexBuilder rexBuilder, final int maxCnfNodeCount, final List<RexNode> corConditions, final List<RexNode> nonCorConditions, final List<RexNode> unsupportedCorConditions) {
// converts the expanded expression to conjunctive normal form,
// like "(a AND b) OR c" will be converted to "(a OR c) AND (b OR c)"
final RexNode cnf = FlinkRexUtil.toCnf(rexBuilder, maxCnfNodeCount, condition);
// converts the cnf condition to a list of AND conditions
final List<RexNode> conjunctions = RelOptUtil.conjunctions(cnf);
// `true` for RexNode is supported correlation condition,
// `false` for RexNode is unsupported correlation condition,
// `null` for RexNode is not a correlation condition.
final RexVisitorImpl<Boolean> visitor = new RexVisitorImpl<Boolean>(true) {
@Override
public Boolean visitFieldAccess(RexFieldAccess fieldAccess) {
final RexNode ref = fieldAccess.getReferenceExpr();
if (ref instanceof RexCorrelVariable) {
return visitCorrelVariable((RexCorrelVariable) ref);
} else {
return super.visitFieldAccess(fieldAccess);
}
}
@Override
public Boolean visitCorrelVariable(RexCorrelVariable correlVariable) {
return variableSet.contains(correlVariable.id);
}
@Override
public Boolean visitSubQuery(RexSubQuery subQuery) {
final List<Boolean> result = new ArrayList<>();
for (RexNode operand : subQuery.operands) {
result.add(operand.accept(this));
}
// in (select t3.d from t3)
if (result.contains(true) || result.contains(false)) {
return false;
} else {
return null;
}
}
@Override
public Boolean visitCall(RexCall call) {
final List<Boolean> result = new ArrayList<>();
for (RexNode operand : call.operands) {
result.add(operand.accept(this));
}
if (result.contains(false)) {
return false;
} else if (result.contains(true)) {
// return call.op.getKind() != SqlKind.OR || !result.contains(null);
return call.op.getKind() != SqlKind.OR;
} else {
return null;
}
}
};
for (RexNode c : conjunctions) {
Boolean r = c.accept(visitor);
if (r == null) {
nonCorConditions.add(c);
} else if (r) {
corConditions.add(c);
} else {
unsupportedCorConditions.add(c);
}
}
}
use of org.apache.calcite.rex.RexSubQuery in project hive by apache.
the class HiveSubQueryRemoveRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final RelNode relNode = call.rel(0);
final RelBuilder builder = call.builder();
// if subquery is in FILTER
if (relNode instanceof HiveFilter) {
final HiveFilter filter = call.rel(0);
final RexSubQuery e = RexUtil.SubQueryFinder.find(filter.getCondition());
assert e != null;
final RelOptUtil.Logic logic = LogicVisitor.find(RelOptUtil.Logic.TRUE, ImmutableList.of(filter.getCondition()), e);
builder.push(filter.getInput());
final int fieldCount = builder.peek().getRowType().getFieldCount();
SubqueryConf subqueryConfig = filter.getCluster().getPlanner().getContext().unwrap(SubqueryConf.class);
boolean isCorrScalarQuery = subqueryConfig.getCorrScalarRexSQWithAgg().contains(e.rel);
final RexNode target = apply(call.getMetadataQuery(), e, HiveFilter.getVariablesSet(e), logic, builder, 1, fieldCount, isCorrScalarQuery);
final RexShuttle shuttle = new ReplaceSubQueryShuttle(e, target);
builder.filter(shuttle.apply(filter.getCondition()));
builder.project(fields(builder, filter.getRowType().getFieldCount()));
RelNode newRel = builder.build();
call.transformTo(newRel);
} else if (relNode instanceof HiveProject) {
// if subquery is in PROJECT
final HiveProject project = call.rel(0);
final RexSubQuery e = RexUtil.SubQueryFinder.find(project.getProjects());
assert e != null;
final RelOptUtil.Logic logic = LogicVisitor.find(RelOptUtil.Logic.TRUE_FALSE_UNKNOWN, project.getProjects(), e);
builder.push(project.getInput());
final int fieldCount = builder.peek().getRowType().getFieldCount();
SubqueryConf subqueryConfig = project.getCluster().getPlanner().getContext().unwrap(SubqueryConf.class);
boolean isCorrScalarQuery = subqueryConfig.getCorrScalarRexSQWithAgg().contains(e.rel);
final RexNode target = apply(call.getMetadataQuery(), e, HiveFilter.getVariablesSet(e), logic, builder, 1, fieldCount, isCorrScalarQuery);
final RexShuttle shuttle = new ReplaceSubQueryShuttle(e, target);
builder.project(shuttle.apply(project.getProjects()), project.getRowType().getFieldNames());
call.transformTo(builder.build());
}
}
use of org.apache.calcite.rex.RexSubQuery in project hive by apache.
the class HiveFilter method traverseFilter.
// traverse the given node to find all correlated variables
// Note that correlated variables are supported in Filter only i.e. Where & Having
private static void traverseFilter(RexNode node, Set<CorrelationId> allVars) {
if (node instanceof RexSubQuery) {
RexSubQuery rexSubQuery = (RexSubQuery) node;
// Also check for case where operator has 0 inputs .e.g TableScan
if (rexSubQuery.rel.getInputs().isEmpty()) {
return;
}
RelNode input = rexSubQuery.rel.getInput(0);
while (input != null && !(input instanceof HiveFilter) && input.getInputs().size() >= 1) {
// we don't expect corr vars within UNION for now
if (input.getInputs().size() > 1) {
if (input instanceof HiveJoin) {
findCorrelatedVar(((HiveJoin) input).getJoinFilter(), allVars);
}
return;
}
input = input.getInput(0);
}
if (input != null && input instanceof HiveFilter) {
findCorrelatedVar(((HiveFilter) input).getCondition(), allVars);
}
return;
}
// AND, NOT etc
if (node instanceof RexCall) {
int numOperands = ((RexCall) node).getOperands().size();
for (int i = 0; i < numOperands; i++) {
RexNode op = ((RexCall) node).getOperands().get(i);
traverseFilter(op, allVars);
}
}
}
use of org.apache.calcite.rex.RexSubQuery in project hazelcast by hazelcast.
the class QueryConverter method hasNestedExists.
private static boolean hasNestedExists(RelNode root) {
class NestedExistsFinder extends RelVisitor {
private boolean found;
private int depth;
@Override
public void visit(RelNode node, int ordinal, @Nullable RelNode parent) {
if (node instanceof LogicalFilter) {
RexSubQuery exists = getExists((LogicalFilter) node);
if (exists != null) {
found |= depth > 0;
depth++;
go(exists.rel);
depth--;
}
}
super.visit(node, ordinal, parent);
}
private boolean find() {
go(root);
return found;
}
private RexSubQuery getExists(LogicalFilter filter) {
RexSubQuery[] existsSubQuery = { null };
filter.getCondition().accept(new RexVisitorImpl<Void>(true) {
@Override
public Void visitSubQuery(RexSubQuery subQuery) {
if (subQuery.getKind() == SqlKind.EXISTS) {
existsSubQuery[0] = subQuery;
}
return super.visitSubQuery(subQuery);
}
});
return existsSubQuery[0];
}
}
return new NestedExistsFinder().find();
}
Aggregations