Search in sources :

Example 1 with SqlMonotonicity

use of org.apache.calcite.sql.validate.SqlMonotonicity in project calcite by apache.

the class SqlMonotonicBinaryOperator method getMonotonicity.

// ~ Methods ----------------------------------------------------------------
@Override
public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
    final SqlMonotonicity mono0 = call.getOperandMonotonicity(0);
    final SqlMonotonicity mono1 = call.getOperandMonotonicity(1);
    // constant <op> constant --> constant
    if ((mono1 == SqlMonotonicity.CONSTANT) && (mono0 == SqlMonotonicity.CONSTANT)) {
        return SqlMonotonicity.CONSTANT;
    }
    // monotonic <op> constant
    if (mono1 == SqlMonotonicity.CONSTANT) {
        // mono0 - constant --> mono0
        if (getName().equals("-") || getName().equals("+")) {
            return mono0;
        }
        assert getName().equals("*");
        switch(call.getOperandLiteralValue(1, BigDecimal.class).signum()) {
            case -1:
                // mono0 * negative constant --> reverse mono0
                return mono0.reverse();
            case 0:
                // mono0 * 0 --> constant (zero)
                return SqlMonotonicity.CONSTANT;
            default:
                // mono0 * positive constant --> mono0
                return mono0;
        }
    }
    // constant <op> mono
    if (mono0 == SqlMonotonicity.CONSTANT) {
        if (getName().equals("-")) {
            // constant - mono1 --> reverse mono1
            return mono1.reverse();
        }
        if (getName().equals("+")) {
            // constant + mono1 --> mono1
            return mono1;
        }
        assert getName().equals("*");
        if (!call.isOperandNull(0, true)) {
            switch(call.getOperandLiteralValue(0, BigDecimal.class).signum()) {
                case -1:
                    // negative constant * mono1 --> reverse mono1
                    return mono1.reverse();
                case 0:
                    // 0 * mono1 --> constant (zero)
                    return SqlMonotonicity.CONSTANT;
                default:
                    // positive constant * mono1 --> mono1
                    return mono1;
            }
        }
    }
    if (getName().equals("+")) {
        if (mono0 == mono1) {
            return mono0;
        } else if (mono0.unstrict() == mono1.unstrict()) {
            return mono0.unstrict();
        } else {
            return SqlMonotonicity.NOT_MONOTONIC;
        }
    }
    if (getName().equals("-")) {
        if (mono0 == mono1.reverse()) {
            return mono0;
        } else if (mono0.unstrict() == mono1.reverse().unstrict()) {
            return mono0.unstrict();
        } else {
            return SqlMonotonicity.NOT_MONOTONIC;
        }
    }
    if (getName().equals("*")) {
        return SqlMonotonicity.NOT_MONOTONIC;
    }
    return super.getMonotonicity(call);
}
Also used : SqlMonotonicity(org.apache.calcite.sql.validate.SqlMonotonicity) BigDecimal(java.math.BigDecimal)

Example 2 with SqlMonotonicity

use of org.apache.calcite.sql.validate.SqlMonotonicity 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 3 with SqlMonotonicity

use of org.apache.calcite.sql.validate.SqlMonotonicity in project calcite by apache.

the class SqlToRelConverter method convertSelectList.

private void convertSelectList(Blackboard bb, SqlSelect select, List<SqlNode> orderList) {
    SqlNodeList selectList = select.getSelectList();
    selectList = validator.expandStar(selectList, select, false);
    replaceSubQueries(bb, selectList, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
    List<String> fieldNames = new ArrayList<>();
    final List<RexNode> exprs = new ArrayList<>();
    final Collection<String> aliases = new TreeSet<>();
    // Project any system fields. (Must be done before regular select items,
    // because offsets may be affected.)
    final List<SqlMonotonicity> columnMonotonicityList = new ArrayList<>();
    extraSelectItems(bb, select, exprs, fieldNames, aliases, columnMonotonicityList);
    // Project select clause.
    int i = -1;
    for (SqlNode expr : selectList) {
        ++i;
        exprs.add(bb.convertExpression(expr));
        fieldNames.add(deriveAlias(expr, aliases, i));
    }
    // Project extra fields for sorting.
    for (SqlNode expr : orderList) {
        ++i;
        SqlNode expr2 = validator.expandOrderExpr(select, expr);
        exprs.add(bb.convertExpression(expr2));
        fieldNames.add(deriveAlias(expr, aliases, i));
    }
    fieldNames = SqlValidatorUtil.uniquify(fieldNames, catalogReader.nameMatcher().isCaseSensitive());
    relBuilder.push(bb.root).projectNamed(exprs, fieldNames, true);
    bb.setRoot(relBuilder.build(), false);
    assert bb.columnMonotonicities.isEmpty();
    bb.columnMonotonicities.addAll(columnMonotonicityList);
    for (SqlNode selectItem : selectList) {
        bb.columnMonotonicities.add(selectItem.getMonotonicity(bb.scope));
    }
}
Also used : TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) SqlMonotonicity(org.apache.calcite.sql.validate.SqlMonotonicity) SqlNodeList(org.apache.calcite.sql.SqlNodeList) NlsString(org.apache.calcite.util.NlsString) RexNode(org.apache.calcite.rex.RexNode) SqlNode(org.apache.calcite.sql.SqlNode)

