use of org.apache.calcite.rex.RexCall in project flink by apache.
the class FlinkRelMdCollation method project.
/**
* Helper method to determine a {@link Project}'s collation.
*/
public static List<RelCollation> project(RelMetadataQuery mq, RelNode input, List<? extends RexNode> projects) {
final SortedSet<RelCollation> collations = new TreeSet<>();
final List<RelCollation> inputCollations = mq.collations(input);
if (inputCollations == null || inputCollations.isEmpty()) {
return com.google.common.collect.ImmutableList.of();
}
final com.google.common.collect.Multimap<Integer, Integer> targets = com.google.common.collect.LinkedListMultimap.create();
final Map<Integer, SqlMonotonicity> targetsWithMonotonicity = new HashMap<>();
for (Ord<RexNode> project : Ord.<RexNode>zip(projects)) {
if (project.e instanceof RexInputRef) {
targets.put(((RexInputRef) project.e).getIndex(), project.i);
} else if (project.e instanceof RexCall) {
final RexCall call = (RexCall) project.e;
final RexCallBinding binding = RexCallBinding.create(input.getCluster().getTypeFactory(), call, inputCollations);
targetsWithMonotonicity.put(project.i, call.getOperator().getMonotonicity(binding));
}
}
final List<RelFieldCollation> fieldCollations = new ArrayList<>();
loop: for (RelCollation ic : inputCollations) {
if (ic.getFieldCollations().isEmpty()) {
continue;
}
fieldCollations.clear();
for (RelFieldCollation ifc : ic.getFieldCollations()) {
final Collection<Integer> integers = targets.get(ifc.getFieldIndex());
if (integers.isEmpty()) {
// cannot do this collation
continue loop;
}
fieldCollations.add(ifc.withFieldIndex(integers.iterator().next()));
}
assert !fieldCollations.isEmpty();
collations.add(RelCollations.of(fieldCollations));
}
final List<RelFieldCollation> fieldCollationsForRexCalls = new ArrayList<>();
for (Map.Entry<Integer, SqlMonotonicity> entry : targetsWithMonotonicity.entrySet()) {
final SqlMonotonicity value = entry.getValue();
switch(value) {
case NOT_MONOTONIC:
case CONSTANT:
break;
default:
fieldCollationsForRexCalls.add(new RelFieldCollation(entry.getKey(), RelFieldCollation.Direction.of(value)));
break;
}
}
if (!fieldCollationsForRexCalls.isEmpty()) {
collations.add(RelCollations.of(fieldCollationsForRexCalls));
}
return com.google.common.collect.ImmutableList.copyOf(collations);
}
use of org.apache.calcite.rex.RexCall in project flink by apache.
the class PythonCorrelateSplitRule method matches.
@Override
public boolean matches(RelOptRuleCall call) {
FlinkLogicalCorrelate correlate = call.rel(0);
RelNode right = ((HepRelVertex) correlate.getRight()).getCurrentRel();
FlinkLogicalTableFunctionScan tableFunctionScan;
if (right instanceof FlinkLogicalTableFunctionScan) {
tableFunctionScan = (FlinkLogicalTableFunctionScan) right;
} else if (right instanceof FlinkLogicalCalc) {
tableFunctionScan = StreamPhysicalCorrelateRule.getTableScan((FlinkLogicalCalc) right);
} else {
return false;
}
RexNode rexNode = tableFunctionScan.getCall();
if (rexNode instanceof RexCall) {
return PythonUtil.isPythonCall(rexNode, null) && PythonUtil.containsNonPythonCall(rexNode) || PythonUtil.isNonPythonCall(rexNode) && PythonUtil.containsPythonCall(rexNode, null) || (PythonUtil.isPythonCall(rexNode, null) && RexUtil.containsFieldAccess(rexNode));
}
return false;
}
use of org.apache.calcite.rex.RexCall 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.RexCall in project flink by apache.
the class RexNodeJsonSerializer method serialize.
@Override
public void serialize(RexNode rexNode, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
final ReadableConfig config = SerdeContext.get(serializerProvider).getConfiguration();
final CatalogPlanCompilation compilationStrategy = config.get(TableConfigOptions.PLAN_COMPILE_CATALOG_OBJECTS);
switch(rexNode.getKind()) {
case INPUT_REF:
case TABLE_INPUT_REF:
serializeInputRef((RexInputRef) rexNode, jsonGenerator, serializerProvider);
break;
case LITERAL:
serializeLiteral((RexLiteral) rexNode, jsonGenerator, serializerProvider);
break;
case FIELD_ACCESS:
serializeFieldAccess((RexFieldAccess) rexNode, jsonGenerator, serializerProvider);
break;
case CORREL_VARIABLE:
serializeCorrelVariable((RexCorrelVariable) rexNode, jsonGenerator, serializerProvider);
break;
case PATTERN_INPUT_REF:
serializePatternFieldRef((RexPatternFieldRef) rexNode, jsonGenerator, serializerProvider);
break;
default:
if (rexNode instanceof RexCall) {
serializeCall((RexCall) rexNode, jsonGenerator, serializerProvider, compilationStrategy);
} else {
throw new TableException("Unknown RexNode: " + rexNode);
}
}
}
use of org.apache.calcite.rex.RexCall in project beam by apache.
the class TVFScanConverter method convert.
@Override
public RelNode convert(ResolvedTVFScan zetaNode, List<RelNode> inputs) {
RelNode input = inputs.get(0);
RexCall call = getExpressionConverter().convertTableValuedFunction(input, zetaNode.getTvf(), zetaNode.getArgumentList(), zetaNode.getArgumentList().size() > 0 && zetaNode.getArgumentList().get(0).getScan() != null ? zetaNode.getArgumentList().get(0).getScan().getColumnList() : Collections.emptyList());
RelNode tableFunctionScan = LogicalTableFunctionScan.create(getCluster(), inputs, call, null, call.getType(), Collections.EMPTY_SET);
// Pure SQL UDF's language body is built bottom up, so FunctionArgumentRefMapping should be
// already consumed thus it can be cleared now.
context.clearFunctionArgumentRefMapping();
return tableFunctionScan;
}
Aggregations