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);
}
}
}
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());
}
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;
}
}
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);
}
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);
}
Aggregations