Example 4 with SqlMonotonicity

use of org.apache.calcite.sql.validate.SqlMonotonicity in project calcite by apache.

the class SqlBinaryOperator method getMonotonicity.

@Override
public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
    if (getName().equals("/")) {
        final SqlMonotonicity mono0 = call.getOperandMonotonicity(0);
        final SqlMonotonicity mono1 = call.getOperandMonotonicity(1);
        if (mono1 == SqlMonotonicity.CONSTANT) {
            if (call.isOperandLiteral(1, false)) {
                switch(call.getOperandLiteralValue(1, BigDecimal.class).signum()) {
                    case -1:
                        // mono / -ve constant --> reverse mono, unstrict
                        return mono0.reverse().unstrict();
                    case 0:
                        // mono / zero --> constant (infinity!)
                        return SqlMonotonicity.CONSTANT;
                    default:
                        // mono / +ve constant * mono1 --> mono, unstrict
                        return mono0.unstrict();
                }
            }
        }
    }
    return super.getMonotonicity(call);
}
Also used : SqlMonotonicity(org.apache.calcite.sql.validate.SqlMonotonicity) BigDecimal(java.math.BigDecimal)

Example 5 with SqlMonotonicity

use of org.apache.calcite.sql.validate.SqlMonotonicity in project flink by apache.

the class FlinkRelMdCollation method project.

/**
 * Helper method to determine a {@link Project}'s collation.
 */
public static List<RelCollation> project(RelMetadataQuery mq, RelNode input, List<? extends RexNode> projects) {
    final SortedSet<RelCollation> collations = new TreeSet<>();
    final List<RelCollation> inputCollations = mq.collations(input);
    if (inputCollations == null || inputCollations.isEmpty()) {
        return com.google.common.collect.ImmutableList.of();
    }
    final com.google.common.collect.Multimap<Integer, Integer> targets = com.google.common.collect.LinkedListMultimap.create();
    final Map<Integer, SqlMonotonicity> targetsWithMonotonicity = new HashMap<>();
    for (Ord<RexNode> project : Ord.<RexNode>zip(projects)) {
        if (project.e instanceof RexInputRef) {
            targets.put(((RexInputRef) project.e).getIndex(), project.i);
        } else if (project.e instanceof RexCall) {
            final RexCall call = (RexCall) project.e;
            final RexCallBinding binding = RexCallBinding.create(input.getCluster().getTypeFactory(), call, inputCollations);
            targetsWithMonotonicity.put(project.i, call.getOperator().getMonotonicity(binding));
        }
    }
    final List<RelFieldCollation> fieldCollations = new ArrayList<>();
    loop: for (RelCollation ic : inputCollations) {
        if (ic.getFieldCollations().isEmpty()) {
            continue;
        }
        fieldCollations.clear();
        for (RelFieldCollation ifc : ic.getFieldCollations()) {
            final Collection<Integer> integers = targets.get(ifc.getFieldIndex());
            if (integers.isEmpty()) {
                // cannot do this collation
                continue loop;
            }
            fieldCollations.add(ifc.withFieldIndex(integers.iterator().next()));
        }
        assert !fieldCollations.isEmpty();
        collations.add(RelCollations.of(fieldCollations));
    }
    final List<RelFieldCollation> fieldCollationsForRexCalls = new ArrayList<>();
    for (Map.Entry<Integer, SqlMonotonicity> entry : targetsWithMonotonicity.entrySet()) {
        final SqlMonotonicity value = entry.getValue();
        switch(value) {
            case NOT_MONOTONIC:
            case CONSTANT:
                break;
            default:
                fieldCollationsForRexCalls.add(new RelFieldCollation(entry.getKey(), RelFieldCollation.Direction.of(value)));
                break;
        }
    }
    if (!fieldCollationsForRexCalls.isEmpty()) {
        collations.add(RelCollations.of(fieldCollationsForRexCalls));
    }
    return com.google.common.collect.ImmutableList.copyOf(collations);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) RexCall(org.apache.calcite.rex.RexCall) RexCallBinding(org.apache.calcite.rex.RexCallBinding) RelCollation(org.apache.calcite.rel.RelCollation) TreeSet(java.util.TreeSet) SqlMonotonicity(org.apache.calcite.sql.validate.SqlMonotonicity) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RexInputRef(org.apache.calcite.rex.RexInputRef) Collection(java.util.Collection) Map(java.util.Map) HashMap(java.util.HashMap) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

SqlMonotonicity (org.apache.calcite.sql.validate.SqlMonotonicity)8 RelCollation (org.apache.calcite.rel.RelCollation)4 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)4 ArrayList (java.util.ArrayList)3 TreeSet (java.util.TreeSet)3 RexNode (org.apache.calcite.rex.RexNode)3 BigDecimal (java.math.BigDecimal)2 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 RexCall (org.apache.calcite.rex.RexCall)2 RexCallBinding (org.apache.calcite.rex.RexCallBinding)2 RexInputRef (org.apache.calcite.rex.RexInputRef)2 SqlNode (org.apache.calcite.sql.SqlNode)2 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 List (java.util.List)1 Set (java.util.Set)1 RelNode (org.apache.calcite.rel.RelNode)1 RelReferentialConstraint (org.apache.calcite.rel.RelReferentialConstraint)1