Search in sources :

Example 26 with RelDataTypeField

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)));
}
Also used : LinkedHashSet(java.util.LinkedHashSet) LinkedHashSet(java.util.LinkedHashSet) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) Set(java.util.Set) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) LinkedHashMap(java.util.LinkedHashMap) Function(com.google.common.base.Function) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) RexBuilder(org.apache.calcite.rex.RexBuilder) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) List(java.util.List) RelOptUtil(org.apache.calcite.plan.RelOptUtil) RelTableRef(org.apache.calcite.rex.RexTableInputRef.RelTableRef) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Example 27 with RelDataTypeField

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)));
}
Also used : LinkedHashSet(java.util.LinkedHashSet) LinkedHashSet(java.util.LinkedHashSet) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) Set(java.util.Set) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RelOptUtil(org.apache.calcite.plan.RelOptUtil) LinkedHashMap(java.util.LinkedHashMap) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Example 28 with RelDataTypeField

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();
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 29 with RelDataTypeField

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;
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 30 with RelDataTypeField

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);
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelOptTable(org.apache.calcite.plan.RelOptTable) Table(org.apache.calcite.schema.Table) ExtensibleTable(org.apache.calcite.schema.ExtensibleTable) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RelDataType(org.apache.calcite.rel.type.RelDataType) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) ExtensibleTable(org.apache.calcite.schema.ExtensibleTable)

Aggregations

RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)383 RelDataType (org.apache.calcite.rel.type.RelDataType)206 RexNode (org.apache.calcite.rex.RexNode)185 ArrayList (java.util.ArrayList)173 RelNode (org.apache.calcite.rel.RelNode)130 RexBuilder (org.apache.calcite.rex.RexBuilder)76 RexInputRef (org.apache.calcite.rex.RexInputRef)72 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)65 Pair (org.apache.calcite.util.Pair)55 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)47 HashMap (java.util.HashMap)39 Map (java.util.Map)35 AggregateCall (org.apache.calcite.rel.core.AggregateCall)35 SqlNode (org.apache.calcite.sql.SqlNode)32 ImmutableList (com.google.common.collect.ImmutableList)31 RelBuilder (org.apache.calcite.tools.RelBuilder)29 RelDataTypeFieldImpl (org.apache.calcite.rel.type.RelDataTypeFieldImpl)25 List (java.util.List)23 LinkedHashSet (java.util.LinkedHashSet)22 RelOptUtil (org.apache.calcite.plan.RelOptUtil)22