Search in sources :

Example 6 with RelOptTable

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.RelOptTable in project calcite by apache.

the class LoptOptimizeJoinRule method findRemovableSelfJoins.

/**
 * Locates pairs of joins that are self-joins where the join can be removed
 * because the join condition between the two factors is an equality join on
 * unique keys.
 *
 * @param multiJoin join factors being optimized
 */
private void findRemovableSelfJoins(RelMetadataQuery mq, LoptMultiJoin multiJoin) {
    // Candidates for self-joins must be simple factors
    Map<Integer, RelOptTable> simpleFactors = getSimpleFactors(mq, multiJoin);
    // See if a simple factor is repeated and therefore potentially is
    // part of a self-join.  Restrict each factor to at most one
    // self-join.
    final List<RelOptTable> repeatedTables = new ArrayList<>();
    final TreeSet<Integer> sortedFactors = new TreeSet<>();
    sortedFactors.addAll(simpleFactors.keySet());
    final Map<Integer, Integer> selfJoinPairs = new HashMap<>();
    Integer[] factors = sortedFactors.toArray(new Integer[sortedFactors.size()]);
    for (int i = 0; i < factors.length; i++) {
        if (repeatedTables.contains(simpleFactors.get(factors[i]))) {
            continue;
        }
        for (int j = i + 1; j < factors.length; j++) {
            int leftFactor = factors[i];
            int rightFactor = factors[j];
            if (simpleFactors.get(leftFactor).getQualifiedName().equals(simpleFactors.get(rightFactor).getQualifiedName())) {
                selfJoinPairs.put(leftFactor, rightFactor);
                repeatedTables.add(simpleFactors.get(leftFactor));
                break;
            }
        }
    }
    // allow the join to be removed.
    for (Integer factor1 : selfJoinPairs.keySet()) {
        final int factor2 = selfJoinPairs.get(factor1);
        final List<RexNode> selfJoinFilters = new ArrayList<>();
        for (RexNode filter : multiJoin.getJoinFilters()) {
            ImmutableBitSet joinFactors = multiJoin.getFactorsRefByJoinFilter(filter);
            if ((joinFactors.cardinality() == 2) && joinFactors.get(factor1) && joinFactors.get(factor2)) {
                selfJoinFilters.add(filter);
            }
        }
        if ((selfJoinFilters.size() > 0) && isSelfJoinFilterUnique(mq, multiJoin, factor1, factor2, selfJoinFilters)) {
            multiJoin.addRemovableSelfJoinPair(factor1, factor2);
        }
    }
}
Also used : ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TreeSet(java.util.TreeSet) RelOptTable(org.apache.calcite.plan.RelOptTable) RexNode(org.apache.calcite.rex.RexNode)

Example 7 with RelOptTable

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.RelOptTable in project calcite by apache.

the class AggregateStarTableRule method apply.

