Search in sources :

Example 36 with RexLiteral

use of org.apache.calcite.rex.RexLiteral in project calcite by apache.

the class RexTransformerTest method testExactLiteral.

/**
 * Test case for
 * <a href="https://issues.apache.org/jira/browse/CALCITE-814">[CALCITE-814]
 * RexBuilder reverses precision and scale of DECIMAL literal</a>
 * and
 * <a href="https://issues.apache.org/jira/browse/CALCITE-1344">[CALCITE-1344]
 * Incorrect inferred precision when BigDecimal value is less than 1</a>.
 */
@Test
public void testExactLiteral() {
    final RexLiteral literal = rexBuilder.makeExactLiteral(new BigDecimal("-1234.56"));
    assertThat(literal.getType().getFullTypeString(), is("DECIMAL(6, 2) NOT NULL"));
    assertThat(literal.getValue().toString(), is("-1234.56"));
    final RexLiteral literal2 = rexBuilder.makeExactLiteral(new BigDecimal("1234.56"));
    assertThat(literal2.getType().getFullTypeString(), is("DECIMAL(6, 2) NOT NULL"));
    assertThat(literal2.getValue().toString(), is("1234.56"));
    final RexLiteral literal3 = rexBuilder.makeExactLiteral(new BigDecimal("0.0123456"));
    assertThat(literal3.getType().getFullTypeString(), is("DECIMAL(8, 7) NOT NULL"));
    assertThat(literal3.getValue().toString(), is("0.0123456"));
    final RexLiteral literal4 = rexBuilder.makeExactLiteral(new BigDecimal("0.01234560"));
    assertThat(literal4.getType().getFullTypeString(), is("DECIMAL(9, 8) NOT NULL"));
    assertThat(literal4.getValue().toString(), is("0.01234560"));
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) BigDecimal(java.math.BigDecimal) Test(org.junit.Test)

Example 37 with RexLiteral

use of org.apache.calcite.rex.RexLiteral 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 38 with RexLiteral

use of org.apache.calcite.rex.RexLiteral in project calcite by apache.

the class DruidJsonFilter method toBoundDruidFilter.

/**
 * @param rexNode    rexNode to translate
 * @param rowType    row type associated to Filter
 * @param druidQuery druid query
 *
 * @return valid Druid Json Bound Filter or null if it can not translate the rexNode.
 */
