use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class JavaTypeFactoryExtImpl method createPdxType2.
// Experimental flattering the nested structures.
public RelDataType createPdxType2(PdxInstance pdxInstance) {
final List<RelDataTypeField> list = new ArrayList<>();
recursiveCreatePdxType(pdxInstance, list, "");
return canonize(new RelRecordType(list));
}
use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class JavaTypeFactoryExtImpl method createStructType.
/**
* See <a href="http://stackoverflow.com/questions/16966629/what-is-the-difference-between-getfields-and-getdeclaredfields-in-java-reflectio">
* the difference between fields and declared fields</a>.
*/
@Override
public RelDataType createStructType(Class type) {
final List<RelDataTypeField> list = new ArrayList<>();
for (Field field : type.getDeclaredFields()) {
if (!Modifier.isStatic(field.getModifiers())) {
// FIXME: watch out for recursion
final Type fieldType = field.getType();
list.add(new RelDataTypeFieldImpl(field.getName(), list.size(), createType(fieldType)));
}
}
return canonize(new JavaRecordType(list, type));
}
use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class PhysTypeImpl method field.
public PhysType field(int ordinal) {
final RelDataTypeField field = rowType.getFieldList().get(ordinal);
final RelDataType type = field.getType();
return PhysTypeImpl.of(typeFactory, toStruct(type), format, false);
}
use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class EnumerableUncollect method implement.
public Result implement(EnumerableRelImplementor implementor, Prefer pref) {
final BlockBuilder builder = new BlockBuilder();
final EnumerableRel child = (EnumerableRel) getInput();
final Result result = implementor.visitChild(this, 0, child, pref);
final PhysType physType = PhysTypeImpl.of(implementor.getTypeFactory(), getRowType(), JavaRowFormat.LIST);
// final Enumerable<List<Employee>> child = <<child adapter>>;
// return child.selectMany(FLAT_PRODUCT);
final Expression child_ = builder.append("child", result.block);
final List<Integer> fieldCounts = new ArrayList<>();
final List<FlatProductInputType> inputTypes = new ArrayList<>();
for (RelDataTypeField field : child.getRowType().getFieldList()) {
final RelDataType type = field.getType();
if (type instanceof MapSqlType) {
fieldCounts.add(2);
inputTypes.add(FlatProductInputType.MAP);
} else {
final RelDataType elementType = type.getComponentType();
if (elementType.isStruct()) {
fieldCounts.add(elementType.getFieldCount());
inputTypes.add(FlatProductInputType.LIST);
} else {
fieldCounts.add(-1);
inputTypes.add(FlatProductInputType.SCALAR);
}
}
}
final Expression lambda = Expressions.call(BuiltInMethod.FLAT_PRODUCT.method, Expressions.constant(Ints.toArray(fieldCounts)), Expressions.constant(withOrdinality), Expressions.constant(inputTypes.toArray(new FlatProductInputType[inputTypes.size()])));
builder.add(Expressions.return_(null, Expressions.call(child_, BuiltInMethod.SELECT_MANY.method, lambda)));
return implementor.result(physType, builder.toBlock());
}
use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class AggregateExpandDistinctAggregatesRule method onMatch.
// ~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
final Aggregate aggregate = call.rel(0);
if (!aggregate.containsDistinctCall()) {
return;
}
// Find all of the agg expressions. We use a LinkedHashSet to ensure determinism.
// find all aggregate calls without distinct
int nonDistinctAggCallCount = 0;
int filterCount = 0;
int unsupportedNonDistinctAggCallCount = 0;
final Set<Pair<List<Integer>, Integer>> argLists = new LinkedHashSet<>();
for (AggregateCall aggCall : aggregate.getAggCallList()) {
if (aggCall.filterArg >= 0) {
++filterCount;
}
if (!aggCall.isDistinct()) {
++nonDistinctAggCallCount;
final SqlKind aggCallKind = aggCall.getAggregation().getKind();
// We only support COUNT/SUM/MIN/MAX for the "single" count distinct optimization
switch(aggCallKind) {
case COUNT:
case SUM:
case SUM0:
case MIN:
case MAX:
break;
default:
++unsupportedNonDistinctAggCallCount;
}
} else {
argLists.add(Pair.of(aggCall.getArgList(), aggCall.filterArg));
}
}
final int distinctAggCallCount = aggregate.getAggCallList().size() - nonDistinctAggCallCount;
Preconditions.checkState(argLists.size() > 0, "containsDistinctCall lied");
// arguments then we can use a more efficient form.
if (nonDistinctAggCallCount == 0 && argLists.size() == 1 && aggregate.getGroupType() == Group.SIMPLE) {
final Pair<List<Integer>, Integer> pair = Iterables.getOnlyElement(argLists);
final RelBuilder relBuilder = call.builder();
convertMonopole(relBuilder, aggregate, pair.left, pair.right);
call.transformTo(relBuilder.build());
return;
}
if (useGroupingSets) {
rewriteUsingGroupingSets(call, aggregate);
return;
}
// we can generate multi-phase aggregates
if (// one distinct aggregate
distinctAggCallCount == 1 && // no filter
filterCount == 0 && // sum/min/max/count in non-distinct aggregate
unsupportedNonDistinctAggCallCount == 0 && nonDistinctAggCallCount > 0) {
// one or more non-distinct aggregates
final RelBuilder relBuilder = call.builder();
convertSingletonDistinct(relBuilder, aggregate, argLists);
call.transformTo(relBuilder.build());
return;
}
// Create a list of the expressions which will yield the final result.
// Initially, the expressions point to the input field.
final List<RelDataTypeField> aggFields = aggregate.getRowType().getFieldList();
final List<RexInputRef> refs = new ArrayList<>();
final List<String> fieldNames = aggregate.getRowType().getFieldNames();
final ImmutableBitSet groupSet = aggregate.getGroupSet();
final int groupAndIndicatorCount = aggregate.getGroupCount() + aggregate.getIndicatorCount();
for (int i : Util.range(groupAndIndicatorCount)) {
refs.add(RexInputRef.of(i, aggFields));
}
// Aggregate the original relation, including any non-distinct aggregates.
final List<AggregateCall> newAggCallList = new ArrayList<>();
int i = -1;
for (AggregateCall aggCall : aggregate.getAggCallList()) {
++i;
if (aggCall.isDistinct()) {
refs.add(null);
continue;
}
refs.add(new RexInputRef(groupAndIndicatorCount + newAggCallList.size(), aggFields.get(groupAndIndicatorCount + i).getType()));
newAggCallList.add(aggCall);
}
// In the case where there are no non-distinct aggregates (regardless of
// whether there are group bys), there's no need to generate the
// extra aggregate and join.
final RelBuilder relBuilder = call.builder();
relBuilder.push(aggregate.getInput());
int n = 0;
if (!newAggCallList.isEmpty()) {
final RelBuilder.GroupKey groupKey = relBuilder.groupKey(groupSet, aggregate.getGroupSets());
relBuilder.aggregate(groupKey, newAggCallList);
++n;
}
// set of operands.
for (Pair<List<Integer>, Integer> argList : argLists) {
doRewrite(relBuilder, aggregate, n++, argList.left, argList.right, refs);
}
relBuilder.project(refs, fieldNames);
call.transformTo(relBuilder.build());
}
Aggregations