Search in sources :

Example 1 with RelCollation

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

the class RelMdCollation method values.

/**
 * Helper method to determine a
 * {@link org.apache.calcite.rel.core.Values}'s collation.
 *
 * <p>We actually under-report the collations. A Values with 0 or 1 rows - an
 * edge case, but legitimate and very common - is ordered by every permutation
 * of every subset of the columns.
 *
 * <p>So, our algorithm aims to:<ul>
 *   <li>produce at most N collations (where N is the number of columns);
 *   <li>make each collation as long as possible;
 *   <li>do not repeat combinations already emitted -
 *       if we've emitted {@code (a, b)} do not later emit {@code (b, a)};
 *   <li>probe the actual values and make sure that each collation is
 *      consistent with the data
 * </ul>
 *
 * <p>So, for an empty Values with 4 columns, we would emit
 * {@code (a, b, c, d), (b, c, d), (c, d), (d)}.
 */
public static List<RelCollation> values(RelMetadataQuery mq, RelDataType rowType, ImmutableList<ImmutableList<RexLiteral>> tuples) {
    // for future use
    Util.discard(mq);
    final List<RelCollation> list = Lists.newArrayList();
    final int n = rowType.getFieldCount();
    final List<Pair<RelFieldCollation, Ordering<List<RexLiteral>>>> pairs = Lists.newArrayList();
    outer: for (int i = 0; i < n; i++) {
        pairs.clear();
        for (int j = i; j < n; j++) {
            final RelFieldCollation fieldCollation = new RelFieldCollation(j);
            Ordering<List<RexLiteral>> comparator = comparator(fieldCollation);
            Ordering<List<RexLiteral>> ordering;
            if (pairs.isEmpty()) {
                ordering = comparator;
            } else {
                ordering = Util.last(pairs).right.compound(comparator);
            }
            pairs.add(Pair.of(fieldCollation, ordering));
            if (!ordering.isOrdered(tuples)) {
                if (j == i) {
                    continue outer;
                }
                pairs.remove(pairs.size() - 1);
            }
        }
        if (!pairs.isEmpty()) {
            list.add(RelCollations.of(Pair.left(pairs)));
        }
    }
    return list;
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) RelCollation(org.apache.calcite.rel.RelCollation) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) Ordering(com.google.common.collect.Ordering) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) List(java.util.List) Pair(org.apache.calcite.util.Pair)

Example 2 with RelCollation

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

the class LogicalWindow method addWindows.

private static void addWindows(Multimap<WindowKey, RexOver> windowMap, RexOver over, final int inputFieldCount) {
    final RexWindow aggWindow = over.getWindow();
    // Look up or create a window.
    RelCollation orderKeys = getCollation(Lists.newArrayList(Iterables.filter(aggWindow.orderKeys, new PredicateImpl<RexFieldCollation>() {

        public boolean test(RexFieldCollation rexFieldCollation) {
            // then we can ignore such ORDER BY key.
            return rexFieldCollation.left instanceof RexLocalRef;
        }
    })));
    ImmutableBitSet groupSet = ImmutableBitSet.of(getProjectOrdinals(aggWindow.partitionKeys));
    final int groupLength = groupSet.length();
    if (inputFieldCount < groupLength) {
        // If PARTITION BY references constant, we can ignore such partition key.
        // All the inputs after inputFieldCount are literals, thus we can clear.
        groupSet = groupSet.except(ImmutableBitSet.range(inputFieldCount, groupLength));
    }
    WindowKey windowKey = new WindowKey(groupSet, orderKeys, aggWindow.isRows(), aggWindow.getLowerBound(), aggWindow.getUpperBound());
    windowMap.put(windowKey, over);
}
Also used : RelCollation(org.apache.calcite.rel.RelCollation) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) RexLocalRef(org.apache.calcite.rex.RexLocalRef) RexWindow(org.apache.calcite.rex.RexWindow) RexFieldCollation(org.apache.calcite.rex.RexFieldCollation)

Example 3 with RelCollation

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

the class MockCatalogReader method deduceMonotonicity.

private static List<RelCollation> deduceMonotonicity(Prepare.PreparingTable table) {
    final List<RelCollation> collationList = Lists.newArrayList();
    // Deduce which fields the table is sorted on.
    int i = -1;
    for (RelDataTypeField field : table.getRowType().getFieldList()) {
        ++i;
        final SqlMonotonicity monotonicity = table.getMonotonicity(field.getName());
        if (monotonicity != SqlMonotonicity.NOT_MONOTONIC) {
            final RelFieldCollation.Direction direction = monotonicity.isDecreasing() ? RelFieldCollation.Direction.DESCENDING : RelFieldCollation.Direction.ASCENDING;
            collationList.add(RelCollations.of(new RelFieldCollation(i, direction)));
        }
    }
    return collationList;
}
Also used : RelCollation(org.apache.calcite.rel.RelCollation) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) SqlMonotonicity(org.apache.calcite.sql.validate.SqlMonotonicity) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RelReferentialConstraint(org.apache.calcite.rel.RelReferentialConstraint)

Example 4 with RelCollation

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

the class EnumerableCalc method create.