@Nullable
private static DruidJsonFilter toBoundDruidFilter(RexNode rexNode, RelDataType rowType, DruidQuery druidQuery) {
    final RexCall rexCall = (RexCall) rexNode;
    final RexLiteral rexLiteral;
    if (rexCall.getOperands().size() < 2) {
        return null;
    }
    final RexNode refNode;
    final RexNode lhs = rexCall.getOperands().get(0);
    final RexNode rhs = rexCall.getOperands().get(1);
    final boolean lhsIsRef;
    if (lhs.getKind() == SqlKind.LITERAL && rhs.getKind() != SqlKind.LITERAL) {
        rexLiteral = (RexLiteral) lhs;
        refNode = rhs;
        lhsIsRef = false;
    } else if (rhs.getKind() == SqlKind.LITERAL && lhs.getKind() != SqlKind.LITERAL) {
        rexLiteral = (RexLiteral) rhs;
        refNode = lhs;
        lhsIsRef = true;
    } else {
        // must have at least one literal
        return null;
    }
    if (RexLiteral.isNullLiteral(rexLiteral)) {
        // we are not handling is NULL filter here thus we bail out if Literal is null
        return null;
    }
    final String literalValue = DruidJsonFilter.toDruidLiteral(rexLiteral, rowType, druidQuery);
    if (literalValue == null) {
        // can not translate literal better bail out
        return null;
    }
    final boolean isNumeric = refNode.getType().getFamily() == SqlTypeFamily.NUMERIC || rexLiteral.getType().getFamily() == SqlTypeFamily.NUMERIC;
    final Pair<String, ExtractionFunction> druidColumn = DruidQuery.toDruidColumn(refNode, rowType, druidQuery);
    final String columnName = druidColumn.left;
    final ExtractionFunction extractionFunction = druidColumn.right;
    if (columnName == null) {
        // no column name better bail out.
        return null;
    }
    switch(rexCall.getKind()) {
        case LESS_THAN_OR_EQUAL:
        case LESS_THAN:
            if (lhsIsRef) {
                return new JsonBound(columnName, null, false, literalValue, rexCall.getKind() == SqlKind.LESS_THAN, isNumeric, extractionFunction);
            } else {
                return new JsonBound(columnName, literalValue, rexCall.getKind() == SqlKind.LESS_THAN, null, false, isNumeric, extractionFunction);
            }
        case GREATER_THAN_OR_EQUAL:
        case GREATER_THAN:
            if (!lhsIsRef) {
                return new JsonBound(columnName, null, false, literalValue, rexCall.getKind() == SqlKind.GREATER_THAN, isNumeric, extractionFunction);
            } else {
                return new JsonBound(columnName, literalValue, rexCall.getKind() == SqlKind.GREATER_THAN, null, false, isNumeric, extractionFunction);
            }
        default:
            return null;
    }
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexLiteral(org.apache.calcite.rex.RexLiteral) TimestampString(org.apache.calcite.util.TimestampString) RexNode(org.apache.calcite.rex.RexNode) Nullable(javax.annotation.Nullable)

Example 39 with RexLiteral

use of org.apache.calcite.rex.RexLiteral in project calcite by apache.

the class DruidJsonFilter method toEqualityKindDruidFilter.

/**
 * @param rexNode    rexNode to translate to Druid Json Filter
 * @param rowType    rowType associated to rexNode
 * @param druidQuery druid query
 *
 * @return Druid Json filter or null if it can not translate
 */
@Nullable
private static DruidJsonFilter toEqualityKindDruidFilter(RexNode rexNode, RelDataType rowType, DruidQuery druidQuery) {
    if (rexNode.getKind() != SqlKind.EQUALS && rexNode.getKind() != SqlKind.NOT_EQUALS) {
        throw new AssertionError(DruidQuery.format("Expecting EQUALS or NOT_EQUALS but got [%s]", rexNode.getKind()));
    }
    final RexCall rexCall = (RexCall) rexNode;
    if (rexCall.getOperands().size() < 2) {
        return null;
    }
    final RexLiteral rexLiteral;
    final RexNode refNode;
    final RexNode lhs = rexCall.getOperands().get(0);
    final RexNode rhs = rexCall.getOperands().get(1);
    if (lhs.getKind() == SqlKind.LITERAL && rhs.getKind() != SqlKind.LITERAL) {
        rexLiteral = (RexLiteral) lhs;
        refNode = rhs;
    } else if (rhs.getKind() == SqlKind.LITERAL && lhs.getKind() != SqlKind.LITERAL) {
        rexLiteral = (RexLiteral) rhs;
        refNode = lhs;
    } else {
        // must have at least one literal
        return null;
    }
    if (RexLiteral.isNullLiteral(rexLiteral)) {
        // we are not handling is NULL filter here thus we bail out if Literal is null
        return null;
    }
    final String literalValue = toDruidLiteral(rexLiteral, rowType, druidQuery);
    if (literalValue == null) {
        // can not translate literal better bail out
        return null;
    }
    final boolean isNumeric = refNode.getType().getFamily() == SqlTypeFamily.NUMERIC || rexLiteral.getType().getFamily() == SqlTypeFamily.NUMERIC;
    final Pair<String, ExtractionFunction> druidColumn = DruidQuery.toDruidColumn(refNode, rowType, druidQuery);
    final String columnName = druidColumn.left;
    final ExtractionFunction extractionFunction = druidColumn.right;
    if (columnName == null) {
        // no column name better bail out.
        return null;
    }
    final DruidJsonFilter partialFilter;
    if (isNumeric) {
        // need bound filter since it one of operands is numeric
        partialFilter = new JsonBound(columnName, literalValue, false, literalValue, false, true, extractionFunction);
    } else {
        partialFilter = new JsonSelector(columnName, literalValue, extractionFunction);
    }
    if (rexNode.getKind() == SqlKind.EQUALS) {
        return partialFilter;
    }
    return toNotDruidFilter(partialFilter);
}
Also used : RexCall(org.apache.calcite.rex.RexCall) RexLiteral(org.apache.calcite.rex.RexLiteral) TimestampString(org.apache.calcite.util.TimestampString) RexNode(org.apache.calcite.rex.RexNode) Nullable(javax.annotation.Nullable)

Example 40 with RexLiteral

use of org.apache.calcite.rex.RexLiteral in project calcite by apache.

the class DruidJsonFilter method toDruidLiteral.

/**
 * @param rexNode    rexNode to translate to Druid literal equivalante
 * @param rowType    rowType associated to rexNode
 * @param druidQuery druid Query
 *
 * @return non null string or null if it can not translate to valid Druid equivalent
 */
@Nullable
private static String toDruidLiteral(RexNode rexNode, RelDataType rowType, DruidQuery druidQuery) {
    final SimpleDateFormat dateFormatter = new SimpleDateFormat(TimeExtractionFunction.ISO_TIME_FORMAT, Locale.ROOT);
    final String timeZone = druidQuery.getConnectionConfig().timeZone();
    if (timeZone != null) {
        dateFormatter.setTimeZone(TimeZone.getTimeZone(timeZone));
    }
    final String val;
    final RexLiteral rhsLiteral = (RexLiteral) rexNode;
    if (SqlTypeName.NUMERIC_TYPES.contains(rhsLiteral.getTypeName())) {
        val = String.valueOf(RexLiteral.value(rhsLiteral));
    } else if (SqlTypeName.CHAR_TYPES.contains(rhsLiteral.getTypeName())) {
        val = String.valueOf(RexLiteral.stringValue(rhsLiteral));
    } else if (SqlTypeName.TIMESTAMP == rhsLiteral.getTypeName() || SqlTypeName.DATE == rhsLiteral.getTypeName() || SqlTypeName.TIMESTAMP_WITH_LOCAL_TIME_ZONE == rhsLiteral.getTypeName()) {
        TimestampString timestampString = DruidDateTimeUtils.literalValue(rexNode, TimeZone.getTimeZone(timeZone));
        if (timestampString == null) {
            throw new AssertionError("Cannot translate Literal" + rexNode + " of type " + rhsLiteral.getTypeName() + " to TimestampString");
        }
        // @TODO this is unnecessary we can send time as Long (eg millis since epoch) to druid
        val = dateFormatter.format(timestampString.getMillisSinceEpoch());
    } else {
        // Don't know how to filter on this kind of literal.
        val = null;
    }
    return val;
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) TimestampString(org.apache.calcite.util.TimestampString) TimestampString(org.apache.calcite.util.TimestampString) SimpleDateFormat(java.text.SimpleDateFormat) Nullable(javax.annotation.Nullable)

Aggregations

RexLiteral (org.apache.calcite.rex.RexLiteral)150 RexNode (org.apache.calcite.rex.RexNode)92 ArrayList (java.util.ArrayList)51 RelDataType (org.apache.calcite.rel.type.RelDataType)45 RexCall (org.apache.calcite.rex.RexCall)45 Test (org.junit.Test)32 BigDecimal (java.math.BigDecimal)28 RexInputRef (org.apache.calcite.rex.RexInputRef)26 RelNode (org.apache.calcite.rel.RelNode)22 ImmutableList (com.google.common.collect.ImmutableList)18 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)17 List (java.util.List)16 Map (java.util.Map)16 RexBuilder (org.apache.calcite.rex.RexBuilder)16 AggregateCall (org.apache.calcite.rel.core.AggregateCall)15 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)12 RexLiteral (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexLiteral)11 NlsString (org.apache.calcite.util.NlsString)11 HashMap (java.util.HashMap)10 RexNode (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)10