use of org.apache.calcite.linq4j.tree.ParameterExpression in project calcite by apache.
the class EnumerableWindow method getPartitionIterator.
private Pair<Expression, Expression> getPartitionIterator(BlockBuilder builder, Expression source_, PhysType inputPhysType, Group group, Expression comparator_) {
//
if (group.keys.isEmpty()) {
// If partition key is empty, no need to partition.
//
// final List<Employee> tempList =
// source.into(new ArrayList<Employee>());
// Iterator<Employee[]> iterator =
// SortedMultiMap.singletonArrayIterator(comparator, tempList);
// final List<Xxx> list = new ArrayList<Xxx>(tempList.size());
final Expression tempList_ = builder.append("tempList", Expressions.convert_(Expressions.call(source_, BuiltInMethod.INTO.method, Expressions.new_(ArrayList.class)), List.class));
return Pair.of(tempList_, builder.append("iterator", Expressions.call(null, BuiltInMethod.SORTED_MULTI_MAP_SINGLETON.method, comparator_, tempList_)));
}
Expression multiMap_ = builder.append("multiMap", Expressions.new_(SortedMultiMap.class));
final BlockBuilder builder2 = new BlockBuilder();
final ParameterExpression v_ = Expressions.parameter(inputPhysType.getJavaRowType(), builder2.newName("v"));
Pair<Type, List<Expression>> selector = inputPhysType.selector(v_, group.keys.asList(), JavaRowFormat.CUSTOM);
final ParameterExpression key_;
if (selector.left instanceof Types.RecordType) {
Types.RecordType keyJavaType = (Types.RecordType) selector.left;
List<Expression> initExpressions = selector.right;
key_ = Expressions.parameter(keyJavaType, "key");
builder2.add(Expressions.declare(0, key_, null));
builder2.add(Expressions.statement(Expressions.assign(key_, Expressions.new_(keyJavaType))));
List<Types.RecordField> fieldList = keyJavaType.getRecordFields();
for (int i = 0; i < initExpressions.size(); i++) {
Expression right = initExpressions.get(i);
builder2.add(Expressions.statement(Expressions.assign(Expressions.field(key_, fieldList.get(i)), right)));
}
} else {
DeclarationStatement declare = Expressions.declare(0, "key", selector.right.get(0));
builder2.add(declare);
key_ = declare.parameter;
}
builder2.add(Expressions.statement(Expressions.call(multiMap_, BuiltInMethod.SORTED_MULTI_MAP_PUT_MULTI.method, key_, v_)));
builder2.add(Expressions.return_(null, Expressions.constant(null)));
builder.add(Expressions.statement(Expressions.call(source_, BuiltInMethod.ENUMERABLE_FOREACH.method, Expressions.lambda(builder2.toBlock(), v_))));
return Pair.of(multiMap_, builder.append("iterator", Expressions.call(multiMap_, BuiltInMethod.SORTED_MULTI_MAP_ARRAYS.method, comparator_)));
}
use of org.apache.calcite.linq4j.tree.ParameterExpression in project calcite by apache.
the class EnumerableWindow method declareAndResetState.
private void declareAndResetState(final JavaTypeFactory typeFactory, BlockBuilder builder, final Result result, int windowIdx, List<AggImpState> aggs, PhysType outputPhysType, List<Expression> outputRow) {
for (final AggImpState agg : aggs) {
agg.context = new WinAggContext() {
public SqlAggFunction aggregation() {
return agg.call.getAggregation();
}
public RelDataType returnRelType() {
return agg.call.type;
}
public Type returnType() {
return EnumUtils.javaClass(typeFactory, returnRelType());
}
public List<? extends Type> parameterTypes() {
return EnumUtils.fieldTypes(typeFactory, parameterRelTypes());
}
public List<? extends RelDataType> parameterRelTypes() {
return EnumUtils.fieldRowTypes(result.physType.getRowType(), constants, agg.call.getArgList());
}
public List<ImmutableBitSet> groupSets() {
throw new UnsupportedOperationException();
}
public List<Integer> keyOrdinals() {
throw new UnsupportedOperationException();
}
public List<? extends RelDataType> keyRelTypes() {
throw new UnsupportedOperationException();
}
public List<? extends Type> keyTypes() {
throw new UnsupportedOperationException();
}
};
String aggName = "a" + agg.aggIdx;
if (CalcitePrepareImpl.DEBUG) {
aggName = Util.toJavaId(agg.call.getAggregation().getName(), 0).substring("ID$0$".length()) + aggName;
}
List<Type> state = agg.implementor.getStateType(agg.context);
final List<Expression> decls = new ArrayList<Expression>(state.size());
for (int i = 0; i < state.size(); i++) {
Type type = state.get(i);
ParameterExpression pe = Expressions.parameter(type, builder.newName(aggName + "s" + i + "w" + windowIdx));
builder.add(Expressions.declare(0, pe, null));
decls.add(pe);
}
agg.state = decls;
Type aggHolderType = agg.context.returnType();
Type aggStorageType = outputPhysType.getJavaFieldType(outputRow.size());
if (Primitive.is(aggHolderType) && !Primitive.is(aggStorageType)) {
aggHolderType = Primitive.box(aggHolderType);
}
ParameterExpression aggRes = Expressions.parameter(0, aggHolderType, builder.newName(aggName + "w" + windowIdx));
builder.add(Expressions.declare(0, aggRes, Expressions.constant(Primitive.is(aggRes.getType()) ? Primitive.of(aggRes.getType()).defaultValue : null, aggRes.getType())));
agg.result = aggRes;
outputRow.add(aggRes);
agg.implementor.implementReset(agg.context, new WinAggResetContextImpl(builder, agg.state, null, null, null, null, null, null));
}
}
use of org.apache.calcite.linq4j.tree.ParameterExpression in project calcite by apache.
the class EnumerableWindow method translateBound.
private Expression translateBound(RexToLixTranslator translator, ParameterExpression i_, Expression row_, Expression min_, Expression max_, Expression rows_, Group group, boolean lower, PhysType physType, Expression rowComparator, Expression keySelector, Expression keyComparator) {
RexWindowBound bound = lower ? group.lowerBound : group.upperBound;
if (bound.isUnbounded()) {
return bound.isPreceding() ? min_ : max_;
}
if (group.isRows) {
if (bound.isCurrentRow()) {
return i_;
}
RexNode node = bound.getOffset();
Expression offs = translator.translate(node);
// Floating offset does not make sense since we refer to array index.
// Nulls do not make sense as well.
offs = RexToLixTranslator.convert(offs, int.class);
Expression b = i_;
if (bound.isFollowing()) {
b = Expressions.add(b, offs);
} else {
b = Expressions.subtract(b, offs);
}
return b;
}
Expression searchLower = min_;
Expression searchUpper = max_;
if (bound.isCurrentRow()) {
if (lower) {
searchUpper = i_;
} else {
searchLower = i_;
}
}
List<RelFieldCollation> fieldCollations = group.collation().getFieldCollations();
if (bound.isCurrentRow() && fieldCollations.size() != 1) {
return Expressions.call((lower ? BuiltInMethod.BINARY_SEARCH5_LOWER : BuiltInMethod.BINARY_SEARCH5_UPPER).method, rows_, row_, searchLower, searchUpper, keySelector, keyComparator);
}
assert fieldCollations.size() == 1 : "When using range window specification, ORDER BY should have" + " exactly one expression." + " Actual collation is " + group.collation();
// isRange
int orderKey = fieldCollations.get(0).getFieldIndex();
RelDataType keyType = physType.getRowType().getFieldList().get(orderKey).getType();
Type desiredKeyType = translator.typeFactory.getJavaClass(keyType);
if (bound.getOffset() == null) {
desiredKeyType = Primitive.box(desiredKeyType);
}
Expression val = translator.translate(new RexInputRef(orderKey, keyType), desiredKeyType);
if (!bound.isCurrentRow()) {
RexNode node = bound.getOffset();
Expression offs = translator.translate(node);
// TODO: support date + interval somehow
if (bound.isFollowing()) {
val = Expressions.add(val, offs);
} else {
val = Expressions.subtract(val, offs);
}
}
return Expressions.call((lower ? BuiltInMethod.BINARY_SEARCH6_LOWER : BuiltInMethod.BINARY_SEARCH6_UPPER).method, rows_, val, searchLower, searchUpper, keySelector, keyComparator);
}
use of org.apache.calcite.linq4j.tree.ParameterExpression in project calcite by apache.
the class EnumerableCorrelate method implement.
public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
final BlockBuilder builder = new BlockBuilder();
final Result leftResult = implementor.visitChild(this, 0, (EnumerableRel) left, pref);
Expression leftExpression = builder.append("left", leftResult.block);
final BlockBuilder corrBlock = new BlockBuilder();
Type corrVarType = leftResult.physType.getJavaRowType();
// correlate to be used in inner loop
ParameterExpression corrRef;
// argument to correlate lambda (must be boxed)
ParameterExpression corrArg;
if (!Primitive.is(corrVarType)) {
corrArg = Expressions.parameter(Modifier.FINAL, corrVarType, getCorrelVariable());
corrRef = corrArg;
} else {
corrArg = Expressions.parameter(Modifier.FINAL, Primitive.box(corrVarType), "$box" + getCorrelVariable());
corrRef = (ParameterExpression) corrBlock.append(getCorrelVariable(), Expressions.unbox(corrArg));
}
implementor.registerCorrelVariable(getCorrelVariable(), corrRef, corrBlock, leftResult.physType);
final Result rightResult = implementor.visitChild(this, 1, (EnumerableRel) right, pref);
implementor.clearCorrelVariable(getCorrelVariable());
corrBlock.add(rightResult.block);
final PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), getRowType(), pref.prefer(JavaRowFormat.CUSTOM));
Expression selector = EnumUtils.joinSelector(joinType.returnsJustFirstInput() ? joinType.toJoinType() : JoinRelType.INNER, physType, ImmutableList.of(leftResult.physType, rightResult.physType));
builder.append(Expressions.call(leftExpression, BuiltInMethod.CORRELATE_JOIN.method, Expressions.constant(joinType.toLinq4j()), Expressions.lambda(corrBlock.toBlock(), corrArg), selector));
return implementor.result(physType, builder.toBlock());
}
use of org.apache.calcite.linq4j.tree.ParameterExpression in project calcite by apache.
the class SqlUserDefinedTableMacro method coerce.
private static Object coerce(Object o, RelDataType type) {
if (o == null) {
return null;
}
if (!(type instanceof RelDataTypeFactoryImpl.JavaType)) {
return null;
}
final RelDataTypeFactoryImpl.JavaType javaType = (RelDataTypeFactoryImpl.JavaType) type;
final Class clazz = javaType.getJavaClass();
// noinspection unchecked
if (clazz.isAssignableFrom(o.getClass())) {
return o;
}
if (clazz == String.class && o instanceof NlsString) {
return ((NlsString) o).getValue();
}
// We need optimization here for constant folding.
// Not all the expressions can be interpreted (e.g. ternary), so
// we rely on optimization capabilities to fold non-interpretable
// expressions.
BlockBuilder bb = new BlockBuilder();
final Expression expr = RexToLixTranslator.convert(Expressions.constant(o), clazz);
bb.add(Expressions.return_(null, expr));
final FunctionExpression convert = Expressions.lambda(bb.toBlock(), Collections.<ParameterExpression>emptyList());
return convert.compile().dynamicInvoke();
}
Aggregations