Search in sources :

Example 16 with RexInputRef

use of org.apache.calcite.rex.RexInputRef in project calcite by apache.

the class RelMdColumnUniqueness method simplyProjects.

private boolean simplyProjects(RelNode rel, ImmutableBitSet columns) {
    if (!(rel instanceof Project)) {
        return false;
    }
    Project project = (Project) rel;
    final List<RexNode> projects = project.getProjects();
    for (int column : columns) {
        if (column >= projects.size()) {
            return false;
        }
        if (!(projects.get(column) instanceof RexInputRef)) {
            return false;
        }
        final RexInputRef ref = (RexInputRef) projects.get(column);
        if (ref.getIndex() != column) {
            return false;
        }
    }
    return true;
}
Also used : Project(org.apache.calcite.rel.core.Project) RexInputRef(org.apache.calcite.rex.RexInputRef) RexNode(org.apache.calcite.rex.RexNode)

Example 17 with RexInputRef

use of org.apache.calcite.rex.RexInputRef in project calcite by apache.

the class RelMdColumnUniqueness method areColumnsUnique.

public Boolean areColumnsUnique(Project rel, RelMetadataQuery mq, ImmutableBitSet columns, boolean ignoreNulls) {
    // LogicalProject maps a set of rows to a different set;
    // Without knowledge of the mapping function(whether it
    // preserves uniqueness), it is only safe to derive uniqueness
    // info from the child of a project when the mapping is f(a) => a.
    // 
    // Also need to map the input column set to the corresponding child
    // references
    List<RexNode> projExprs = rel.getProjects();
    ImmutableBitSet.Builder childColumns = ImmutableBitSet.builder();
    for (int bit : columns) {
        RexNode projExpr = projExprs.get(bit);
        if (projExpr instanceof RexInputRef) {
            childColumns.set(((RexInputRef) projExpr).getIndex());
        } else if (projExpr instanceof RexCall && ignoreNulls) {
            // If the expression is a cast such that the types are the same
            // except for the nullability, then if we're ignoring nulls,
            // it doesn't matter whether the underlying column reference
            // is nullable.  Check that the types are the same by making a
            // nullable copy of both types and then comparing them.
            RexCall call = (RexCall) projExpr;
            if (call.getOperator() != SqlStdOperatorTable.CAST) {
                continue;
            }
            RexNode castOperand = call.getOperands().get(0);
            if (!(castOperand instanceof RexInputRef)) {
                continue;
            }
            RelDataTypeFactory typeFactory = rel.getCluster().getTypeFactory();
            RelDataType castType = typeFactory.createTypeWithNullability(projExpr.getType(), true);
            RelDataType origType = typeFactory.createTypeWithNullability(castOperand.getType(), true);
            if (castType.equals(origType)) {
                childColumns.set(((RexInputRef) castOperand).getIndex());
            }
        } else {
            // projection, then skip it.
            continue;
        }
    }
    // If no columns can affect uniqueness, then return unknown
    if (childColumns.cardinality() == 0) {
        return null;
    }
    return mq.areColumnsUnique(rel.getInput(), childColumns.build(), ignoreNulls);
}
Also used : RexCall(org.apache.calcite.rex.RexCall) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RexInputRef(org.apache.calcite.rex.RexInputRef) RelDataType(org.apache.calcite.rel.type.RelDataType) RexNode(org.apache.calcite.rex.RexNode)

Example 18 with RexInputRef

use of org.apache.calcite.rex.RexInputRef in project calcite by apache.

the class RelMdExpressionLineage method getExpressionLineage.

/**
 * Expression lineage from {@link Join}.
 *
 * <p>We only extract the lineage for INNER joins.
 */