protected void apply(RelOptRuleCall call, Project postProject, final Aggregate aggregate, StarTable.StarTableScan scan) {
    final RelOptCluster cluster = scan.getCluster();
    final RelOptTable table = scan.getTable();
    final RelOptLattice lattice = call.getPlanner().getLattice(table);
    final List<Lattice.Measure> measures = lattice.lattice.toMeasures(aggregate.getAggCallList());
    final Pair<CalciteSchema.TableEntry, TileKey> pair = lattice.getAggregate(call.getPlanner(), aggregate.getGroupSet(), measures);
    if (pair == null) {
        return;
    }
    final RelBuilder relBuilder = call.builder();
    final CalciteSchema.TableEntry tableEntry = pair.left;
    final TileKey tileKey = pair.right;
    final RelMetadataQuery mq = call.getMetadataQuery();
    final double rowCount = aggregate.estimateRowCount(mq);
    final Table aggregateTable = tableEntry.getTable();
    final RelDataType aggregateTableRowType = aggregateTable.getRowType(cluster.getTypeFactory());
    final RelOptTable aggregateRelOptTable = RelOptTableImpl.create(table.getRelOptSchema(), aggregateTableRowType, tableEntry, rowCount);
    relBuilder.push(aggregateRelOptTable.toRel(RelOptUtil.getContext(cluster)));
    if (tileKey == null) {
        if (CalcitePrepareImpl.DEBUG) {
            System.out.println("Using materialization " + aggregateRelOptTable.getQualifiedName() + " (exact match)");
        }
    } else if (!tileKey.dimensions.equals(aggregate.getGroupSet())) {
        // Aggregate has finer granularity than we need. Roll up.
        if (CalcitePrepareImpl.DEBUG) {
            System.out.println("Using materialization " + aggregateRelOptTable.getQualifiedName() + ", rolling up " + tileKey.dimensions + " to " + aggregate.getGroupSet());
        }
        assert tileKey.dimensions.contains(aggregate.getGroupSet());
        final List<AggregateCall> aggCalls = Lists.newArrayList();
        ImmutableBitSet.Builder groupSet = ImmutableBitSet.builder();
        for (int key : aggregate.getGroupSet()) {
            groupSet.set(tileKey.dimensions.indexOf(key));
        }
        for (AggregateCall aggCall : aggregate.getAggCallList()) {
            final AggregateCall copy = rollUp(groupSet.cardinality(), relBuilder, aggCall, tileKey);
            if (copy == null) {
                return;
            }
            aggCalls.add(copy);
        }
        relBuilder.push(aggregate.copy(aggregate.getTraitSet(), relBuilder.build(), false, groupSet.build(), null, aggCalls));
    } else if (!tileKey.measures.equals(measures)) {
        if (CalcitePrepareImpl.DEBUG) {
            System.out.println("Using materialization " + aggregateRelOptTable.getQualifiedName() + ", right granularity, but different measures " + aggregate.getAggCallList());
        }
        relBuilder.project(relBuilder.fields(new AbstractSourceMapping(tileKey.dimensions.cardinality() + tileKey.measures.size(), aggregate.getRowType().getFieldCount()) {

            public int getSourceOpt(int source) {
                assert aggregate.getIndicatorCount() == 0;
                if (source < aggregate.getGroupCount()) {
                    int in = tileKey.dimensions.nth(source);
                    return aggregate.getGroupSet().indexOf(in);
                }
                Lattice.Measure measure = measures.get(source - aggregate.getGroupCount());
                int i = tileKey.measures.indexOf(measure);
                assert i >= 0;
                return tileKey.dimensions.cardinality() + i;
            }
        }.inverse()));
    }
    if (postProject != null) {
        relBuilder.push(postProject.copy(postProject.getTraitSet(), ImmutableList.of(relBuilder.peek())));
    }
    call.transformTo(relBuilder.build());
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RelBuilder(org.apache.calcite.tools.RelBuilder) RelOptTable(org.apache.calcite.plan.RelOptTable) Table(org.apache.calcite.schema.Table) StarTable(org.apache.calcite.schema.impl.StarTable) RelBuilder(org.apache.calcite.tools.RelBuilder) TileKey(org.apache.calcite.materialize.TileKey) RelDataType(org.apache.calcite.rel.type.RelDataType) AggregateCall(org.apache.calcite.rel.core.AggregateCall) AbstractSourceMapping(org.apache.calcite.util.mapping.AbstractSourceMapping) CalciteSchema(org.apache.calcite.jdbc.CalciteSchema) RelOptLattice(org.apache.calcite.plan.RelOptLattice) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) RelOptTable(org.apache.calcite.plan.RelOptTable)

Example 8 with RelOptTable

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.RelOptTable in project calcite by apache.

the class LoptSemiJoinOptimizer method validateKeys.

/**
 * Validates the candidate semijoin keys corresponding to the fact table.
 * Ensure the keys all originate from the same underlying table, and they
 * all correspond to simple column references. If unsuitable keys are found,
 * they're removed from the key list and a new list corresponding to the
 * remaining valid keys is returned.
 *
 * @param factRel fact table RelNode
 * @param leftKeys fact table semijoin keys
 * @param rightKeys dimension table semijoin keys
 * @param actualLeftKeys the remaining valid fact table semijoin keys
 *
 * @return the underlying fact table if the semijoin keys are valid;
 * otherwise null
 */
private LcsTable validateKeys(RelNode factRel, List<Integer> leftKeys, List<Integer> rightKeys, List<Integer> actualLeftKeys) {
    int keyIdx = 0;
    RelOptTable theTable = null;
    ListIterator<Integer> keyIter = leftKeys.listIterator();
    while (keyIter.hasNext()) {
        boolean removeKey = false;
        final RelColumnOrigin colOrigin = mq.getColumnOrigin(factRel, keyIter.next());
        // can't use the rid column as a semijoin key
        if ((colOrigin == null) || LucidDbSpecialOperators.isLcsRidColumnId(colOrigin.getOriginColumnOrdinal())) {
            removeKey = true;
        } else {
            RelOptTable table = colOrigin.getOriginTable();
            if (theTable == null) {
                if (!(table instanceof LcsTable)) {
                    // not a column store table
                    removeKey = true;
                } else {
                    theTable = table;
                }
            } else {
                // a simple origin
                assert table == theTable;
            }
        }
        if (!removeKey) {
            actualLeftKeys.add(colOrigin.getOriginColumnOrdinal());
            keyIdx++;
        } else {
            keyIter.remove();
            rightKeys.remove(keyIdx);
        }
    }
    // keys
    if (actualLeftKeys.isEmpty()) {
        return null;
    } else {
        return (LcsTable) theTable;
    }
}
Also used : RelColumnOrigin(org.apache.calcite.rel.metadata.RelColumnOrigin) RelOptTable(org.apache.calcite.plan.RelOptTable)

Example 9 with RelOptTable

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.RelOptTable in project calcite by apache.

the class SqlValidatorImpl method validateInsert.

