use of org.apache.calcite.rex.RexCall in project calcite by apache.
the class RexProgramTest method testSimplifyCaseNotNullableBoolean.
/**
* Unit test for
* <a href="https://issues.apache.org/jira/browse/CALCITE-1289">[CALCITE-1289]
* RexUtil.simplifyCase() should account for nullability</a>.
*/
@Test
public void testSimplifyCaseNotNullableBoolean() {
RexNode condition = eq(rexBuilder.makeInputRef(typeFactory.createTypeWithNullability(typeFactory.createSqlType(SqlTypeName.VARCHAR), true), 0), rexBuilder.makeLiteral("S"));
RexCall caseNode = (RexCall) case_(condition, trueLiteral, falseLiteral);
RexCall result = (RexCall) simplify.simplify(caseNode);
assertThat(result.getType().isNullable(), is(false));
assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.BOOLEAN));
assertThat(result.getOperator(), is((SqlOperator) SqlStdOperatorTable.CASE));
assertThat(result.getOperands().size(), is((Object) 3));
assertThat(result.getOperands().get(0), is(condition));
assertThat(result.getOperands().get(1), is((RexNode) trueLiteral));
assertThat(result.getOperands().get(2), is((RexNode) falseLiteral));
}
use of org.apache.calcite.rex.RexCall in project calcite by apache.
the class RelMetadataTest method testAllPredicatesAggregate2.
@Test
public void testAllPredicatesAggregate2() {
final String sql = "select * from (select a, max(b) from (\n" + " select empno as a, sal as b from emp)subq\n" + "group by a) \n" + "where a = 5";
final RelNode rel = convertSql(sql);
final RelMetadataQuery mq = RelMetadataQuery.instance();
RelOptPredicateList inputSet = mq.getAllPredicates(rel);
ImmutableList<RexNode> pulledUpPredicates = inputSet.pulledUpPredicates;
assertThat(pulledUpPredicates.size(), is(1));
RexCall call = (RexCall) pulledUpPredicates.get(0);
assertThat(call.getOperands().size(), is(2));
final RexTableInputRef inputRef1 = (RexTableInputRef) call.getOperands().get(0);
assertTrue(inputRef1.getQualifiedName().equals(EMP_QNAME));
assertThat(inputRef1.getIndex(), is(0));
final RexLiteral constant = (RexLiteral) call.getOperands().get(1);
assertThat(constant.toString(), is("5"));
}
use of org.apache.calcite.rex.RexCall in project calcite by apache.
the class RelMetadataTest method testExpressionLineageMultiUnion.
@Test
public void testExpressionLineageMultiUnion() {
// empno is column 0 in catalog.sales.emp
// sal is column 5 in catalog.sales.emp
final RelNode rel = convertSql("select a.empno + b.sal from \n" + " (select empno, ename from emp,dept) a join " + " (select * from emp union all select * from emp) b \n" + " on a.empno = b.empno \n" + " where b.deptno = 10");
final RelMetadataQuery mq = RelMetadataQuery.instance();
final RexNode ref = RexInputRef.of(0, rel.getRowType().getFieldList());
final Set<RexNode> r = mq.getExpressionLineage(rel, ref);
// With the union, we should get two origins
// The first one should be the same one: join
// The second should come from each union input
final Set<List<String>> set = new HashSet<>();
assertThat(r.size(), is(2));
for (RexNode result : r) {
assertThat(result.getKind(), is(SqlKind.PLUS));
final RexCall call = (RexCall) result;
assertThat(call.getOperands().size(), is(2));
final RexTableInputRef inputRef1 = (RexTableInputRef) call.getOperands().get(0);
assertTrue(inputRef1.getQualifiedName().equals(EMP_QNAME));
// Add join alpha to set
set.add(inputRef1.getQualifiedName());
assertThat(inputRef1.getIndex(), is(0));
final RexTableInputRef inputRef2 = (RexTableInputRef) call.getOperands().get(1);
assertTrue(inputRef2.getQualifiedName().equals(EMP_QNAME));
assertThat(inputRef2.getIndex(), is(5));
assertThat(inputRef1.getIdentifier(), not(inputRef2.getIdentifier()));
}
assertThat(set.size(), is(1));
}
use of org.apache.calcite.rex.RexCall in project calcite by apache.
the class DruidDateTimeUtils method literalValue.
@Nullable
protected static TimestampString literalValue(RexNode node, TimeZone timeZone) {
switch(node.getKind()) {
case LITERAL:
switch(((RexLiteral) node).getTypeName()) {
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
return ((RexLiteral) node).getValueAs(TimestampString.class);
case TIMESTAMP:
// Cast timestamp to timestamp with local time zone
final TimestampString t = ((RexLiteral) node).getValueAs(TimestampString.class);
return new TimestampWithTimeZoneString(t.toString() + " " + timeZone.getID()).withTimeZone(DateTimeUtils.UTC_ZONE).getLocalTimestampString();
case DATE:
// Cast date to timestamp with local time zone
final DateString d = ((RexLiteral) node).getValueAs(DateString.class);
return new TimestampWithTimeZoneString(TimestampString.fromMillisSinceEpoch(d.getMillisSinceEpoch()).toString() + " " + timeZone.getID()).withTimeZone(DateTimeUtils.UTC_ZONE).getLocalTimestampString();
}
break;
case CAST:
// We can handle that case by traversing the dummy CAST.
assert node instanceof RexCall;
final RexCall call = (RexCall) node;
final RexNode operand = call.getOperands().get(0);
final RelDataType callType = call.getType();
final RelDataType operandType = operand.getType();
if (operand.getKind() == SqlKind.LITERAL && callType.getSqlTypeName() == operandType.getSqlTypeName() && (callType.getSqlTypeName() == SqlTypeName.DATE || callType.getSqlTypeName() == SqlTypeName.TIMESTAMP || callType.getSqlTypeName() == SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE) && callType.isNullable() && !operandType.isNullable()) {
return literalValue(operand, timeZone);
}
}
return null;
}
use of org.apache.calcite.rex.RexCall in project calcite by apache.
the class DruidExpressions method toDruidExpression.
/**
* Translates Calcite rexNode to Druid Expression when possible
* @param rexNode rexNode to convert to a Druid Expression
* @param inputRowType input row type of the rexNode to translate
* @param druidRel Druid query
*
* @return Druid Expression or null when can not convert the RexNode
*/
@Nullable
public static String toDruidExpression(final RexNode rexNode, final RelDataType inputRowType, final DruidQuery druidRel) {
SqlKind kind = rexNode.getKind();
SqlTypeName sqlTypeName = rexNode.getType().getSqlTypeName();
if (kind == SqlKind.INPUT_REF) {
final RexInputRef ref = (RexInputRef) rexNode;
final String columnName = inputRowType.getFieldNames().get(ref.getIndex());
if (columnName == null) {
return null;
}
if (druidRel.getDruidTable().timestampFieldName.equals(columnName)) {
return DruidExpressions.fromColumn(DruidTable.DEFAULT_TIMESTAMP_COLUMN);
}
return DruidExpressions.fromColumn(columnName);
}
if (rexNode instanceof RexCall) {
final SqlOperator operator = ((RexCall) rexNode).getOperator();
final DruidSqlOperatorConverter conversion = druidRel.getOperatorConversionMap().get(operator);
if (conversion == null) {
// unknown operator can not translate
return null;
} else {
return conversion.toDruidExpression(rexNode, inputRowType, druidRel);
}
}
if (kind == SqlKind.LITERAL) {
// Translate literal.
if (RexLiteral.isNullLiteral(rexNode)) {
// case the filter/project might yield to unknown let Calcite deal with this for now
return null;
} else if (SqlTypeName.NUMERIC_TYPES.contains(sqlTypeName)) {
return DruidExpressions.numberLiteral((Number) RexLiteral.value(rexNode));
} else if (SqlTypeFamily.INTERVAL_DAY_TIME == sqlTypeName.getFamily()) {
// Calcite represents DAY-TIME intervals in milliseconds.
final long milliseconds = ((Number) RexLiteral.value(rexNode)).longValue();
return DruidExpressions.numberLiteral(milliseconds);
} else if (SqlTypeFamily.INTERVAL_YEAR_MONTH == sqlTypeName.getFamily()) {
// Calcite represents YEAR-MONTH intervals in months.
final long months = ((Number) RexLiteral.value(rexNode)).longValue();
return DruidExpressions.numberLiteral(months);
} else if (SqlTypeName.STRING_TYPES.contains(sqlTypeName)) {
return DruidExpressions.stringLiteral(RexLiteral.stringValue(rexNode));
} else if (SqlTypeName.TIMESTAMP == sqlTypeName || SqlTypeName.DATE == sqlTypeName || SqlTypeName.TIME_WITH_LOCAL_TIME_ZONE == sqlTypeName) {
return DruidExpressions.numberLiteral(DruidDateTimeUtils.literalValue(rexNode, TimeZone.getTimeZone(druidRel.getConnectionConfig().timeZone())).getMillisSinceEpoch());
} else if (SqlTypeName.BOOLEAN == sqlTypeName) {
return DruidExpressions.numberLiteral(RexLiteral.booleanValue(rexNode) ? 1 : 0);
}
}
// Not Literal/InputRef/RexCall or unknown type?
return null;
}
Aggregations