use of org.apache.calcite.linq4j.tree.ParameterExpression in project calcite by apache.
the class EnumerableTableScan method toRows.
private Expression toRows(PhysType physType, Expression expression) {
if (physType.getFormat() == JavaRowFormat.SCALAR && Object[].class.isAssignableFrom(elementType) && getRowType().getFieldCount() == 1 && (table.unwrap(ScannableTable.class) != null || table.unwrap(FilterableTable.class) != null || table.unwrap(ProjectableFilterableTable.class) != null)) {
return Expressions.call(BuiltInMethod.SLICE0.method, expression);
}
JavaRowFormat oldFormat = format();
if (physType.getFormat() == oldFormat && !hasCollectionField(rowType)) {
return expression;
}
final ParameterExpression row_ = Expressions.parameter(elementType, "row");
final int fieldCount = table.getRowType().getFieldCount();
List<Expression> expressionList = new ArrayList<>(fieldCount);
for (int i = 0; i < fieldCount; i++) {
expressionList.add(fieldExpression(row_, i, physType, oldFormat));
}
return Expressions.call(expression, BuiltInMethod.SELECT.method, Expressions.lambda(Function1.class, physType.record(expressionList), row_));
}
use of org.apache.calcite.linq4j.tree.ParameterExpression 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.ParameterExpression in project calcite by apache.
the class EnumUtils method joinSelector.
static Expression joinSelector(JoinRelType joinType, PhysType physType, List<PhysType> inputPhysTypes) {
// A parameter for each input.
final List<ParameterExpression> parameters = new ArrayList<>();
// Generate all fields.
final List<Expression> expressions = new ArrayList<>();
final int outputFieldCount = physType.getRowType().getFieldCount();
for (Ord<PhysType> ord : Ord.zip(inputPhysTypes)) {
final PhysType inputPhysType = ord.e.makeNullable(joinType.generatesNullsOn(ord.i));
// If input item is just a primitive, we do not generate specialized
// primitive apply override since it won't be called anyway
// Function<T> always operates on boxed arguments
final ParameterExpression parameter = Expressions.parameter(Primitive.box(inputPhysType.getJavaRowType()), EnumUtils.LEFT_RIGHT.get(ord.i));
parameters.add(parameter);
if (expressions.size() == outputFieldCount) {
// For instance, if semi-join needs to return just the left inputs
break;
}
final int fieldCount = inputPhysType.getRowType().getFieldCount();
for (int i = 0; i < fieldCount; i++) {
Expression expression = inputPhysType.fieldReference(parameter, i, physType.getJavaFieldType(expressions.size()));
if (joinType.generatesNullsOn(ord.i)) {
expression = Expressions.condition(Expressions.equal(parameter, Expressions.constant(null)), Expressions.constant(null), expression);
}
expressions.add(expression);
}
}
return Expressions.lambda(Function2.class, physType.record(expressions), parameters);
}
use of org.apache.calcite.linq4j.tree.ParameterExpression in project calcite by apache.
the class EnumerableCalc method implement.
public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
final JavaTypeFactory typeFactory = implementor.getTypeFactory();
final BlockBuilder builder = new BlockBuilder();
final EnumerableRel child = (EnumerableRel) getInput();
final Result result = implementor.visitChild(this, 0, child, pref);
final PhysType physType = PhysTypeImpl.of(typeFactory, getRowType(), pref.prefer(result.format));
// final Enumerable<Employee> inputEnumerable = <<child adapter>>;
// return new Enumerable<IntString>() {
// Enumerator<IntString> enumerator() {
// return new Enumerator<IntString>() {
// public void reset() {
// ...
Type outputJavaType = physType.getJavaRowType();
final Type enumeratorType = Types.of(Enumerator.class, outputJavaType);
Type inputJavaType = result.physType.getJavaRowType();
ParameterExpression inputEnumerator = Expressions.parameter(Types.of(Enumerator.class, inputJavaType), "inputEnumerator");
Expression input = RexToLixTranslator.convert(Expressions.call(inputEnumerator, BuiltInMethod.ENUMERATOR_CURRENT.method), inputJavaType);
final RexBuilder rexBuilder = getCluster().getRexBuilder();
final RelMetadataQuery mq = RelMetadataQuery.instance();
final RelOptPredicateList predicates = mq.getPulledUpPredicates(child);
final RexSimplify simplify = new RexSimplify(rexBuilder, predicates, false, RexUtil.EXECUTOR);
final RexProgram program = this.program.normalize(rexBuilder, simplify);
BlockStatement moveNextBody;
if (program.getCondition() == null) {
moveNextBody = Blocks.toFunctionBlock(Expressions.call(inputEnumerator, BuiltInMethod.ENUMERATOR_MOVE_NEXT.method));
} else {
final BlockBuilder builder2 = new BlockBuilder();
Expression condition = RexToLixTranslator.translateCondition(program, typeFactory, builder2, new RexToLixTranslator.InputGetterImpl(Collections.singletonList(Pair.of(input, result.physType))), implementor.allCorrelateVariables);
builder2.add(Expressions.ifThen(condition, Expressions.return_(null, Expressions.constant(true))));
moveNextBody = Expressions.block(Expressions.while_(Expressions.call(inputEnumerator, BuiltInMethod.ENUMERATOR_MOVE_NEXT.method), builder2.toBlock()), Expressions.return_(null, Expressions.constant(false)));
}
final BlockBuilder builder3 = new BlockBuilder();
List<Expression> expressions = RexToLixTranslator.translateProjects(program, typeFactory, builder3, physType, DataContext.ROOT, new RexToLixTranslator.InputGetterImpl(Collections.singletonList(Pair.of(input, result.physType))), implementor.allCorrelateVariables);
builder3.add(Expressions.return_(null, physType.record(expressions)));
BlockStatement currentBody = builder3.toBlock();
final Expression inputEnumerable = builder.append("inputEnumerable", result.block, false);
final Expression body = Expressions.new_(enumeratorType, NO_EXPRS, Expressions.list(Expressions.fieldDecl(Modifier.PUBLIC | Modifier.FINAL, inputEnumerator, Expressions.call(inputEnumerable, BuiltInMethod.ENUMERABLE_ENUMERATOR.method)), EnumUtils.overridingMethodDecl(BuiltInMethod.ENUMERATOR_RESET.method, NO_PARAMS, Blocks.toFunctionBlock(Expressions.call(inputEnumerator, BuiltInMethod.ENUMERATOR_RESET.method))), EnumUtils.overridingMethodDecl(BuiltInMethod.ENUMERATOR_MOVE_NEXT.method, NO_PARAMS, moveNextBody), EnumUtils.overridingMethodDecl(BuiltInMethod.ENUMERATOR_CLOSE.method, NO_PARAMS, Blocks.toFunctionBlock(Expressions.call(inputEnumerator, BuiltInMethod.ENUMERATOR_CLOSE.method))), Expressions.methodDecl(Modifier.PUBLIC, BRIDGE_METHODS ? Object.class : outputJavaType, "current", NO_PARAMS, currentBody)));
builder.add(Expressions.return_(null, Expressions.new_(BuiltInMethod.ABSTRACT_ENUMERABLE_CTOR.constructor, // Collections.singletonList(inputRowType),
NO_EXPRS, ImmutableList.<MemberDeclaration>of(Expressions.methodDecl(Modifier.PUBLIC, enumeratorType, BuiltInMethod.ENUMERABLE_ENUMERATOR.method.getName(), NO_PARAMS, Blocks.toFunctionBlock(body))))));
return implementor.result(physType, builder.toBlock());
}
use of org.apache.calcite.linq4j.tree.ParameterExpression in project calcite by apache.
the class EnumerableMergeJoin method implement.
public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
BlockBuilder builder = new BlockBuilder();
final Result leftResult = implementor.visitChild(this, 0, (EnumerableRel) left, pref);
final Expression leftExpression = builder.append("left", leftResult.block);
final ParameterExpression left_ = Expressions.parameter(leftResult.physType.getJavaRowType(), "left");
final Result rightResult = implementor.visitChild(this, 1, (EnumerableRel) right, pref);
final Expression rightExpression = builder.append("right", rightResult.block);
final ParameterExpression right_ = Expressions.parameter(rightResult.physType.getJavaRowType(), "right");
final JavaTypeFactory typeFactory = implementor.getTypeFactory();
final PhysType physType = PhysTypeImpl.of(typeFactory, getRowType(), pref.preferArray());
final List<Expression> leftExpressions = new ArrayList<>();
final List<Expression> rightExpressions = new ArrayList<>();
for (Pair<Integer, Integer> pair : Pair.zip(leftKeys, rightKeys)) {
final RelDataType keyType = typeFactory.leastRestrictive(ImmutableList.of(left.getRowType().getFieldList().get(pair.left).getType(), right.getRowType().getFieldList().get(pair.right).getType()));
final Type keyClass = typeFactory.getJavaClass(keyType);
leftExpressions.add(Types.castIfNecessary(keyClass, leftResult.physType.fieldReference(left_, pair.left)));
rightExpressions.add(Types.castIfNecessary(keyClass, rightResult.physType.fieldReference(right_, pair.right)));
}
final PhysType leftKeyPhysType = leftResult.physType.project(leftKeys, JavaRowFormat.LIST);
final PhysType rightKeyPhysType = rightResult.physType.project(rightKeys, JavaRowFormat.LIST);
return implementor.result(physType, builder.append(Expressions.call(BuiltInMethod.MERGE_JOIN.method, Expressions.list(leftExpression, rightExpression, Expressions.lambda(leftKeyPhysType.record(leftExpressions), left_), Expressions.lambda(rightKeyPhysType.record(rightExpressions), right_), EnumUtils.joinSelector(joinType, physType, ImmutableList.of(leftResult.physType, rightResult.physType)), Expressions.constant(joinType.generatesNullsOnLeft()), Expressions.constant(joinType.generatesNullsOnRight())))).toBlock());
}
Aggregations