Search in sources :

Example 36 with Mapping

use of org.apache.calcite.util.mapping.Mapping in project calcite by apache.

the class RelFieldTrimmer method trimFields.

/**
 * Variant of {@link #trimFields(RelNode, ImmutableBitSet, Set)} for
 * {@link org.apache.calcite.rel.logical.LogicalValues}.
 */
public TrimResult trimFields(LogicalValues values, ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final RelDataType rowType = values.getRowType();
    final int fieldCount = rowType.getFieldCount();
    // which is unlikely to be a system field.
    if (fieldsUsed.isEmpty()) {
        fieldsUsed = ImmutableBitSet.range(fieldCount - 1, fieldCount);
    }
    // If all fields are used, return unchanged.
    if (fieldsUsed.equals(ImmutableBitSet.range(fieldCount))) {
        Mapping mapping = Mappings.createIdentity(fieldCount);
        return result(values, mapping);
    }
    final ImmutableList.Builder<ImmutableList<RexLiteral>> newTuples = ImmutableList.builder();
    for (ImmutableList<RexLiteral> tuple : values.getTuples()) {
        ImmutableList.Builder<RexLiteral> newTuple = ImmutableList.builder();
        for (int field : fieldsUsed) {
            newTuple.add(tuple.get(field));
        }
        newTuples.add(newTuple.build());
    }
    final Mapping mapping = createMapping(fieldsUsed, fieldCount);
    final RelDataType newRowType = RelOptUtil.permute(values.getCluster().getTypeFactory(), rowType, mapping);
    final LogicalValues newValues = LogicalValues.create(values.getCluster(), newRowType, newTuples.build());
    return result(newValues, mapping);
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) ImmutableList(com.google.common.collect.ImmutableList) RelDataType(org.apache.calcite.rel.type.RelDataType) Mapping(org.apache.calcite.util.mapping.Mapping) LogicalValues(org.apache.calcite.rel.logical.LogicalValues)

Example 37 with Mapping

use of org.apache.calcite.util.mapping.Mapping in project calcite by apache.

the class RelFieldTrimmer method trimFields.

/**
 * Variant of {@link #trimFields(RelNode, ImmutableBitSet, Set)} for
 * {@link org.apache.calcite.rel.logical.LogicalTableFunctionScan}.
 */
public TrimResult trimFields(LogicalTableFunctionScan tabFun, ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final RelDataType rowType = tabFun.getRowType();
    final int fieldCount = rowType.getFieldCount();
    final List<RelNode> newInputs = new ArrayList<>();
    for (RelNode input : tabFun.getInputs()) {
        final int inputFieldCount = input.getRowType().getFieldCount();
        ImmutableBitSet inputFieldsUsed = ImmutableBitSet.range(inputFieldCount);
        // Create input with trimmed columns.
        final Set<RelDataTypeField> inputExtraFields = Collections.emptySet();
        TrimResult trimResult = trimChildRestore(tabFun, input, inputFieldsUsed, inputExtraFields);
        assert trimResult.right.isIdentity();
        newInputs.add(trimResult.left);
    }
    LogicalTableFunctionScan newTabFun = tabFun;
    if (!tabFun.getInputs().equals(newInputs)) {
        newTabFun = tabFun.copy(tabFun.getTraitSet(), newInputs, tabFun.getCall(), tabFun.getElementType(), tabFun.getRowType(), tabFun.getColumnMappings());
    }
    assert newTabFun.getClass() == tabFun.getClass();
    // Always project all fields.
    Mapping mapping = Mappings.createIdentity(fieldCount);
    return result(newTabFun, mapping);
}
Also used : LogicalTableFunctionScan(org.apache.calcite.rel.logical.LogicalTableFunctionScan) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) Mapping(org.apache.calcite.util.mapping.Mapping)

Example 38 with Mapping

use of org.apache.calcite.util.mapping.Mapping in project calcite by apache.

the class RelFieldTrimmer method trimFields.

/**
 * Variant of {@link #trimFields(RelNode, ImmutableBitSet, Set)} for
 * {@link org.apache.calcite.rel.core.SetOp} (including UNION and UNION ALL).
 */
public TrimResult trimFields(SetOp setOp, ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final RelDataType rowType = setOp.getRowType();
    final int fieldCount = rowType.getFieldCount();
    int changeCount = 0;
    // system field.)
    if (fieldsUsed.isEmpty()) {
        fieldsUsed = ImmutableBitSet.of(rowType.getFieldCount() - 1);
    }
    // Compute the desired field mapping. Give the consumer the fields they
    // want, in the order that they appear in the bitset.
    final Mapping mapping = createMapping(fieldsUsed, fieldCount);
    // Create input with trimmed columns.
    for (RelNode input : setOp.getInputs()) {
        TrimResult trimResult = trimChild(setOp, input, fieldsUsed, extraFields);
        // We want "mapping", the input gave us "inputMapping", compute
        // "remaining" mapping.
        // |                   |                |
        // |---------------- mapping ---------->|
        // |-- inputMapping -->|                |
        // |                   |-- remaining -->|
        // 
        // For instance, suppose we have columns [a, b, c, d],
        // the consumer asked for mapping = [b, d],
        // and the transformed input has columns inputMapping = [d, a, b].
        // remaining will permute [b, d] to [d, a, b].
        Mapping remaining = Mappings.divide(mapping, trimResult.right);
        // Create a projection; does nothing if remaining is identity.
        relBuilder.push(trimResult.left);
        relBuilder.permute(remaining);
        if (input != relBuilder.peek()) {
            ++changeCount;
        }
    }
    // there's to do.
    if (changeCount == 0 && mapping.isIdentity()) {
        for (RelNode input : setOp.getInputs()) {
            relBuilder.build();
        }
        return result(setOp, mapping);
    }
    switch(setOp.kind) {
        case UNION:
            relBuilder.union(setOp.all, setOp.getInputs().size());
            break;
        case INTERSECT:
            relBuilder.intersect(setOp.all, setOp.getInputs().size());
            break;
        case EXCEPT:
            assert setOp.getInputs().size() == 2;
            relBuilder.minus(setOp.all);
            break;
        default:
            throw new AssertionError("unknown setOp " + setOp);
    }
    return result(relBuilder.build(), mapping);
}
Also used : RelNode(org.apache.calcite.rel.RelNode) RelDataType(org.apache.calcite.rel.type.RelDataType) Mapping(org.apache.calcite.util.mapping.Mapping)