public void validateInsert(SqlInsert insert) {
    final SqlValidatorNamespace targetNamespace = getNamespace(insert);
    validateNamespace(targetNamespace, unknownType);
    final RelOptTable relOptTable = SqlValidatorUtil.getRelOptTable(targetNamespace, catalogReader.unwrap(Prepare.CatalogReader.class), null, null);
    final SqlValidatorTable table = relOptTable == null ? targetNamespace.getTable() : relOptTable.unwrap(SqlValidatorTable.class);
    // INSERT has an optional column name list.  If present then
    // reduce the rowtype to the columns specified.  If not present
    // then the entire target rowtype is used.
    final RelDataType targetRowType = createTargetRowType(table, insert.getTargetColumnList(), false);
    final SqlNode source = insert.getSource();
    if (source instanceof SqlSelect) {
        final SqlSelect sqlSelect = (SqlSelect) source;
        validateSelect(sqlSelect, targetRowType);
    } else {
        final SqlValidatorScope scope = scopes.get(source);
        validateQuery(source, scope, targetRowType);
    }
    // REVIEW jvs 4-Dec-2008: In FRG-365, this namespace row type is
    // discarding the type inferred by inferUnknownTypes (which was invoked
    // from validateSelect above).  It would be better if that information
    // were used here so that we never saw any untyped nulls during
    // checkTypeAssignment.
    final RelDataType sourceRowType = getNamespace(source).getRowType();
    final RelDataType logicalTargetRowType = getLogicalTargetRowType(targetRowType, insert);
    setValidatedNodeType(insert, logicalTargetRowType);
    final RelDataType logicalSourceRowType = getLogicalSourceRowType(sourceRowType, insert);
    checkFieldCount(insert.getTargetTable(), table, source, logicalSourceRowType, logicalTargetRowType);
    checkTypeAssignment(logicalSourceRowType, logicalTargetRowType, insert);
    checkConstraint(table, source, logicalTargetRowType);
    validateAccess(insert.getTargetTable(), table, SqlAccessEnum.INSERT);
}
Also used : SqlSelect(org.apache.calcite.sql.SqlSelect) RelDataType(org.apache.calcite.rel.type.RelDataType) RelOptTable(org.apache.calcite.plan.RelOptTable) SqlNode(org.apache.calcite.sql.SqlNode)

Example 10 with RelOptTable

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.RelOptTable in project calcite by apache.

the class SqlValidatorImpl method createTargetRowType.

/**
 * Derives a row-type for INSERT and UPDATE operations.
 *
 * @param table            Target table for INSERT/UPDATE
 * @param targetColumnList List of target columns, or null if not specified
 * @param append           Whether to append fields to those in <code>
 *                         baseRowType</code>
 * @return Rowtype
 */
protected RelDataType createTargetRowType(SqlValidatorTable table, SqlNodeList targetColumnList, boolean append) {
    RelDataType baseRowType = table.getRowType();
    if (targetColumnList == null) {
        return baseRowType;
    }
    List<RelDataTypeField> targetFields = baseRowType.getFieldList();
    final List<Map.Entry<String, RelDataType>> types = new ArrayList<>();
    if (append) {
        for (RelDataTypeField targetField : targetFields) {
            types.add(Pair.of(SqlUtil.deriveAliasFromOrdinal(types.size()), targetField.getType()));
        }
    }
    final Set<Integer> assignedFields = new HashSet<>();
    final RelOptTable relOptTable = table instanceof RelOptTable ? ((RelOptTable) table) : null;
    for (SqlNode node : targetColumnList) {
        SqlIdentifier id = (SqlIdentifier) node;
        RelDataTypeField targetField = SqlValidatorUtil.getTargetField(baseRowType, typeFactory, id, catalogReader, relOptTable);
        if (targetField == null) {
            throw newValidationError(id, RESOURCE.unknownTargetColumn(id.toString()));
        }
        if (!assignedFields.add(targetField.getIndex())) {
            throw newValidationError(id, RESOURCE.duplicateTargetColumn(targetField.getName()));
        }
        types.add(targetField);
    }
    return typeFactory.createStructType(types);
}
Also used : BigInteger(java.math.BigInteger) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) RelOptTable(org.apache.calcite.plan.RelOptTable) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) SqlNode(org.apache.calcite.sql.SqlNode)

Aggregations

RelOptTable (org.apache.calcite.plan.RelOptTable)63 RelDataType (org.apache.calcite.rel.type.RelDataType)20 RexNode (org.apache.calcite.rex.RexNode)18 RelNode (org.apache.calcite.rel.RelNode)17 Table (org.apache.calcite.schema.Table)15 ArrayList (java.util.ArrayList)14 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)12 RelTraitSet (org.apache.calcite.plan.RelTraitSet)10 SqlNode (org.apache.calcite.sql.SqlNode)10 RelOptCluster (org.apache.calcite.plan.RelOptCluster)9 ImmutableList (com.google.common.collect.ImmutableList)8 NlsString (org.apache.calcite.util.NlsString)8 List (java.util.List)6 LogicalJoin (org.apache.calcite.rel.logical.LogicalJoin)6 SchemaPlus (org.apache.calcite.schema.SchemaPlus)6 RelOptSchema (org.apache.calcite.plan.RelOptSchema)5 Project (org.apache.calcite.rel.core.Project)5 LogicalProject (org.apache.calcite.rel.logical.LogicalProject)5 ProjectableFilterableTable (org.apache.calcite.schema.ProjectableFilterableTable)5 Test (org.junit.Test)5