use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class RelMdAllPredicates method getAllPredicates.
/**
* Add the Join condition to the list obtained from the input.
*/
public RelOptPredicateList getAllPredicates(Join join, RelMetadataQuery mq) {
if (join.getJoinType() != JoinRelType.INNER) {
// We cannot map origin of this expression.
return null;
}
final RexBuilder rexBuilder = join.getCluster().getRexBuilder();
final RexNode pred = join.getCondition();
final Multimap<List<String>, RelTableRef> qualifiedNamesToRefs = HashMultimap.create();
RelOptPredicateList newPreds = RelOptPredicateList.EMPTY;
for (RelNode input : join.getInputs()) {
final RelOptPredicateList inputPreds = mq.getAllPredicates(input);
if (inputPreds == null) {
// Bail out
return null;
}
// Gather table references
final Set<RelTableRef> tableRefs = mq.getTableReferences(input);
if (input == join.getLeft()) {
// Left input references remain unchanged
for (RelTableRef leftRef : tableRefs) {
qualifiedNamesToRefs.put(leftRef.getQualifiedName(), leftRef);
}
newPreds = newPreds.union(rexBuilder, inputPreds);
} else {
// Right input references might need to be updated if there are table name
// clashes with left input
final Map<RelTableRef, RelTableRef> currentTablesMapping = new HashMap<>();
for (RelTableRef rightRef : tableRefs) {
int shift = 0;
Collection<RelTableRef> lRefs = qualifiedNamesToRefs.get(rightRef.getQualifiedName());
if (lRefs != null) {
shift = lRefs.size();
}
currentTablesMapping.put(rightRef, RelTableRef.of(rightRef.getTable(), shift + rightRef.getEntityNumber()));
}
final List<RexNode> updatedPreds = Lists.newArrayList(Iterables.transform(inputPreds.pulledUpPredicates, new Function<RexNode, RexNode>() {
@Override
public RexNode apply(RexNode e) {
return RexUtil.swapTableReferences(rexBuilder, e, currentTablesMapping);
}
}));
newPreds = newPreds.union(rexBuilder, RelOptPredicateList.of(rexBuilder, updatedPreds));
}
}
// Extract input fields referenced by Join condition
final Set<RelDataTypeField> inputExtraFields = new LinkedHashSet<>();
final RelOptUtil.InputFinder inputFinder = new RelOptUtil.InputFinder(inputExtraFields);
pred.accept(inputFinder);
final ImmutableBitSet inputFieldsUsed = inputFinder.inputBitSet.build();
// Infer column origin expressions for given references
final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
for (int idx : inputFieldsUsed) {
final RexInputRef inputRef = RexInputRef.of(idx, join.getRowType().getFieldList());
final Set<RexNode> originalExprs = mq.getExpressionLineage(join, inputRef);
if (originalExprs == null) {
// Bail out
return null;
}
final RexInputRef ref = RexInputRef.of(idx, join.getRowType().getFieldList());
mapping.put(ref, originalExprs);
}
// Replace with new expressions and return union of predicates
return newPreds.union(rexBuilder, RelOptPredicateList.of(rexBuilder, RelMdExpressionLineage.createAllPossibleExpressions(rexBuilder, pred, mapping)));
}
use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class RelMdAllPredicates method getAllPredicates.
/**
* Add the Filter condition to the list obtained from the input.
*/
public RelOptPredicateList getAllPredicates(Filter filter, RelMetadataQuery mq) {
final RelNode input = filter.getInput();
final RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
final RexNode pred = filter.getCondition();
final RelOptPredicateList predsBelow = mq.getAllPredicates(input);
if (predsBelow == null) {
// Safety check
return null;
}
// Extract input fields referenced by Filter condition
final Set<RelDataTypeField> inputExtraFields = new LinkedHashSet<>();
final RelOptUtil.InputFinder inputFinder = new RelOptUtil.InputFinder(inputExtraFields);
pred.accept(inputFinder);
final ImmutableBitSet inputFieldsUsed = inputFinder.inputBitSet.build();
// Infer column origin expressions for given references
final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
for (int idx : inputFieldsUsed) {
final RexInputRef ref = RexInputRef.of(idx, filter.getRowType().getFieldList());
final Set<RexNode> originalExprs = mq.getExpressionLineage(filter, ref);
if (originalExprs == null) {
// Bail out
return null;
}
mapping.put(ref, originalExprs);
}
// Replace with new expressions and return union of predicates
return predsBelow.union(rexBuilder, RelOptPredicateList.of(rexBuilder, RelMdExpressionLineage.createAllPossibleExpressions(rexBuilder, pred, mapping)));
}
use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class Aggregate method deriveRowType.
/**
* Computes the row type of an {@code Aggregate} before it exists.
*
* @param typeFactory Type factory
* @param inputRowType Input row type
* @param indicator Whether row type should include indicator fields to
* indicate which grouping set is active; must be true if
* aggregate is not simple
* @param groupSet Bit set of grouping fields
* @param groupSets List of all grouping sets; null for just {@code groupSet}
* @param aggCalls Collection of calls to aggregate functions
* @return Row type of the aggregate
*/
public static RelDataType deriveRowType(RelDataTypeFactory typeFactory, final RelDataType inputRowType, boolean indicator, ImmutableBitSet groupSet, List<ImmutableBitSet> groupSets, final List<AggregateCall> aggCalls) {
final List<Integer> groupList = groupSet.asList();
assert groupList.size() == groupSet.cardinality();
final RelDataTypeFactory.Builder builder = typeFactory.builder();
final List<RelDataTypeField> fieldList = inputRowType.getFieldList();
final Set<String> containedNames = Sets.newHashSet();
for (int groupKey : groupList) {
final RelDataTypeField field = fieldList.get(groupKey);
containedNames.add(field.getName());
builder.add(field);
if (groupSets != null && !allContain(groupSets, groupKey)) {
builder.nullable(true);
}
}
if (indicator) {
for (int groupKey : groupList) {
final RelDataType booleanType = typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.BOOLEAN), false);
final String base = "i$" + fieldList.get(groupKey).getName();
String name = base;
int i = 0;
while (containedNames.contains(name)) {
name = base + "_" + i++;
}
containedNames.add(name);
builder.add(name, booleanType);
}
}
for (Ord<AggregateCall> aggCall : Ord.zip(aggCalls)) {
final String base;
if (aggCall.e.name != null) {
base = aggCall.e.name;
} else {
base = "$f" + (groupList.size() + aggCall.i);
}
String name = base;
int i = 0;
while (containedNames.contains(name)) {
name = base + "_" + i++;
}
containedNames.add(name);
builder.add(name, aggCall.e.type);
}
return builder.build();
}
use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class Values method assertRowType.
/**
* Returns true if all tuples match rowType; otherwise, assert on
* mismatch.
*/
private boolean assertRowType() {
for (List<RexLiteral> tuple : tuples) {
assert tuple.size() == rowType.getFieldCount();
for (Pair<RexLiteral, RelDataTypeField> pair : Pair.zip(tuple, rowType.getFieldList())) {
RexLiteral literal = pair.left;
RelDataType fieldType = pair.right.getType();
// been dealt with.
if (!RexLiteral.isNullLiteral(literal)) {
assert SqlTypeUtil.canAssignFrom(fieldType, literal.getType()) : "to " + fieldType + " from " + literal;
}
}
}
return true;
}
use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.
the class ModifiableViewTable method extend.
/**
* Extends the underlying table and returns a new view with updated row-type
* and column-mapping.
*
* <p>The type factory is used to perform some scratch calculations, viz the
* type mapping, but the "real" row-type will be assigned later, when the
* table has been bound to the statement's type factory. The is important,
* because adding types to type factories that do not belong to a statement
* could potentially leak memory.
*
* @param extendedColumns Extended fields
* @param typeFactory Type factory
*/
public final ModifiableViewTable extend(List<RelDataTypeField> extendedColumns, RelDataTypeFactory typeFactory) {
final ExtensibleTable underlying = unwrap(ExtensibleTable.class);
assert underlying != null;
final RelDataTypeFactory.Builder builder = typeFactory.builder();
final RelDataType rowType = getRowType(typeFactory);
for (RelDataTypeField column : rowType.getFieldList()) {
builder.add(column);
}
for (RelDataTypeField column : extendedColumns) {
builder.add(column);
}
// The characteristics of the new view.
final RelDataType newRowType = builder.build();
final ImmutableIntList newColumnMapping = getNewColumnMapping(underlying, getColumnMapping(), extendedColumns, typeFactory);
// Extend the underlying table with only the fields that
// duplicate column names in neither the view nor the base table.
final List<RelDataTypeField> underlyingColumns = underlying.getRowType(typeFactory).getFieldList();
final List<RelDataTypeField> columnsOfExtendedBaseTable = RelOptUtil.deduplicateColumns(underlyingColumns, extendedColumns);
final List<RelDataTypeField> extendColumnsOfBaseTable = columnsOfExtendedBaseTable.subList(underlyingColumns.size(), columnsOfExtendedBaseTable.size());
final Table extendedTable = underlying.extend(extendColumnsOfBaseTable);
return extend(extendedTable, RelDataTypeImpl.proto(newRowType), newColumnMapping);
}
Aggregations