Search in sources :

Example 36 with RexCall

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));
}
Also used : RexCall(org.apache.calcite.rex.RexCall) SqlOperator(org.apache.calcite.sql.SqlOperator) RexNode(org.apache.calcite.rex.RexNode) Test(org.junit.Test)

Example 37 with RexCall

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"));
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RexLiteral(org.apache.calcite.rex.RexLiteral) RelNode(org.apache.calcite.rel.RelNode) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) RexTableInputRef(org.apache.calcite.rex.RexTableInputRef) RexNode(org.apache.calcite.rex.RexNode) Test(org.junit.Test)

Example 38 with RexCall

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));
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RelMetadataQuery(org.apache.calcite.rel.metadata.RelMetadataQuery) RelNode(org.apache.calcite.rel.RelNode) ArrayList(java.util.ArrayList) RelOptPredicateList(org.apache.calcite.plan.RelOptPredicateList) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) RexTableInputRef(org.apache.calcite.rex.RexTableInputRef) RexNode(org.apache.calcite.rex.RexNode) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 39 with RexCall

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;
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexLiteral(org.apache.calcite.rex.RexLiteral) DateString(org.apache.calcite.util.DateString) TimestampWithTimeZoneString(org.apache.calcite.util.TimestampWithTimeZoneString) RelDataType(org.apache.calcite.rel.type.RelDataType) TimestampString(org.apache.calcite.util.TimestampString) RexNode(org.apache.calcite.rex.RexNode) Nullable(javax.annotation.Nullable)

Example 40 with RexCall

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;
}
Also used : RexCall(org.apache.calcite.rex.RexCall) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) SqlOperator(org.apache.calcite.sql.SqlOperator) RexInputRef(org.apache.calcite.rex.RexInputRef) SqlKind(org.apache.calcite.sql.SqlKind) Nullable(javax.annotation.Nullable)

Aggregations

RexCall (org.apache.calcite.rex.RexCall)213 RexNode (org.apache.calcite.rex.RexNode)172 RexInputRef (org.apache.calcite.rex.RexInputRef)61 ArrayList (java.util.ArrayList)59 RexLiteral (org.apache.calcite.rex.RexLiteral)44 Nullable (javax.annotation.Nullable)35 RelNode (org.apache.calcite.rel.RelNode)26 RelDataType (org.apache.calcite.rel.type.RelDataType)24 SqlOperator (org.apache.calcite.sql.SqlOperator)23 List (java.util.List)22 RexBuilder (org.apache.calcite.rex.RexBuilder)22 DruidExpression (org.apache.druid.sql.calcite.expression.DruidExpression)19 SqlKind (org.apache.calcite.sql.SqlKind)14 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)14 RelOptUtil (org.apache.calcite.plan.RelOptUtil)11 PostAggregator (org.apache.druid.query.aggregation.PostAggregator)11 RexCall (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexCall)10 RexTableInputRef (org.apache.calcite.rex.RexTableInputRef)10 TimeUnitRange (org.apache.calcite.avatica.util.TimeUnitRange)9 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)9