use of org.apache.calcite.linq4j.tree.Expression in project calcite by apache.
the class ElasticsearchToEnumerableConverter method implement.
@Override
public Result implement(EnumerableRelImplementor implementor, Prefer prefer) {
final BlockBuilder list = new BlockBuilder();
final ElasticsearchRel.Implementor elasticsearchImplementor = new ElasticsearchRel.Implementor();
elasticsearchImplementor.visitChild(0, getInput());
final RelDataType rowType = getRowType();
final PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), rowType, prefer.prefer(JavaRowFormat.ARRAY));
final Expression fields = list.append("fields", constantArrayList(Pair.zip(ElasticsearchRules.elasticsearchFieldNames(rowType), new AbstractList<Class>() {
@Override
public Class get(int index) {
return physType.fieldClass(index);
}
@Override
public int size() {
return rowType.getFieldCount();
}
}), Pair.class));
final Expression table = list.append("table", elasticsearchImplementor.table.getExpression(AbstractElasticsearchTable.ElasticsearchQueryable.class));
List<String> opList = elasticsearchImplementor.list;
final Expression ops = list.append("ops", constantArrayList(opList, String.class));
Expression enumerable = list.append("enumerable", Expressions.call(table, ElasticsearchMethod.ELASTICSEARCH_QUERYABLE_FIND.method, ops, fields));
if (CalcitePrepareImpl.DEBUG) {
System.out.println("Elasticsearch: " + opList);
}
Hook.QUERY_PLAN.run(opList);
list.add(Expressions.return_(null, enumerable));
return implementor.result(physType, list.toBlock());
}
use of org.apache.calcite.linq4j.tree.Expression in project calcite by apache.
the class PhysTypeImpl method generateAccessor.
public Expression generateAccessor(List<Integer> fields) {
ParameterExpression v1 = Expressions.parameter(javaRowClass, "v1");
switch(fields.size()) {
case 0:
return Expressions.lambda(Function1.class, Expressions.field(null, BuiltInMethod.COMPARABLE_EMPTY_LIST.field), v1);
case 1:
int field0 = fields.get(0);
// new Function1<Employee, Res> {
// public Res apply(Employee v1) {
// return v1.<fieldN>;
// }
// }
Class returnType = fieldClasses.get(field0);
Expression fieldReference = Types.castIfNecessary(returnType, fieldReference(v1, field0));
return Expressions.lambda(Function1.class, fieldReference, v1);
default:
// new Function1<Employee, List> {
// public List apply(Employee v1) {
// return Arrays.asList(
// new Object[] {v1.<fieldN>, v1.<fieldM>});
// }
// }
Expressions.FluentList<Expression> list = Expressions.list();
for (int field : fields) {
list.add(fieldReference(v1, field));
}
switch(list.size()) {
case 2:
return Expressions.lambda(Function1.class, Expressions.call(List.class, null, BuiltInMethod.LIST2.method, list), v1);
case 3:
return Expressions.lambda(Function1.class, Expressions.call(List.class, null, BuiltInMethod.LIST3.method, list), v1);
case 4:
return Expressions.lambda(Function1.class, Expressions.call(List.class, null, BuiltInMethod.LIST4.method, list), v1);
case 5:
return Expressions.lambda(Function1.class, Expressions.call(List.class, null, BuiltInMethod.LIST5.method, list), v1);
case 6:
return Expressions.lambda(Function1.class, Expressions.call(List.class, null, BuiltInMethod.LIST6.method, list), v1);
default:
return Expressions.lambda(Function1.class, Expressions.call(List.class, null, BuiltInMethod.LIST_N.method, Expressions.newArrayInit(Comparable.class, list)), v1);
}
}
}
use of org.apache.calcite.linq4j.tree.Expression in project calcite by apache.
the class PhysTypeImpl method generateSelector.
public Expression generateSelector(final ParameterExpression parameter, final List<Integer> fields, List<Integer> usedFields, JavaRowFormat targetFormat) {
final PhysType targetPhysType = project(fields, true, targetFormat);
final List<Expression> expressions = Lists.newArrayList();
for (Ord<Integer> ord : Ord.zip(fields)) {
final Integer field = ord.e;
if (usedFields.contains(field)) {
expressions.add(fieldReference(parameter, field));
} else {
final Primitive primitive = Primitive.of(targetPhysType.fieldClass(ord.i));
expressions.add(Expressions.constant(primitive != null ? primitive.defaultValue : null));
}
}
for (Integer field : fields) {
expressions.add(Expressions.constant(!usedFields.contains(field)));
}
return Expressions.lambda(Function1.class, targetPhysType.record(expressions), parameter);
}
use of org.apache.calcite.linq4j.tree.Expression in project calcite by apache.
the class RexImpTable method implementNullSemantics.
private static Expression implementNullSemantics(RexToLixTranslator translator, RexCall call, NullAs nullAs, NullPolicy nullPolicy, NotNullImplementor implementor) {
final List<Expression> list = new ArrayList<>();
switch(nullAs) {
case NULL:
// v0 == null || v1 == null ? null : f(v0, v1)
for (Ord<RexNode> operand : Ord.zip(call.getOperands())) {
if (translator.isNullable(operand.e)) {
list.add(translator.translate(operand.e, NullAs.IS_NULL));
translator = translator.setNullable(operand.e, false);
}
}
final Expression box = Expressions.box(implementCall(translator, call, implementor, nullAs));
return optimize(Expressions.condition(Expressions.foldOr(list), Types.castIfNecessary(box.getType(), NULL_EXPR), box));
case FALSE:
// v0 != null && v1 != null && f(v0, v1)
for (Ord<RexNode> operand : Ord.zip(call.getOperands())) {
if (translator.isNullable(operand.e)) {
list.add(translator.translate(operand.e, NullAs.IS_NOT_NULL));
translator = translator.setNullable(operand.e, false);
}
}
list.add(implementCall(translator, call, implementor, nullAs));
return Expressions.foldAnd(list);
case TRUE:
// v0 == null || v1 == null || f(v0, v1)
for (Ord<RexNode> operand : Ord.zip(call.getOperands())) {
if (translator.isNullable(operand.e)) {
list.add(translator.translate(operand.e, NullAs.IS_NULL));
translator = translator.setNullable(operand.e, false);
}
}
list.add(implementCall(translator, call, implementor, nullAs));
return Expressions.foldOr(list);
case NOT_POSSIBLE:
// Need to transmit to the implementor the fact that call cannot
// return null. In particular, it should return a primitive (e.g.
// int) rather than a box type (Integer).
// The cases with setNullable above might not help since the same
// RexNode can be referred via multiple ways: RexNode itself, RexLocalRef,
// and may be others.
final Map<RexNode, Boolean> nullable = new HashMap<>();
switch(nullPolicy) {
case STRICT:
// in nulls NOT_POSSIBLE mode
for (RexNode arg : call.getOperands()) {
if (translator.isNullable(arg) && !nullable.containsKey(arg)) {
nullable.put(arg, false);
}
}
}
nullable.put(call, false);
translator = translator.setNullable(nullable);
// fall through
default:
return implementCall(translator, call, implementor, nullAs);
}
}
use of org.apache.calcite.linq4j.tree.Expression in project calcite by apache.
the class RexToLixTranslator method handleNull.
/**
* Adapts an expression with "normal" result to one that adheres to
* this particular policy. Wraps the result expression into a new
* parameter if need be.
*
* @param input Expression
* @param nullAs If false, if expression is definitely not null at
* runtime. Therefore we can optimize. For example, we can cast to int
* using x.intValue().
* @return Translated expression
*/
public Expression handleNull(Expression input, RexImpTable.NullAs nullAs) {
final Expression nullHandled = nullAs.handle(input);
// If we get ConstantExpression, just return it (i.e. primitive false)
if (nullHandled instanceof ConstantExpression) {
return nullHandled;
}
// then we can just reuse it
if (nullHandled == input) {
return input;
}
// If nullHandled is different, then it might be unsafe to compute
// early (i.e. unbox of null value should not happen _before_ ternary).
// Thus we wrap it into brand-new ParameterExpression,
// and we are guaranteed that ParameterExpression will not be shared
String unboxVarName = "v_unboxed";
if (input instanceof ParameterExpression) {
unboxVarName = ((ParameterExpression) input).name + "_unboxed";
}
ParameterExpression unboxed = Expressions.parameter(nullHandled.getType(), list.newName(unboxVarName));
list.add(Expressions.declare(Modifier.FINAL, unboxed, nullHandled));
return unboxed;
}
Aggregations