use of org.apache.calcite.linq4j.tree.MethodCallExpression in project calcite by apache.
the class EnumerableRelImplementor method classDecl.
private ClassDeclaration classDecl(JavaTypeFactoryImpl.SyntheticRecordType type) {
ClassDeclaration classDeclaration = Expressions.classDecl(Modifier.PUBLIC | Modifier.STATIC, type.getName(), null, ImmutableList.<Type>of(Serializable.class), new ArrayList<MemberDeclaration>());
// ...
for (Types.RecordField field : type.getRecordFields()) {
classDeclaration.memberDeclarations.add(Expressions.fieldDecl(field.getModifiers(), Expressions.parameter(field.getType(), field.getName()), null));
}
// Constructor:
// Foo(T0 f0, ...) { this.f0 = f0; ... }
final BlockBuilder blockBuilder = new BlockBuilder();
final List<ParameterExpression> parameters = new ArrayList<>();
final ParameterExpression thisParameter = Expressions.parameter(type, "this");
// Here a constructor without parameter is used because the generated
// code could cause error if number of fields is too large.
classDeclaration.memberDeclarations.add(Expressions.constructorDecl(Modifier.PUBLIC, type, parameters, blockBuilder.toBlock()));
// equals method():
// public boolean equals(Object o) {
// if (this == o) return true;
// if (!(o instanceof MyClass)) return false;
// final MyClass that = (MyClass) o;
// return this.f0 == that.f0
// && equal(this.f1, that.f1)
// ...
// }
final BlockBuilder blockBuilder2 = new BlockBuilder();
final ParameterExpression thatParameter = Expressions.parameter(type, "that");
final ParameterExpression oParameter = Expressions.parameter(Object.class, "o");
blockBuilder2.add(Expressions.ifThen(Expressions.equal(thisParameter, oParameter), Expressions.return_(null, Expressions.constant(true))));
blockBuilder2.add(Expressions.ifThen(Expressions.not(Expressions.typeIs(oParameter, type)), Expressions.return_(null, Expressions.constant(false))));
blockBuilder2.add(Expressions.declare(Modifier.FINAL, thatParameter, Expressions.convert_(oParameter, type)));
final List<Expression> conditions = new ArrayList<>();
for (Types.RecordField field : type.getRecordFields()) {
conditions.add(Primitive.is(field.getType()) ? Expressions.equal(Expressions.field(thisParameter, field.getName()), Expressions.field(thatParameter, field.getName())) : Expressions.call(BuiltInMethod.OBJECTS_EQUAL.method, Expressions.field(thisParameter, field.getName()), Expressions.field(thatParameter, field.getName())));
}
blockBuilder2.add(Expressions.return_(null, Expressions.foldAnd(conditions)));
classDeclaration.memberDeclarations.add(Expressions.methodDecl(Modifier.PUBLIC, boolean.class, "equals", Collections.singletonList(oParameter), blockBuilder2.toBlock()));
// hashCode method:
// public int hashCode() {
// int h = 0;
// h = hash(h, f0);
// ...
// return h;
// }
final BlockBuilder blockBuilder3 = new BlockBuilder();
final ParameterExpression hParameter = Expressions.parameter(int.class, "h");
final ConstantExpression constantZero = Expressions.constant(0);
blockBuilder3.add(Expressions.declare(0, hParameter, constantZero));
for (Types.RecordField field : type.getRecordFields()) {
final Method method = BuiltInMethod.HASH.method;
blockBuilder3.add(Expressions.statement(Expressions.assign(hParameter, Expressions.call(method.getDeclaringClass(), method.getName(), ImmutableList.of(hParameter, Expressions.field(thisParameter, field))))));
}
blockBuilder3.add(Expressions.return_(null, hParameter));
classDeclaration.memberDeclarations.add(Expressions.methodDecl(Modifier.PUBLIC, int.class, "hashCode", Collections.<ParameterExpression>emptyList(), blockBuilder3.toBlock()));
// compareTo method:
// public int compareTo(MyClass that) {
// int c;
// c = compare(this.f0, that.f0);
// if (c != 0) return c;
// ...
// return 0;
// }
final BlockBuilder blockBuilder4 = new BlockBuilder();
final ParameterExpression cParameter = Expressions.parameter(int.class, "c");
final int mod = type.getRecordFields().size() == 1 ? Modifier.FINAL : 0;
blockBuilder4.add(Expressions.declare(mod, cParameter, null));
final ConditionalStatement conditionalStatement = Expressions.ifThen(Expressions.notEqual(cParameter, constantZero), Expressions.return_(null, cParameter));
for (Types.RecordField field : type.getRecordFields()) {
MethodCallExpression compareCall;
try {
final Method method = (field.nullable() ? BuiltInMethod.COMPARE_NULLS_LAST : BuiltInMethod.COMPARE).method;
compareCall = Expressions.call(method.getDeclaringClass(), method.getName(), Expressions.field(thisParameter, field), Expressions.field(thatParameter, field));
} catch (RuntimeException e) {
if (e.getCause() instanceof NoSuchMethodException) {
// In those cases it is fine if we skip the problematic fields.
continue;
}
throw e;
}
blockBuilder4.add(Expressions.statement(Expressions.assign(cParameter, compareCall)));
blockBuilder4.add(conditionalStatement);
}
blockBuilder4.add(Expressions.return_(null, constantZero));
classDeclaration.memberDeclarations.add(Expressions.methodDecl(Modifier.PUBLIC, int.class, "compareTo", Collections.singletonList(thatParameter), blockBuilder4.toBlock()));
// toString method:
// public String toString() {
// return "{f0=" + f0
// + ", f1=" + f1
// ...
// + "}";
// }
final BlockBuilder blockBuilder5 = new BlockBuilder();
Expression expression5 = null;
for (Types.RecordField field : type.getRecordFields()) {
if (expression5 == null) {
expression5 = Expressions.constant("{" + field.getName() + "=");
} else {
expression5 = Expressions.add(expression5, Expressions.constant(", " + field.getName() + "="));
}
expression5 = Expressions.add(expression5, Expressions.field(thisParameter, field.getName()));
}
expression5 = expression5 == null ? Expressions.constant("{}") : Expressions.add(expression5, Expressions.constant("}"));
blockBuilder5.add(Expressions.return_(null, expression5));
classDeclaration.memberDeclarations.add(Expressions.methodDecl(Modifier.PUBLIC, String.class, "toString", Collections.<ParameterExpression>emptyList(), blockBuilder5.toBlock()));
return classDeclaration;
}
use of org.apache.calcite.linq4j.tree.MethodCallExpression in project calcite by apache.
the class EnumerableTableScan method fieldExpression.
private Expression fieldExpression(ParameterExpression row_, int i, PhysType physType, JavaRowFormat format) {
final Expression e = format.field(row_, i, null, physType.getJavaFieldType(i));
final RelDataType relFieldType = physType.getRowType().getFieldList().get(i).getType();
switch(relFieldType.getSqlTypeName()) {
case ARRAY:
case MULTISET:
// We can't represent a multiset or array as a List<Employee>, because
// the consumer does not know the element type.
// The standard element type is List.
// We need to convert to a List<List>.
final JavaTypeFactory typeFactory = (JavaTypeFactory) getCluster().getTypeFactory();
final PhysType elementPhysType = PhysTypeImpl.of(typeFactory, relFieldType.getComponentType(), JavaRowFormat.CUSTOM);
final MethodCallExpression e2 = Expressions.call(BuiltInMethod.AS_ENUMERABLE2.method, e);
final RelDataType dummyType = this.rowType;
final Expression e3 = elementPhysType.convertTo(e2, PhysTypeImpl.of(typeFactory, dummyType, JavaRowFormat.LIST));
return Expressions.call(e3, BuiltInMethod.ENUMERABLE_TO_LIST.method);
default:
return e;
}
}
use of org.apache.calcite.linq4j.tree.MethodCallExpression in project calcite by apache.
the class LixToRelTranslator method translate.
public RelNode translate(Expression expression) {
if (expression instanceof MethodCallExpression) {
final MethodCallExpression call = (MethodCallExpression) expression;
BuiltInMethod method = BuiltInMethod.MAP.get(call.method);
if (method == null) {
throw new UnsupportedOperationException("unknown method " + call.method);
}
RelNode input;
switch(method) {
case SELECT:
input = translate(call.targetExpression);
return LogicalProject.create(input, toRex(input, (FunctionExpression) call.expressions.get(0)), (List<String>) null);
case WHERE:
input = translate(call.targetExpression);
return LogicalFilter.create(input, toRex((FunctionExpression) call.expressions.get(0), input));
case AS_QUERYABLE:
return LogicalTableScan.create(cluster, RelOptTableImpl.create(null, typeFactory.createJavaType(Types.toClass(Types.getElementType(call.targetExpression.getType()))), ImmutableList.<String>of(), call.targetExpression));
case SCHEMA_GET_TABLE:
return LogicalTableScan.create(cluster, RelOptTableImpl.create(null, typeFactory.createJavaType((Class) ((ConstantExpression) call.expressions.get(1)).value), ImmutableList.<String>of(), call.targetExpression));
default:
throw new UnsupportedOperationException("unknown method " + call.method);
}
}
throw new UnsupportedOperationException("unknown expression type " + expression.getNodeType());
}
use of org.apache.calcite.linq4j.tree.MethodCallExpression in project calcite by apache.
the class ExpressionTest method testCompile.
@Test
public void testCompile() throws NoSuchMethodException {
// Creating a parameter for the expression tree.
ParameterExpression param = Expressions.parameter(String.class);
// Creating an expression for the method call and specifying its
// parameter.
MethodCallExpression methodCall = Expressions.call(Integer.class, "valueOf", Collections.<Expression>singletonList(param));
// The following statement first creates an expression tree,
// then compiles it, and then runs it.
int x = Expressions.<Function1<String, Integer>>lambda(methodCall, new ParameterExpression[] { param }).getFunction().apply("1234");
assertEquals(1234, x);
}
Aggregations