use of org.apache.calcite.rex.RexDynamicParam in project calcite by apache.
the class RexProgramTest method testCnf.
/**
* Unit test for {@link org.apache.calcite.rex.RexUtil#toCnf}.
*/
@Test
public void testCnf() {
final RelDataType booleanType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
final RelDataType intType = typeFactory.createSqlType(SqlTypeName.INTEGER);
final RelDataType rowType = typeFactory.builder().add("a", booleanType).add("b", booleanType).add("c", booleanType).add("d", booleanType).add("e", booleanType).add("f", booleanType).add("g", booleanType).add("h", intType).build();
final RexDynamicParam range = rexBuilder.makeDynamicParam(rowType, 0);
final RexNode aRef = rexBuilder.makeFieldAccess(range, 0);
final RexNode bRef = rexBuilder.makeFieldAccess(range, 1);
final RexNode cRef = rexBuilder.makeFieldAccess(range, 2);
final RexNode dRef = rexBuilder.makeFieldAccess(range, 3);
final RexNode eRef = rexBuilder.makeFieldAccess(range, 4);
final RexNode fRef = rexBuilder.makeFieldAccess(range, 5);
final RexNode gRef = rexBuilder.makeFieldAccess(range, 6);
final RexNode hRef = rexBuilder.makeFieldAccess(range, 7);
final RexLiteral sevenLiteral = rexBuilder.makeExactLiteral(BigDecimal.valueOf(7));
final RexNode hEqSeven = eq(hRef, sevenLiteral);
checkCnf(aRef, "?0.a");
checkCnf(trueLiteral, "true");
checkCnf(falseLiteral, "false");
checkCnf(unknownLiteral, "null");
checkCnf(and(aRef, bRef), "AND(?0.a, ?0.b)");
checkCnf(and(aRef, bRef, cRef), "AND(?0.a, ?0.b, ?0.c)");
checkCnf(and(or(aRef, bRef), or(cRef, dRef)), "AND(OR(?0.a, ?0.b), OR(?0.c, ?0.d))");
checkCnf(or(and(aRef, bRef), and(cRef, dRef)), "AND(OR(?0.a, ?0.c), OR(?0.a, ?0.d), OR(?0.b, ?0.c), OR(?0.b, ?0.d))");
// Input has nested ORs, output ORs are flat
checkCnf(or(and(aRef, bRef), or(cRef, dRef)), "AND(OR(?0.a, ?0.c, ?0.d), OR(?0.b, ?0.c, ?0.d))");
checkCnf(or(aRef, not(and(bRef, not(hEqSeven)))), "OR(?0.a, NOT(?0.b), =(?0.h, 7))");
// apply de Morgan's theorem
checkCnf(not(or(aRef, not(bRef))), "AND(NOT(?0.a), ?0.b)");
// apply de Morgan's theorem,
// filter out 'OR ... FALSE' and 'AND ... TRUE'
checkCnf(not(or(and(aRef, trueLiteral), not(bRef), falseLiteral)), "AND(NOT(?0.a), ?0.b)");
checkCnf(and(aRef, or(bRef, and(cRef, dRef))), "AND(?0.a, OR(?0.b, ?0.c), OR(?0.b, ?0.d))");
checkCnf(and(aRef, or(bRef, and(cRef, or(dRef, and(eRef, or(fRef, gRef)))))), "AND(?0.a, OR(?0.b, ?0.c), OR(?0.b, ?0.d, ?0.e), OR(?0.b, ?0.d, ?0.f, ?0.g))");
checkCnf(and(aRef, or(bRef, and(cRef, or(dRef, and(eRef, or(fRef, and(gRef, or(trueLiteral, falseLiteral)))))))), "AND(?0.a, OR(?0.b, ?0.c), OR(?0.b, ?0.d, ?0.e), OR(?0.b, ?0.d, ?0.f, ?0.g))");
}
use of org.apache.calcite.rex.RexDynamicParam in project calcite by apache.
the class RexProgramTest method testThresholdCnf.
/**
* Unit test for
* <a href="https://issues.apache.org/jira/browse/CALCITE-1290">[CALCITE-1290]
* When converting to CNF, fail if the expression exceeds a threshold</a>.
*/
@Test
public void testThresholdCnf() {
final RelDataType intType = typeFactory.createSqlType(SqlTypeName.INTEGER);
final RelDataType rowType = typeFactory.builder().add("x", intType).add("y", intType).build();
final RexDynamicParam range = rexBuilder.makeDynamicParam(rowType, 0);
final RexNode xRef = rexBuilder.makeFieldAccess(range, 0);
final RexNode yRef = rexBuilder.makeFieldAccess(range, 1);
final RexLiteral literal1 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(1));
final RexLiteral literal2 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(2));
final RexLiteral literal3 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(3));
final RexLiteral literal4 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(4));
// Expression
// OR(=(?0.x, 1), AND(=(?0.x, 2), =(?0.y, 3)))
// transformation creates 7 nodes
// AND(OR(=(?0.x, 1), =(?0.x, 2)), OR(=(?0.x, 1), =(?0.y, 3)))
// Thus, it is triggered.
checkThresholdCnf(or(eq(xRef, literal1), and(eq(xRef, literal2), eq(yRef, literal3))), 8, "AND(OR(=(?0.x, 1), =(?0.x, 2)), OR(=(?0.x, 1), =(?0.y, 3)))");
// Expression
// OR(=(?0.x, 1), =(?0.x, 2), AND(=(?0.x, 3), =(?0.y, 4)))
// transformation creates 9 nodes
// AND(OR(=(?0.x, 1), =(?0.x, 2), =(?0.x, 3)),
// OR(=(?0.x, 1), =(?0.x, 2), =(?0.y, 8)))
// Thus, it is NOT triggered.
checkThresholdCnf(or(eq(xRef, literal1), eq(xRef, literal2), and(eq(xRef, literal3), eq(yRef, literal4))), 8, "OR(=(?0.x, 1), =(?0.x, 2), AND(=(?0.x, 3), =(?0.y, 4)))");
}
use of org.apache.calcite.rex.RexDynamicParam in project druid by druid-io.
the class RelParameterizerShuttle method bindRel.
private RelNode bindRel(RelNode node, RexBuilder builder, RelDataTypeFactory typeFactory) {
final RexShuttle binder = new RexShuttle() {
@Override
public RexNode visitDynamicParam(RexDynamicParam dynamicParam) {
return bind(dynamicParam, builder, typeFactory);
}
};
node = node.accept(binder);
node.childrenAccept(new RelVisitor() {
@Override
public void visit(RelNode node, int ordinal, RelNode parent) {
super.visit(node, ordinal, parent);
RelNode transformed = node.accept(binder);
if (!node.equals(transformed)) {
parent.replaceInput(ordinal, transformed);
}
}
});
return node;
}
use of org.apache.calcite.rex.RexDynamicParam in project hive by apache.
the class RelFieldTrimmer method trimFields.
/**
* Variant of {@link #trimFields(RelNode, ImmutableBitSet, Set)} for
* {@link org.apache.calcite.rel.core.Sort}.
*/
public TrimResult trimFields(Sort sort, ImmutableBitSet fieldsUsed, Set<RelDataTypeField> extraFields) {
final RelDataType rowType = sort.getRowType();
final int fieldCount = rowType.getFieldCount();
final RelCollation collation = sort.getCollation();
final RelNode input = sort.getInput();
// We use the fields used by the consumer, plus any fields used as sort
// keys.
final ImmutableBitSet.Builder inputFieldsUsed = fieldsUsed.rebuild();
for (RelFieldCollation field : collation.getFieldCollations()) {
inputFieldsUsed.set(field.getFieldIndex());
}
// Create input with trimmed columns.
final Set<RelDataTypeField> inputExtraFields = Collections.emptySet();
TrimResult trimResult = trimChild(sort, input, inputFieldsUsed.build(), inputExtraFields);
RelNode newInput = trimResult.left;
final Mapping inputMapping = trimResult.right;
// there's nothing we can do.
if (newInput == input && inputMapping.isIdentity() && fieldsUsed.cardinality() == fieldCount) {
return result(sort, Mappings.createIdentity(fieldCount));
}
// leave the Sort unchanged in case we have dynamic limits
if (sort.offset instanceof RexDynamicParam || sort.fetch instanceof RexDynamicParam) {
return result(sort, inputMapping);
}
final RelBuilder relBuilder = REL_BUILDER.get();
relBuilder.push(newInput);
final int offset = sort.offset == null ? 0 : RexLiteral.intValue(sort.offset);
final int fetch = sort.fetch == null ? -1 : RexLiteral.intValue(sort.fetch);
final ImmutableList<RexNode> fields = relBuilder.fields(RexUtil.apply(inputMapping, collation));
relBuilder.sortLimit(offset, fetch, fields);
// needs them for its condition.
return result(relBuilder.build(), inputMapping);
}
use of org.apache.calcite.rex.RexDynamicParam in project beam by apache.
the class LimitOffsetScanToLimitConverter method convert.
@Override
public RelNode convert(ResolvedLimitOffsetScan zetaNode, List<RelNode> inputs) {
RelNode input = inputs.get(0);
RelCollation relCollation = RelCollations.of(ImmutableList.of());
RexNode offset = zetaNode.getOffset() == null ? null : getExpressionConverter().convertRexNodeFromResolvedExpr(zetaNode.getOffset());
RexNode fetch = getExpressionConverter().convertRexNodeFromResolvedExpr(zetaNode.getLimit(), zetaNode.getColumnList(), input.getRowType().getFieldList(), ImmutableMap.of());
// offset or fetch being RexDynamicParam means it is NULL (the only param supported currently)
if (offset instanceof RexDynamicParam || RexLiteral.isNullLiteral(offset) || fetch instanceof RexDynamicParam || RexLiteral.isNullLiteral(fetch)) {
throw new UnsupportedOperationException("Limit requires non-null count and offset");
}
return LogicalSort.create(input, relCollation, offset, fetch);
}
Aggregations