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