public Set<RexNode> getExpressionLineage(Join rel, RelMetadataQuery mq, RexNode outputExpression) {
    if (rel.getJoinType() != JoinRelType.INNER) {
        // We cannot map origin of this expression.
        return null;
    }
    final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
    final RelNode leftInput = rel.getLeft();
    final RelNode rightInput = rel.getRight();
    final int nLeftColumns = leftInput.getRowType().getFieldList().size();
    // Infer column origin expressions for given references
    final Multimap<List<String>, RelTableRef> qualifiedNamesToRefs = HashMultimap.create();
    final Map<RelTableRef, RelTableRef> currentTablesMapping = new HashMap<>();
    final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
    for (int idx = 0; idx < rel.getRowType().getFieldList().size(); idx++) {
        if (idx < nLeftColumns) {
            final RexInputRef inputRef = RexInputRef.of(idx, leftInput.getRowType().getFieldList());
            final Set<RexNode> originalExprs = mq.getExpressionLineage(leftInput, inputRef);
            if (originalExprs == null) {
                // Bail out
                return null;
            }
            // Gather table references, left input references remain unchanged
            final Set<RelTableRef> tableRefs = RexUtil.gatherTableReferences(Lists.newArrayList(originalExprs));
            for (RelTableRef leftRef : tableRefs) {
                qualifiedNamesToRefs.put(leftRef.getQualifiedName(), leftRef);
            }
            mapping.put(RexInputRef.of(idx, rel.getRowType().getFieldList()), originalExprs);
        } else {
            // Right input.
            final RexInputRef inputRef = RexInputRef.of(idx - nLeftColumns, rightInput.getRowType().getFieldList());
            final Set<RexNode> originalExprs = mq.getExpressionLineage(rightInput, inputRef);
            if (originalExprs == null) {
                // Bail out
                return null;
            }
            // Gather table references, right input references might need to be
            // updated if there are table names clashes with left input
            final Set<RelTableRef> tableRefs = RexUtil.gatherTableReferences(Lists.newArrayList(originalExprs));
            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 Set<RexNode> updatedExprs = Sets.newHashSet(Iterables.transform(originalExprs, new Function<RexNode, RexNode>() {

                @Override
                public RexNode apply(RexNode e) {
                    return RexUtil.swapTableReferences(rexBuilder, e, currentTablesMapping);
                }
            }));
            mapping.put(RexInputRef.of(idx, rel.getRowType().getFieldList()), updatedExprs);
        }
    }
    // Return result
    return createAllPossibleExpressions(rexBuilder, outputExpression, mapping);
}
Also used : HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) Set(java.util.Set) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) RelTableRef(org.apache.calcite.rex.RexTableInputRef.RelTableRef) LinkedHashMap(java.util.LinkedHashMap) Function(com.google.common.base.Function) RelNode(org.apache.calcite.rel.RelNode) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) ArrayList(java.util.ArrayList) List(java.util.List) RexNode(org.apache.calcite.rex.RexNode)

Example 19 with RexInputRef

use of org.apache.calcite.rex.RexInputRef in project calcite by apache.

the class RelMdExpressionLineage method getExpressionLineage.

/**
 * Expression lineage from {@link Union}.
 *
 * <p>For Union operator, we might be able to extract multiple origins for the
 * references in the given expression.
 */
