Search in sources :

Example 71 with RelDataTypeField

use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class RelFieldTrimmer method trimFields.

/**
 * Variant of {@link #trimFields(RelNode, ImmutableBitSet, Set)} for
 * {@link org.apache.calcite.rel.logical.LogicalFilter}.
 */
public TrimResult trimFields(Filter filter, ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final RelDataType rowType = filter.getRowType();
    final int fieldCount = rowType.getFieldCount();
    final RexNode conditionExpr = filter.getCondition();
    final RelNode input = filter.getInput();
    // We use the fields used by the consumer, plus any fields used in the
    // filter.
    final Set<RelDataTypeField> inputExtraFields = new LinkedHashSet<>(extraFields);
    RelOptUtil.InputFinder inputFinder = new RelOptUtil.InputFinder(inputExtraFields);
    inputFinder.inputBitSet.addAll(fieldsUsed);
    conditionExpr.accept(inputFinder);
    final ImmutableBitSet inputFieldsUsed = inputFinder.inputBitSet.build();
    // Create input with trimmed columns.
    TrimResult trimResult = trimChild(filter, input, inputFieldsUsed, inputExtraFields);
    RelNode newInput = trimResult.left;
    final Mapping inputMapping = trimResult.right;
    // there's nothing we can do.
    if (newInput == input && fieldsUsed.cardinality() == fieldCount) {
        return result(filter, Mappings.createIdentity(fieldCount));
    }
    // Build new project expressions, and populate the mapping.
    final RexVisitor<RexNode> shuttle = new RexPermuteInputsShuttle(inputMapping, newInput);
    RexNode newConditionExpr = conditionExpr.accept(shuttle);
    // Use copy rather than relBuilder so that correlating variables get set.
    relBuilder.push(filter.copy(filter.getTraitSet(), newInput, newConditionExpr));
    // needs them for its condition.
    return result(relBuilder.build(), inputMapping);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RelOptUtil(org.apache.calcite.plan.RelOptUtil) RelDataType(org.apache.calcite.rel.type.RelDataType) Mapping(org.apache.calcite.util.mapping.Mapping) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexPermuteInputsShuttle(org.apache.calcite.rex.RexPermuteInputsShuttle) RexNode(org.apache.calcite.rex.RexNode)

Example 72 with RelDataTypeField

use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class RelFieldTrimmer method trimFields.

/**
 * Variant of {@link #trimFields(RelNode, ImmutableBitSet, Set)} for
 * {@link org.apache.calcite.rel.core.Sort}.
 */
public TrimResult trimFields(Sort sort, ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final RelDataType rowType = sort.getRowType();
    final int fieldCount = rowType.getFieldCount();
    final RelCollation collation = sort.getCollation();
    final RelNode input = sort.getInput();
    // We use the fields used by the consumer, plus any fields used as sort
    // keys.
    final ImmutableBitSet.Builder inputFieldsUsed = fieldsUsed.rebuild();
    for (RelFieldCollation field : collation.getFieldCollations()) {
        inputFieldsUsed.set(field.getFieldIndex());
    }
    // Create input with trimmed columns.
    final Set<RelDataTypeField> inputExtraFields = Collections.emptySet();
    TrimResult trimResult = trimChild(sort, input, inputFieldsUsed.build(), inputExtraFields);
    RelNode newInput = trimResult.left;
    final Mapping inputMapping = trimResult.right;
    // there's nothing we can do.
    if (newInput == input && inputMapping.isIdentity() && fieldsUsed.cardinality() == fieldCount) {
        return result(sort, Mappings.createIdentity(fieldCount));
    }
    // leave the Sort unchanged in case we have dynamic limits
    if (sort.offset instanceof RexDynamicParam || sort.fetch instanceof RexDynamicParam) {
        return result(sort, inputMapping);
    }
    relBuilder.push(newInput);
    final int offset = sort.offset == null ? 0 : RexLiteral.intValue(sort.offset);
    final int fetch = sort.fetch == null ? -1 : RexLiteral.intValue(sort.fetch);
    final ImmutableList<RexNode> fields = relBuilder.fields(RexUtil.apply(inputMapping, collation));
    relBuilder.sortLimit(offset, fetch, fields);
    // needs them for its condition.
    return result(relBuilder.build(), inputMapping);
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RelDataType(org.apache.calcite.rel.type.RelDataType) Mapping(org.apache.calcite.util.mapping.Mapping) RelCollation(org.apache.calcite.rel.RelCollation) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RexDynamicParam(org.apache.calcite.rex.RexDynamicParam) RexNode(org.apache.calcite.rex.RexNode)

Example 73 with RelDataTypeField

use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class RelStructuredTypeFlattener method calculateFlattenedOffset.

private int calculateFlattenedOffset(RelDataType rowType, int ordinal) {
    int offset = 0;
    if (SqlTypeUtil.needsNullIndicator(rowType)) {
        // skip null indicator
        ++offset;
    }
    List<RelDataTypeField> oldFields = rowType.getFieldList();
    for (int i = 0; i < ordinal; ++i) {
        RelDataType oldFieldType = oldFields.get(i).getType();
        if (oldFieldType.isStruct()) {
            // TODO jvs 10-Feb-2005:  this isn't terribly efficient;
            // keep a mapping somewhere
            RelDataType flattened = SqlTypeUtil.flattenRecordType(rexBuilder.getTypeFactory(), oldFieldType, null);
            final List<RelDataTypeField> fields = flattened.getFieldList();
            offset += fields.size();
        } else {
            ++offset;
        }
    }
    return offset;
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 74 with RelDataTypeField

use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class RelStructuredTypeFlattener method flattenProjection.

private void flattenProjection(RewriteRexShuttle shuttle, RexNode exp, String fieldName, List<Pair<RexNode, String>> flattenedExps) {
    if (exp.getType().isStruct()) {
        if (exp instanceof RexInputRef) {
            RexInputRef inputRef = (RexInputRef) exp;
            int newOffset = getNewForOldInput(inputRef.getIndex());
            // expand to range
            RelDataType flattenedType = SqlTypeUtil.flattenRecordType(rexBuilder.getTypeFactory(), exp.getType(), null);
            List<RelDataTypeField> fieldList = flattenedType.getFieldList();
            int n = fieldList.size();
            for (int j = 0; j < n; ++j) {
                RelDataTypeField field = fieldList.get(j);
                flattenedExps.add(Pair.<RexNode, String>of(new RexInputRef(newOffset + j, field.getType()), fieldName));
            }
        } else if (isConstructor(exp) || exp.isA(SqlKind.CAST)) {
            // REVIEW jvs 27-Feb-2005:  for cast, see corresponding note
            // in RewriteRexShuttle
            RexCall call = (RexCall) exp;
            if (exp.isA(SqlKind.NEW_SPECIFICATION)) {
                // For object constructors, prepend a FALSE null
                // indicator.
                flattenedExps.add(Pair.<RexNode, String>of(rexBuilder.makeLiteral(false), fieldName));
            } else if (exp.isA(SqlKind.CAST)) {
                if (RexLiteral.isNullLiteral(((RexCall) exp).operands.get(0))) {
                    // Translate CAST(NULL AS UDT) into
                    // the correct number of null fields.
                    flattenNullLiteral(exp.getType(), flattenedExps);
                    return;
                }
            }
            flattenProjections(new RewriteRexShuttle(), call.getOperands(), Collections.<String>nCopies(call.getOperands().size(), null), fieldName, flattenedExps);
        } else if (exp instanceof RexCall) {
            // NOTE jvs 10-Feb-2005:  This is a lame hack to keep special
            // functions which return row types working.
            int j = 0;
            RexNode newExp = exp;
            List<RexNode> oldOperands = ((RexCall) exp).getOperands();
            if (oldOperands.get(0) instanceof RexInputRef) {
                RexInputRef inputRef = (RexInputRef) oldOperands.get(0);
                int newOffset = getNewForOldInput(inputRef.getIndex());
                newExp = rexBuilder.makeCall(exp.getType(), ((RexCall) exp).getOperator(), ImmutableList.of(rexBuilder.makeInputRef(inputRef.getType(), newOffset), oldOperands.get(1)));
            }
            for (RelDataTypeField field : newExp.getType().getFieldList()) {
                flattenedExps.add(Pair.of(rexBuilder.makeFieldAccess(newExp, field.getIndex()), fieldName + "$" + (j++)));
            }
        } else {
            throw Util.needToImplement(exp);
        }
    } else {
        flattenedExps.add(Pair.of(exp.accept(shuttle), fieldName));
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RexInputRef(org.apache.calcite.rex.RexInputRef) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Example 75 with RelDataTypeField

use of org.apache.calcite.rel.type.RelDataTypeField in project calcite by apache.

the class SqlValidatorUtil method analyzeGroupExpr.

/**
 * Analyzes a component of a tuple in a GROUPING SETS clause.
 */
private static ImmutableBitSet analyzeGroupExpr(SqlValidatorScope scope, GroupAnalyzer groupAnalyzer, SqlNode groupExpr) {
    final SqlNode expandedGroupExpr = scope.getValidator().expand(groupExpr, scope);
    switch(expandedGroupExpr.getKind()) {
        case ROW:
            return ImmutableBitSet.union(analyzeGroupTuple(scope, groupAnalyzer, ((SqlCall) expandedGroupExpr).getOperandList()));
        case OTHER:
            if (expandedGroupExpr instanceof SqlNodeList && ((SqlNodeList) expandedGroupExpr).size() == 0) {
                return ImmutableBitSet.of();
            }
    }
    final int ref = lookupGroupExpr(groupAnalyzer, groupExpr);
    if (expandedGroupExpr instanceof SqlIdentifier) {
        // SQL 2003 does not allow expressions of column references
        SqlIdentifier expr = (SqlIdentifier) expandedGroupExpr;
        // column references should be fully qualified.
        assert expr.names.size() == 2;
        String originalRelName = expr.names.get(0);
        String originalFieldName = expr.names.get(1);
        final SqlNameMatcher nameMatcher = scope.getValidator().getCatalogReader().nameMatcher();
        final SqlValidatorScope.ResolvedImpl resolved = new SqlValidatorScope.ResolvedImpl();
        scope.resolve(ImmutableList.of(originalRelName), nameMatcher, false, resolved);
        assert resolved.count() == 1;
        final SqlValidatorScope.Resolve resolve = resolved.only();
        final RelDataType rowType = resolve.rowType();
        final int childNamespaceIndex = resolve.path.steps().get(0).i;
        int namespaceOffset = 0;
        if (childNamespaceIndex > 0) {
            // If not the first child, need to figure out the width of
            // output types from all the preceding namespaces
            final SqlValidatorScope ancestorScope = resolve.scope;
            assert ancestorScope instanceof ListScope;
            List<SqlValidatorNamespace> children = ((ListScope) ancestorScope).getChildren();
            for (int j = 0; j < childNamespaceIndex; j++) {
                namespaceOffset += children.get(j).getRowType().getFieldCount();
            }
        }
        RelDataTypeField field = nameMatcher.field(rowType, originalFieldName);
        int origPos = namespaceOffset + field.getIndex();
        groupAnalyzer.groupExprProjection.put(origPos, ref);
    }
    return ImmutableBitSet.of(ref);
}
Also used : SqlCall(org.apache.calcite.sql.SqlCall) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)388 RelDataType (org.apache.calcite.rel.type.RelDataType)210 RexNode (org.apache.calcite.rex.RexNode)185 ArrayList (java.util.ArrayList)175 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)26 List (java.util.List)23 LinkedHashSet (java.util.LinkedHashSet)22 RelOptUtil (org.apache.calcite.plan.RelOptUtil)22