Search in sources :

Example 46 with RelNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode in project calcite by apache.

the class RelMdColumnOrigins method getColumnOrigins.

public Set<RelColumnOrigin> getColumnOrigins(TableFunctionScan rel, RelMetadataQuery mq, int iOutputColumn) {
    final Set<RelColumnOrigin> set = new HashSet<>();
    Set<RelColumnMapping> mappings = rel.getColumnMappings();
    if (mappings == null) {
        if (rel.getInputs().size() > 0) {
            // columns below.
            return null;
        } else {
            // column origins.
            return set;
        }
    }
    for (RelColumnMapping mapping : mappings) {
        if (mapping.iOutputColumn != iOutputColumn) {
            continue;
        }
        final RelNode input = rel.getInputs().get(mapping.iInputRel);
        final int column = mapping.iInputColumn;
        Set<RelColumnOrigin> origins = mq.getColumnOrigins(input, column);
        if (origins == null) {
            return null;
        }
        if (mapping.derived) {
            origins = createDerivedColumnOrigins(origins);
        }
        set.addAll(origins);
    }
    return set;
}
Also used : RelNode(org.apache.calcite.rel.RelNode) HashSet(java.util.HashSet)

Example 47 with RelNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode in project calcite by apache.

the class RelMdColumnUniqueness method areColumnsUnique.

public Boolean areColumnsUnique(Join rel, RelMetadataQuery mq, ImmutableBitSet columns, boolean ignoreNulls) {
    if (columns.cardinality() == 0) {
        return false;
    }
    final RelNode left = rel.getLeft();
    final RelNode right = rel.getRight();
    // Divide up the input column mask into column masks for the left and
    // right sides of the join
    final Pair<ImmutableBitSet, ImmutableBitSet> leftAndRightColumns = splitLeftAndRightColumns(rel.getLeft().getRowType().getFieldCount(), columns);
    final ImmutableBitSet leftColumns = leftAndRightColumns.left;
    final ImmutableBitSet rightColumns = leftAndRightColumns.right;
    // If the original column mask contains columns from both the left and
    // right hand side, then the columns are unique if and only if they're
    // unique for their respective join inputs
    Boolean leftUnique = mq.areColumnsUnique(left, leftColumns, ignoreNulls);
    Boolean rightUnique = mq.areColumnsUnique(right, rightColumns, ignoreNulls);
    if ((leftColumns.cardinality() > 0) && (rightColumns.cardinality() > 0)) {
        if ((leftUnique == null) || (rightUnique == null)) {
            return null;
        } else {
            return leftUnique && rightUnique;
        }
    }
    // If we're only trying to determine uniqueness for columns that
    // originate from one join input, then determine if the equijoin
    // columns from the other join input are unique.  If they are, then
    // the columns are unique for the entire join if they're unique for
    // the corresponding join input, provided that input is not null
    // generating.
    final JoinInfo joinInfo = rel.analyzeCondition();
    if (leftColumns.cardinality() > 0) {
        if (rel.getJoinType().generatesNullsOnLeft()) {
            return false;
        }
        Boolean rightJoinColsUnique = mq.areColumnsUnique(right, joinInfo.rightSet(), ignoreNulls);
        if ((rightJoinColsUnique == null) || (leftUnique == null)) {
            return null;
        }
        return rightJoinColsUnique && leftUnique;
    } else if (rightColumns.cardinality() > 0) {
        if (rel.getJoinType().generatesNullsOnRight()) {
            return false;
        }
        Boolean leftJoinColsUnique = mq.areColumnsUnique(left, joinInfo.leftSet(), ignoreNulls);
        if ((leftJoinColsUnique == null) || (rightUnique == null)) {
            return null;
        }
        return leftJoinColsUnique && rightUnique;
    }
    throw new AssertionError();
}
Also used : JoinInfo(org.apache.calcite.rel.core.JoinInfo) RelNode(org.apache.calcite.rel.RelNode) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet)

Example 48 with RelNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode in project calcite by apache.

the class RelMdDistinctRowCount method getDistinctRowCount.

public Double getDistinctRowCount(Union rel, RelMetadataQuery mq, ImmutableBitSet groupKey, RexNode predicate) {
    Double rowCount = 0.0;
    int[] adjustments = new int[rel.getRowType().getFieldCount()];
    RexBuilder rexBuilder = rel.getCluster().getRexBuilder();
    for (RelNode input : rel.getInputs()) {
        // convert the predicate to reference the types of the union child
        RexNode modifiedPred;
        if (predicate == null) {
            modifiedPred = null;
        } else {
            modifiedPred = predicate.accept(new RelOptUtil.RexInputConverter(rexBuilder, null, input.getRowType().getFieldList(), adjustments));
        }
        Double partialRowCount = mq.getDistinctRowCount(input, groupKey, modifiedPred);
        if (partialRowCount == null) {
            return null;
        }
        rowCount += partialRowCount;
    }
    return rowCount;
}
Also used : RelNode(org.apache.calcite.rel.RelNode) RexBuilder(org.apache.calcite.rex.RexBuilder) RexNode(org.apache.calcite.rex.RexNode)

Example 49 with RelNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode 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 50 with RelNode

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode 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)

Aggregations

RelNode (org.apache.calcite.rel.RelNode)1133 RexNode (org.apache.calcite.rex.RexNode)353 ArrayList (java.util.ArrayList)273 Test (org.junit.Test)239 RelBuilder (org.apache.calcite.tools.RelBuilder)161 RelDataType (org.apache.calcite.rel.type.RelDataType)156 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)142 RexBuilder (org.apache.calcite.rex.RexBuilder)129 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)121 RelTraitSet (org.apache.calcite.plan.RelTraitSet)114 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)97 RexInputRef (org.apache.calcite.rex.RexInputRef)85 HashMap (java.util.HashMap)82 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)77 Project (org.apache.calcite.rel.core.Project)74 RelOptCluster (org.apache.calcite.plan.RelOptCluster)71 List (java.util.List)67 Pair (org.apache.calcite.util.Pair)67 AggregateCall (org.apache.calcite.rel.core.AggregateCall)63 SqlNode (org.apache.calcite.sql.SqlNode)61