Example 39 with Mapping

use of org.apache.calcite.util.mapping.Mapping in project calcite by apache.

the class RelFieldTrimmer method trimFields.

/**
 * Variant of {@link #trimFields(RelNode, ImmutableBitSet, Set)} for
 * {@link org.apache.calcite.rel.logical.LogicalTableModify}.
 */
public TrimResult trimFields(LogicalTableModify modifier, ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    // Ignore what consumer wants. We always project all columns.
    Util.discard(fieldsUsed);
    final RelDataType rowType = modifier.getRowType();
    final int fieldCount = rowType.getFieldCount();
    RelNode input = modifier.getInput();
    // We want all fields from the child.
    final int inputFieldCount = input.getRowType().getFieldCount();
    final ImmutableBitSet inputFieldsUsed = ImmutableBitSet.range(inputFieldCount);
    // Create input with trimmed columns.
    final Set<RelDataTypeField> inputExtraFields = Collections.emptySet();
    TrimResult trimResult = trimChild(modifier, input, inputFieldsUsed, inputExtraFields);
    RelNode newInput = trimResult.left;
    final Mapping inputMapping = trimResult.right;
    if (!inputMapping.isIdentity()) {
        // to permute them!
        throw new AssertionError("Expected identity mapping, got " + inputMapping);
    }
    LogicalTableModify newModifier = modifier;
    if (newInput != input) {
        newModifier = modifier.copy(modifier.getTraitSet(), Collections.singletonList(newInput));
    }
    assert newModifier.getClass() == modifier.getClass();
    // Always project all fields.
    Mapping mapping = Mappings.createIdentity(fieldCount);
    return result(newModifier, mapping);
}
Also used : RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) LogicalTableModify(org.apache.calcite.rel.logical.LogicalTableModify) RelDataType(org.apache.calcite.rel.type.RelDataType) Mapping(org.apache.calcite.util.mapping.Mapping)

Example 40 with Mapping

use of org.apache.calcite.util.mapping.Mapping in project calcite by apache.

the class RelFieldTrimmer method dispatchTrimFields.

/**
 * Invokes {@link #trimFields}, or the appropriate method for the type
 * of the rel parameter, using multi-method dispatch.
 *
 * @param rel        Relational expression
 * @param fieldsUsed Bitmap of fields needed by the consumer
 * @return New relational expression and its field mapping
 */
protected final TrimResult dispatchTrimFields(RelNode rel, ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
    final TrimResult trimResult = trimFieldsDispatcher.invoke(rel, fieldsUsed, extraFields);
    final RelNode newRel = trimResult.left;
    final Mapping mapping = trimResult.right;
    final int fieldCount = rel.getRowType().getFieldCount();
    assert mapping.getSourceCount() == fieldCount : "source: " + mapping.getSourceCount() + " != " + fieldCount;
    final int newFieldCount = newRel.getRowType().getFieldCount();
    assert mapping.getTargetCount() + extraFields.size() == newFieldCount || Bug.TODO_FIXED : "target: " + mapping.getTargetCount() + " + " + extraFields.size() + " != " + newFieldCount;
    if (Bug.TODO_FIXED) {
        assert newFieldCount > 0 : "rel has no fields after trim: " + rel;
    }
    if (newRel.equals(rel)) {
        return result(rel, mapping);
    }
    return trimResult;
}
Also used : RelNode(org.apache.calcite.rel.RelNode) Mapping(org.apache.calcite.util.mapping.Mapping)

Aggregations

Mapping (org.apache.calcite.util.mapping.Mapping)44 RelNode (org.apache.calcite.rel.RelNode)36 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)29 RelDataType (org.apache.calcite.rel.type.RelDataType)26 RexNode (org.apache.calcite.rex.RexNode)25 ArrayList (java.util.ArrayList)22 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)20 RelBuilder (org.apache.calcite.tools.RelBuilder)15 RexPermuteInputsShuttle (org.apache.calcite.rex.RexPermuteInputsShuttle)13 RexBuilder (org.apache.calcite.rex.RexBuilder)11 RelOptUtil (org.apache.calcite.plan.RelOptUtil)9 LinkedHashSet (java.util.LinkedHashSet)8 AggregateCall (org.apache.calcite.rel.core.AggregateCall)8 Aggregate (org.apache.calcite.rel.core.Aggregate)6 Join (org.apache.calcite.rel.core.Join)6 RexInputRef (org.apache.calcite.rex.RexInputRef)6 RexLiteral (org.apache.calcite.rex.RexLiteral)6 Mappings (org.apache.calcite.util.mapping.Mappings)6 ImmutableList (com.google.common.collect.ImmutableList)5 HashMap (java.util.HashMap)5