public Set<RexNode> getExpressionLineage(Union rel, RelMetadataQuery mq, RexNode outputExpression) {
    final RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
    // Infer column origin expressions for given references
    final Multimap<List<String>, RelTableRef> qualifiedNamesToRefs = HashMultimap.create();
    final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
    for (RelNode input : rel.getInputs()) {
        final Map<RelTableRef, RelTableRef> currentTablesMapping = new HashMap<>();
        for (int idx = 0; idx < input.getRowType().getFieldList().size(); idx++) {
            final RexInputRef inputRef = RexInputRef.of(idx, input.getRowType().getFieldList());
            final Set<RexNode> originalExprs = mq.getExpressionLineage(input, inputRef);
            if (originalExprs == null) {
                // Bail out
                return null;
            }
            final RexInputRef ref = RexInputRef.of(idx, rel.getRowType().getFieldList());
            // Gather table references, references might need to be
            // updated
            final Set<RelTableRef> tableRefs = RexUtil.gatherTableReferences(Lists.newArrayList(originalExprs));
            for (RelTableRef tableRef : tableRefs) {
                int shift = 0;
                Collection<RelTableRef> lRefs = qualifiedNamesToRefs.get(tableRef.getQualifiedName());
                if (lRefs != null) {
                    shift = lRefs.size();
                }
                currentTablesMapping.put(tableRef, RelTableRef.of(tableRef.getTable(), shift + tableRef.getEntityNumber()));
            }
            final Set<RexNode> updatedExprs = Sets.newHashSet(Iterables.transform(originalExprs, new Function<RexNode, RexNode>() {

                @Override
                public RexNode apply(RexNode e) {
                    return RexUtil.swapTableReferences(rexBuilder, e, currentTablesMapping);
                }
            }));
            final Set<RexNode> set = mapping.get(ref);
            if (set != null) {
                set.addAll(updatedExprs);
            } else {
                mapping.put(ref, updatedExprs);
            }
        }
        // Add to existing qualified names
        for (RelTableRef newRef : currentTablesMapping.values()) {
            qualifiedNamesToRefs.put(newRef.getQualifiedName(), newRef);
        }
    }
    // Return result
    return createAllPossibleExpressions(rexBuilder, outputExpression, mapping);
}
Also used : HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) Set(java.util.Set) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) RelTableRef(org.apache.calcite.rex.RexTableInputRef.RelTableRef) LinkedHashMap(java.util.LinkedHashMap) Function(com.google.common.base.Function) RelNode(org.apache.calcite.rel.RelNode) RexBuilder(org.apache.calcite.rex.RexBuilder) RexInputRef(org.apache.calcite.rex.RexInputRef) ArrayList(java.util.ArrayList) List(java.util.List) RexNode(org.apache.calcite.rex.RexNode)

Example 20 with RexInputRef

use of org.apache.calcite.rex.RexInputRef in project calcite by apache.

the class LogicalWindow method toInputRefs.

private static List<RexNode> toInputRefs(final List<? extends RexNode> operands) {
    return new AbstractList<RexNode>() {

        public int size() {
            return operands.size();
        }

        public RexNode get(int index) {
            final RexNode operand = operands.get(index);
            if (operand instanceof RexInputRef) {
                return operand;
            }
            assert operand instanceof RexLocalRef;
            final RexLocalRef ref = (RexLocalRef) operand;
            return new RexInputRef(ref.getIndex(), ref.getType());
        }
    };
}
Also used : AbstractList(java.util.AbstractList) RexInputRef(org.apache.calcite.rex.RexInputRef) RexLocalRef(org.apache.calcite.rex.RexLocalRef) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RexInputRef (org.apache.calcite.rex.RexInputRef)241 RexNode (org.apache.calcite.rex.RexNode)200 ArrayList (java.util.ArrayList)103 RelNode (org.apache.calcite.rel.RelNode)85 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)80 RexCall (org.apache.calcite.rex.RexCall)67 RelDataType (org.apache.calcite.rel.type.RelDataType)63 RexBuilder (org.apache.calcite.rex.RexBuilder)54 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)52 HashMap (java.util.HashMap)47 AggregateCall (org.apache.calcite.rel.core.AggregateCall)36 List (java.util.List)35 HashSet (java.util.HashSet)32 Pair (org.apache.calcite.util.Pair)32 RexLiteral (org.apache.calcite.rex.RexLiteral)29 Map (java.util.Map)24 RelOptUtil (org.apache.calcite.plan.RelOptUtil)24 Set (java.util.Set)20 ImmutableList (com.google.common.collect.ImmutableList)19 LinkedHashMap (java.util.LinkedHashMap)19