/**
 * Creates an EnumerableCalc.
 */
public static EnumerableCalc create(final RelNode input, final RexProgram program) {
    final RelOptCluster cluster = input.getCluster();
    final RelMetadataQuery mq = cluster.getMetadataQuery();
    final RelTraitSet traitSet = cluster.traitSet().replace(EnumerableConvention.INSTANCE).replaceIfs(RelCollationTraitDef.INSTANCE, new Supplier<List<RelCollation>>() {

        public List<RelCollation> get() {
            return RelMdCollation.calc(mq, input, program);
        }
    }).replaceIf(RelDistributionTraitDef.INSTANCE, new Supplier<RelDistribution>() {

        public RelDistribution get() {
            return RelMdDistribution.calc(mq, input, program);
        }
    });
    return new EnumerableCalc(cluster, traitSet, input, program);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RelCollation(org.apache.calcite.rel.RelCollation) Supplier(com.google.common.base.Supplier) RelTraitSet(org.apache.calcite.plan.RelTraitSet) RelDistribution(org.apache.calcite.rel.RelDistribution)

Example 5 with RelCollation

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

the class SqlToRelConverter method convertMatchRecognize.

protected void convertMatchRecognize(Blackboard bb, SqlCall call) {
    final SqlMatchRecognize matchRecognize = (SqlMatchRecognize) call;
    final SqlValidatorNamespace ns = validator.getNamespace(matchRecognize);
    final SqlValidatorScope scope = validator.getMatchRecognizeScope(matchRecognize);
    final Blackboard matchBb = createBlackboard(scope, null, false);
    final RelDataType rowType = ns.getRowType();
    // convert inner query, could be a table name or a derived table
    SqlNode expr = matchRecognize.getTableRef();
    convertFrom(matchBb, expr);
    final RelNode input = matchBb.root;
    // PARTITION BY
    final SqlNodeList partitionList = matchRecognize.getPartitionList();
    final List<RexNode> partitionKeys = new ArrayList<>();
    for (SqlNode partition : partitionList) {
        RexNode e = matchBb.convertExpression(partition);
        partitionKeys.add(e);
    }
    // ORDER BY
    final SqlNodeList orderList = matchRecognize.getOrderList();
    final List<RelFieldCollation> orderKeys = new ArrayList<>();
    for (SqlNode order : orderList) {
        final RelFieldCollation.Direction direction;
        switch(order.getKind()) {
            case DESCENDING:
                direction = RelFieldCollation.Direction.DESCENDING;
                order = ((SqlCall) order).operand(0);
                break;
            case NULLS_FIRST:
            case NULLS_LAST:
                throw new AssertionError();
            default:
                direction = RelFieldCollation.Direction.ASCENDING;
                break;
        }
        final RelFieldCollation.NullDirection nullDirection = validator.getDefaultNullCollation().last(desc(direction)) ? RelFieldCollation.NullDirection.LAST : RelFieldCollation.NullDirection.FIRST;
        RexNode e = matchBb.convertExpression(order);
        orderKeys.add(new RelFieldCollation(((RexInputRef) e).getIndex(), direction, nullDirection));
    }
    final RelCollation orders = cluster.traitSet().canonize(RelCollations.of(orderKeys));
    // convert pattern
    final Set<String> patternVarsSet = new HashSet<>();
    SqlNode pattern = matchRecognize.getPattern();
    final SqlBasicVisitor<RexNode> patternVarVisitor = new SqlBasicVisitor<RexNode>() {

        @Override
        public RexNode visit(SqlCall call) {
            List<SqlNode> operands = call.getOperandList();
            List<RexNode> newOperands = Lists.newArrayList();
            for (SqlNode node : operands) {
                newOperands.add(node.accept(this));
            }
            return rexBuilder.makeCall(validator.getUnknownType(), call.getOperator(), newOperands);
        }

        @Override
        public RexNode visit(SqlIdentifier id) {
            assert id.isSimple();
            patternVarsSet.add(id.getSimple());
            return rexBuilder.makeLiteral(id.getSimple());
        }

        @Override
        public RexNode visit(SqlLiteral literal) {
            if (literal instanceof SqlNumericLiteral) {
                return rexBuilder.makeExactLiteral(BigDecimal.valueOf(literal.intValue(true)));
            } else {
                return rexBuilder.makeLiteral(literal.booleanValue());
            }
        }
    };
    final RexNode patternNode = pattern.accept(patternVarVisitor);
    SqlLiteral interval = matchRecognize.getInterval();
    RexNode intervalNode = null;
    if (interval != null) {
        intervalNode = matchBb.convertLiteral(interval);
    }
    // convert subset
    final SqlNodeList subsets = matchRecognize.getSubsetList();
    final Map<String, TreeSet<String>> subsetMap = Maps.newHashMap();
    for (SqlNode node : subsets) {
        List<SqlNode> operands = ((SqlCall) node).getOperandList();
        SqlIdentifier left = (SqlIdentifier) operands.get(0);
        patternVarsSet.add(left.getSimple());
        SqlNodeList rights = (SqlNodeList) operands.get(1);
        final TreeSet<String> list = new TreeSet<String>();
        for (SqlNode right : rights) {
            assert right instanceof SqlIdentifier;
            list.add(((SqlIdentifier) right).getSimple());
        }
        subsetMap.put(left.getSimple(), list);
    }
    SqlNode afterMatch = matchRecognize.getAfter();
    if (afterMatch == null) {
        afterMatch = SqlMatchRecognize.AfterOption.SKIP_TO_NEXT_ROW.symbol(SqlParserPos.ZERO);
    }
    final RexNode after;
    if (afterMatch instanceof SqlCall) {
        List<SqlNode> operands = ((SqlCall) afterMatch).getOperandList();
        SqlOperator operator = ((SqlCall) afterMatch).getOperator();
        assert operands.size() == 1;
        SqlIdentifier id = (SqlIdentifier) operands.get(0);
        assert patternVarsSet.contains(id.getSimple()) : id.getSimple() + " not defined in pattern";
        RexNode rex = rexBuilder.makeLiteral(id.getSimple());
        after = rexBuilder.makeCall(validator.getUnknownType(), operator, ImmutableList.of(rex));
    } else {
        after = matchBb.convertExpression(afterMatch);
    }
    matchBb.setPatternVarRef(true);
    // convert measures
    final ImmutableMap.Builder<String, RexNode> measureNodes = ImmutableMap.builder();
    for (SqlNode measure : matchRecognize.getMeasureList()) {
        List<SqlNode> operands = ((SqlCall) measure).getOperandList();
        String alias = ((SqlIdentifier) operands.get(1)).getSimple();
        RexNode rex = matchBb.convertExpression(operands.get(0));
        measureNodes.put(alias, rex);
    }
    // convert definitions
    final ImmutableMap.Builder<String, RexNode> definitionNodes = ImmutableMap.builder();
    for (SqlNode def : matchRecognize.getPatternDefList()) {
        List<SqlNode> operands = ((SqlCall) def).getOperandList();
        String alias = ((SqlIdentifier) operands.get(1)).getSimple();
        RexNode rex = matchBb.convertExpression(operands.get(0));
        definitionNodes.put(alias, rex);
    }
    final SqlLiteral rowsPerMatch = matchRecognize.getRowsPerMatch();
    final boolean allRows = rowsPerMatch != null && rowsPerMatch.getValue() == SqlMatchRecognize.RowsPerMatchOption.ALL_ROWS;
    matchBb.setPatternVarRef(false);
    final RelFactories.MatchFactory factory = RelFactories.DEFAULT_MATCH_FACTORY;
    final RelNode rel = factory.createMatch(input, patternNode, rowType, matchRecognize.getStrictStart().booleanValue(), matchRecognize.getStrictEnd().booleanValue(), definitionNodes.build(), measureNodes.build(), after, subsetMap, allRows, partitionKeys, orders, intervalNode);
    bb.setRoot(rel, false);
}
Also used : SqlValidatorScope(org.apache.calcite.sql.validate.SqlValidatorScope) SqlOperator(org.apache.calcite.sql.SqlOperator) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) NlsString(org.apache.calcite.util.NlsString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) TreeSet(java.util.TreeSet) SqlBasicVisitor(org.apache.calcite.sql.util.SqlBasicVisitor) RelFactories(org.apache.calcite.rel.core.RelFactories) SqlNode(org.apache.calcite.sql.SqlNode) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) SqlCall(org.apache.calcite.sql.SqlCall) SqlMatchRecognize(org.apache.calcite.sql.SqlMatchRecognize) ImmutableMap(com.google.common.collect.ImmutableMap) RelCollation(org.apache.calcite.rel.RelCollation) RelNode(org.apache.calcite.rel.RelNode) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) SqlNodeList(org.apache.calcite.sql.SqlNodeList) RexInputRef(org.apache.calcite.rex.RexInputRef) SqlValidatorNamespace(org.apache.calcite.sql.validate.SqlValidatorNamespace) SqlLiteral(org.apache.calcite.sql.SqlLiteral) SqlNumericLiteral(org.apache.calcite.sql.SqlNumericLiteral) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

RelCollation (org.apache.calcite.rel.RelCollation)83 RelNode (org.apache.calcite.rel.RelNode)40 RelTraitSet (org.apache.calcite.plan.RelTraitSet)37 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)33 RexNode (org.apache.calcite.rex.RexNode)24 ArrayList (java.util.ArrayList)19 RelDataType (org.apache.calcite.rel.type.RelDataType)17 RelOptCluster (org.apache.calcite.plan.RelOptCluster)15 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)13 RelMetadataQuery (org.apache.calcite.rel.metadata.RelMetadataQuery)12 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)12 List (java.util.List)11 Sort (org.apache.calcite.rel.core.Sort)11 ImmutableList (com.google.common.collect.ImmutableList)8 RelDistribution (org.apache.calcite.rel.RelDistribution)8 RexInputRef (org.apache.calcite.rex.RexInputRef)8 Map (java.util.Map)7 Mappings (org.apache.calcite.util.mapping.Mappings)7 Supplier (com.google.common.base.Supplier)6 HashMap (java.util.HashMap)6