use of org.apache.calcite.rex.RexCorrelVariable in project hive by apache.
the class RelFieldTrimmer method result.
protected TrimResult result(RelNode r, final Mapping mapping) {
final RelBuilder relBuilder = REL_BUILDER.get();
final RexBuilder rexBuilder = relBuilder.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) && 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.id);
if (old != new_) {
return rexBuilder.makeFieldAccess(newV, new_);
}
}
return fieldAccess;
}
});
}
return new TrimResult(r, mapping);
}
use of org.apache.calcite.rex.RexCorrelVariable in project herddb by diennea.
the class SQLExpressionCompiler method compileExpression.
public static CompiledSQLExpression compileExpression(RexNode expression) {
if (expression == null) {
return null;
}
if (expression instanceof RexDynamicParam) {
RexDynamicParam p = (RexDynamicParam) expression;
return new TypedJdbcParameterExpression(p.getIndex(), CalcitePlanner.convertToHerdType(p.getType()));
} else if (expression instanceof RexLiteral) {
RexLiteral p = (RexLiteral) expression;
if (p.isNull()) {
return new ConstantExpression(null);
} else {
return new ConstantExpression(safeValue(p.getValue3(), p.getTypeName()));
}
} else if (expression instanceof RexInputRef) {
RexInputRef p = (RexInputRef) expression;
return new AccessCurrentRowExpression(p.getIndex());
} else if (expression instanceof RexCall) {
RexCall p = (RexCall) expression;
SqlOperator op = p.op;
String name = op.getName();
CompiledSQLExpression[] operands = new CompiledSQLExpression[p.operands.size()];
// System.out.println("operator '" + op + "' with " + p.operands.size() + " ops");
int i = 0;
for (RexNode operand : p.operands) {
// System.out.println("operand: " + operand);
operands[i++] = compileExpression(operand);
}
switch(name) {
case "=":
return new CompiledEqualsExpression(false, operands[0], operands[1]);
case "<>":
return new CompiledNotEqualsExpression(false, operands[0], operands[1]);
case ">":
return new CompiledGreaterThenExpression(false, operands[0], operands[1]);
case ">=":
return new CompiledGreaterThenEqualsExpression(false, operands[0], operands[1]);
case "<":
return new CompiledMinorThenExpression(false, operands[0], operands[1]);
case "<=":
return new CompiledMinorThenEqualsExpression(false, operands[0], operands[1]);
case "+":
return new CompiledAddExpression(false, operands[0], operands[1]);
case "-":
if (operands.length == 1) {
return new CompiledSignedExpression('-', operands[0]);
} else if (operands.length == 2) {
return new CompiledSubtractExpression(false, operands[0], operands[1]);
}
break;
case "*":
return new CompiledMultiplyExpression(false, operands[0], operands[1]);
case "/":
return new CompiledDivideExpression(false, operands[0], operands[1]);
case "LIKE":
return new CompiledLikeExpression(false, operands[0], operands[1]);
case "AND":
return new CompiledMultiAndExpression(operands);
case "OR":
return new CompiledMultiOrExpression(operands);
case "NOT":
return new CompiledParenthesisExpression(true, operands[0]);
case "IS NOT NULL":
return new CompiledIsNullExpression(true, operands[0]);
case "IS NOT TRUE":
return new CompiledIsNotTrueExpression(false, operands[0]);
case "IS NULL":
return new CompiledIsNullExpression(false, operands[0]);
case "CAST":
return operands[0].cast(CalcitePlanner.convertToHerdType(p.type));
case "CASE":
List<Map.Entry<CompiledSQLExpression, CompiledSQLExpression>> cases = new ArrayList<>(operands.length / 2);
boolean hasElse = operands.length % 2 == 1;
int numcases = hasElse ? ((operands.length - 1) / 2) : (operands.length / 2);
for (int j = 0; j < numcases; j++) {
cases.add(new AbstractMap.SimpleImmutableEntry<>(operands[j * 2], operands[j * 2 + 1]));
}
CompiledSQLExpression elseExp = hasElse ? operands[operands.length - 1] : null;
return new CompiledCaseExpression(cases, elseExp);
case BuiltinFunctions.NAME_CURRENT_TIMESTAMP:
return new CompiledFunction(BuiltinFunctions.CURRENT_TIMESTAMP, Collections.emptyList());
case BuiltinFunctions.NAME_LOWERCASE:
return new CompiledFunction(BuiltinFunctions.LOWER, Arrays.asList(operands));
case BuiltinFunctions.NAME_UPPER:
return new CompiledFunction(BuiltinFunctions.UPPER, Arrays.asList(operands));
case BuiltinFunctions.NAME_ABS:
return new CompiledFunction(BuiltinFunctions.ABS, Arrays.asList(operands));
case BuiltinFunctions.NAME_ROUND:
return new CompiledFunction(BuiltinFunctions.ROUND, Arrays.asList(operands));
default:
throw new StatementExecutionException("unsupported operator '" + name + "'");
}
} else if (expression instanceof RexFieldAccess) {
RexFieldAccess p = (RexFieldAccess) expression;
CompiledSQLExpression object = compileExpression(p.getReferenceExpr());
return new AccessFieldExpression(object, p.getField().getName());
} else if (expression instanceof RexCorrelVariable) {
RexCorrelVariable p = (RexCorrelVariable) expression;
return new AccessCorrelVariableExpression(p.id.getId(), p.id.getName());
}
throw new StatementExecutionException("not implemented expression type " + expression.getClass() + ": " + expression);
}
use of org.apache.calcite.rex.RexCorrelVariable in project calcite by apache.
the class RelBuilderTest method testCorrelationFails.
@Test
public 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"));
}
}
use of org.apache.calcite.rex.RexCorrelVariable in project calcite by apache.
the class RelBuilderTest method testCorrelationWithCondition.
@Test
public 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));
}
use of org.apache.calcite.rex.RexCorrelVariable in project flink by apache.
the class PythonCorrelateSplitRule method createNewFieldNames.
private List<String> createNewFieldNames(RelDataType rowType, RexBuilder rexBuilder, int primitiveFieldCount, ArrayBuffer<RexNode> extractedRexNodes, List<RexNode> calcProjects) {
for (int i = 0; i < primitiveFieldCount; i++) {
calcProjects.add(RexInputRef.of(i, rowType));
}
// change RexCorrelVariable to RexInputRef.
RexDefaultVisitor<RexNode> visitor = new RexDefaultVisitor<RexNode>() {
@Override
public RexNode visitFieldAccess(RexFieldAccess fieldAccess) {
RexNode expr = fieldAccess.getReferenceExpr();
if (expr instanceof RexCorrelVariable) {
RelDataTypeField field = fieldAccess.getField();
return new RexInputRef(field.getIndex(), field.getType());
} else {
return rexBuilder.makeFieldAccess(expr.accept(this), fieldAccess.getField().getIndex());
}
}
@Override
public RexNode visitNode(RexNode rexNode) {
return rexNode;
}
};
// add the fields of the extracted rex calls.
Iterator<RexNode> iterator = extractedRexNodes.iterator();
while (iterator.hasNext()) {
RexNode rexNode = iterator.next();
if (rexNode instanceof RexCall) {
RexCall rexCall = (RexCall) rexNode;
List<RexNode> newProjects = rexCall.getOperands().stream().map(x -> x.accept(visitor)).collect(Collectors.toList());
RexCall newRexCall = rexCall.clone(rexCall.getType(), newProjects);
calcProjects.add(newRexCall);
} else {
calcProjects.add(rexNode);
}
}
List<String> nameList = new LinkedList<>();
for (int i = 0; i < primitiveFieldCount; i++) {
nameList.add(rowType.getFieldNames().get(i));
}
Iterator<Object> indicesIterator = extractedRexNodes.indices().iterator();
while (indicesIterator.hasNext()) {
nameList.add("f" + indicesIterator.next());
}
return SqlValidatorUtil.uniquify(nameList, rexBuilder.getTypeFactory().getTypeSystem().isSchemaCaseSensitive());
}
Aggregations