Search in sources :

Example 6 with NlsString

use of org.apache.calcite.util.NlsString in project calcite by apache.

the class RexProgramTest method testSimplifyCastLiteral.

@Test
public void testSimplifyCastLiteral() {
    final List<RexLiteral> literals = new ArrayList<>();
    literals.add(rexBuilder.makeExactLiteral(BigDecimal.ONE, typeFactory.createSqlType(SqlTypeName.INTEGER)));
    literals.add(rexBuilder.makeExactLiteral(BigDecimal.valueOf(2), typeFactory.createSqlType(SqlTypeName.BIGINT)));
    literals.add(rexBuilder.makeExactLiteral(BigDecimal.valueOf(3), typeFactory.createSqlType(SqlTypeName.SMALLINT)));
    literals.add(rexBuilder.makeExactLiteral(BigDecimal.valueOf(4), typeFactory.createSqlType(SqlTypeName.TINYINT)));
    literals.add(rexBuilder.makeExactLiteral(new BigDecimal("1234"), typeFactory.createSqlType(SqlTypeName.DECIMAL, 4, 0)));
    literals.add(rexBuilder.makeExactLiteral(new BigDecimal("123.45"), typeFactory.createSqlType(SqlTypeName.DECIMAL, 5, 2)));
    literals.add(rexBuilder.makeApproxLiteral(new BigDecimal("3.1415"), typeFactory.createSqlType(SqlTypeName.REAL)));
    literals.add(rexBuilder.makeApproxLiteral(BigDecimal.valueOf(Math.E), typeFactory.createSqlType(SqlTypeName.FLOAT)));
    literals.add(rexBuilder.makeApproxLiteral(BigDecimal.valueOf(Math.PI), typeFactory.createSqlType(SqlTypeName.DOUBLE)));
    literals.add(rexBuilder.makeLiteral(true));
    literals.add(rexBuilder.makeLiteral(false));
    literals.add(rexBuilder.makeLiteral("hello world"));
    literals.add(rexBuilder.makeLiteral("1969-07-20 12:34:56"));
    literals.add(rexBuilder.makeLiteral("1969-07-20"));
    literals.add(rexBuilder.makeLiteral("12:34:45"));
    literals.add((RexLiteral) rexBuilder.makeLiteral(new ByteString(new byte[] { 1, 2, -34, 0, -128 }), typeFactory.createSqlType(SqlTypeName.BINARY, 5), false));
    literals.add(rexBuilder.makeDateLiteral(new DateString(1974, 8, 9)));
    literals.add(rexBuilder.makeTimeLiteral(new TimeString(1, 23, 45), 0));
    literals.add(rexBuilder.makeTimestampLiteral(new TimestampString(1974, 8, 9, 1, 23, 45), 0));
    final Multimap<SqlTypeName, RexLiteral> map = LinkedHashMultimap.create();
    for (RexLiteral literal : literals) {
        map.put(literal.getTypeName(), literal);
    }
    final List<RelDataType> types = new ArrayList<>();
    types.add(typeFactory.createSqlType(SqlTypeName.INTEGER));
    types.add(typeFactory.createSqlType(SqlTypeName.BIGINT));
    types.add(typeFactory.createSqlType(SqlTypeName.SMALLINT));
    types.add(typeFactory.createSqlType(SqlTypeName.TINYINT));
    types.add(typeFactory.createSqlType(SqlTypeName.REAL));
    types.add(typeFactory.createSqlType(SqlTypeName.FLOAT));
    types.add(typeFactory.createSqlType(SqlTypeName.DOUBLE));
    types.add(typeFactory.createSqlType(SqlTypeName.BOOLEAN));
    types.add(typeFactory.createSqlType(SqlTypeName.VARCHAR, 10));
    types.add(typeFactory.createSqlType(SqlTypeName.CHAR, 5));
    types.add(typeFactory.createSqlType(SqlTypeName.VARBINARY, 60));
    types.add(typeFactory.createSqlType(SqlTypeName.BINARY, 3));
    types.add(typeFactory.createSqlType(SqlTypeName.TIMESTAMP));
    types.add(typeFactory.createSqlType(SqlTypeName.TIME));
    types.add(typeFactory.createSqlType(SqlTypeName.DATE));
    for (RelDataType fromType : types) {
        for (RelDataType toType : types) {
            if (SqlTypeAssignmentRules.instance(false).canCastFrom(toType.getSqlTypeName(), fromType.getSqlTypeName())) {
                for (RexLiteral literal : map.get(fromType.getSqlTypeName())) {
                    final RexNode cast = rexBuilder.makeCast(toType, literal);
                    if (cast instanceof RexLiteral) {
                        assertThat(cast.getType(), is(toType));
                        // makeCast already simplified
                        continue;
                    }
                    final RexNode simplified = simplify.simplify(cast);
                    boolean expectedSimplify = literal.getTypeName() != toType.getSqlTypeName() || (literal.getTypeName() == SqlTypeName.CHAR && ((NlsString) literal.getValue()).getValue().length() > toType.getPrecision()) || (literal.getTypeName() == SqlTypeName.BINARY && ((ByteString) literal.getValue()).length() > toType.getPrecision());
                    boolean couldSimplify = !cast.equals(simplified);
                    final String reason = (expectedSimplify ? "expected to simplify, but could not: " : "simplified, but did not expect to: ") + cast + " --> " + simplified;
                    assertThat(reason, couldSimplify, is(expectedSimplify));
                }
            }
        }
    }
}
Also used : RexLiteral(org.apache.calcite.rex.RexLiteral) TimeString(org.apache.calcite.util.TimeString) SqlTypeName(org.apache.calcite.sql.type.SqlTypeName) ByteString(org.apache.calcite.avatica.util.ByteString) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) DateString(org.apache.calcite.util.DateString) TimestampWithTimeZoneString(org.apache.calcite.util.TimestampWithTimeZoneString) ByteString(org.apache.calcite.avatica.util.ByteString) TimestampString(org.apache.calcite.util.TimestampString) TimeString(org.apache.calcite.util.TimeString) NlsString(org.apache.calcite.util.NlsString) BigDecimal(java.math.BigDecimal) DateString(org.apache.calcite.util.DateString) NlsString(org.apache.calcite.util.NlsString) TimestampString(org.apache.calcite.util.TimestampString) RexNode(org.apache.calcite.rex.RexNode) Test(org.junit.Test)

Example 7 with NlsString

use of org.apache.calcite.util.NlsString in project calcite by apache.

the class RexBuilder method makeLiteral.

/**
 * Internal method to create a call to a literal. Code outside this package
 * should call one of the type-specific methods such as
 * {@link #makeDateLiteral(DateString)}, {@link #makeLiteral(boolean)},
 * {@link #makeLiteral(String)}.
 *
 * @param o        Value of literal, must be appropriate for the type
 * @param type     Type of literal
 * @param typeName SQL type of literal
 * @return Literal
 */
protected RexLiteral makeLiteral(Comparable o, RelDataType type, SqlTypeName typeName) {
    // All literals except NULL have NOT NULL types.
    type = typeFactory.createTypeWithNullability(type, o == null);
    int p;
    switch(typeName) {
        case CHAR:
            // from the type if necessary.
            assert o instanceof NlsString;
            NlsString nlsString = (NlsString) o;
            if ((nlsString.getCollation() == null) || (nlsString.getCharset() == null)) {
                assert type.getSqlTypeName() == SqlTypeName.CHAR;
                assert type.getCharset().name() != null;
                assert type.getCollation() != null;
                o = new NlsString(nlsString.getValue(), type.getCharset().name(), type.getCollation());
            }
            break;
        case TIME:
            assert o instanceof TimeString;
            p = type.getPrecision();
            if (p == RelDataType.PRECISION_NOT_SPECIFIED) {
                p = 0;
            }
            o = ((TimeString) o).round(p);
            break;
        case TIME_WITH_LOCAL_TIME_ZONE:
            assert o instanceof TimeString;
            p = type.getPrecision();
            if (p == RelDataType.PRECISION_NOT_SPECIFIED) {
                p = 0;
            }
            o = ((TimeString) o).round(p);
            break;
        case TIMESTAMP:
            assert o instanceof TimestampString;
            p = type.getPrecision();
            if (p == RelDataType.PRECISION_NOT_SPECIFIED) {
                p = 0;
            }
            o = ((TimestampString) o).round(p);
            break;
        case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
            assert o instanceof TimestampString;
            p = type.getPrecision();
            if (p == RelDataType.PRECISION_NOT_SPECIFIED) {
                p = 0;
            }
            o = ((TimestampString) o).round(p);
    }
    return new RexLiteral(o, type, typeName);
}
Also used : TimeString(org.apache.calcite.util.TimeString) NlsString(org.apache.calcite.util.NlsString) TimestampString(org.apache.calcite.util.TimestampString)

Example 8 with NlsString

use of org.apache.calcite.util.NlsString in project drill by axbaretto.

the class DrillValuesRelBase method writeLiteral.

private static void writeLiteral(RexLiteral literal, JsonOutput out) throws IOException {
    switch(literal.getType().getSqlTypeName()) {
        case BIGINT:
            if (isLiteralNull(literal)) {
                out.writeBigIntNull();
            } else {
                out.writeBigInt((((BigDecimal) literal.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)).longValue());
            }
            return;
        case BOOLEAN:
            if (isLiteralNull(literal)) {
                out.writeBooleanNull();
            } else {
                out.writeBoolean((Boolean) literal.getValue());
            }
            return;
        case CHAR:
            if (isLiteralNull(literal)) {
                out.writeVarcharNull();
            } else {
                // Since Calcite treats string literals as fixed char and adds trailing spaces to the strings to make them the
                // same length, here we do an rtrim() to get the string without the trailing spaces. If we don't rtrim, the comparison
                // with Drill's varchar column values would not return a match.
                // TODO: However, note that if the user had explicitly added spaces in the string literals then even those would get
                // trimmed, so this exposes another issue that needs to be resolved.
                out.writeVarChar(((NlsString) literal.getValue()).rtrim().getValue());
            }
            return;
        case DOUBLE:
            if (isLiteralNull(literal)) {
                out.writeDoubleNull();
            } else {
                out.writeDouble(((BigDecimal) literal.getValue()).doubleValue());
            }
            return;
        case FLOAT:
            if (isLiteralNull(literal)) {
                out.writeFloatNull();
            } else {
                out.writeFloat(((BigDecimal) literal.getValue()).floatValue());
            }
            return;
        case INTEGER:
            if (isLiteralNull(literal)) {
                out.writeIntNull();
            } else {
                out.writeInt((((BigDecimal) literal.getValue()).setScale(0, BigDecimal.ROUND_HALF_UP)).intValue());
            }
            return;
        case DECIMAL:
            if (isLiteralNull(literal)) {
                out.writeDoubleNull();
            } else {
                out.writeDouble(((BigDecimal) literal.getValue()).doubleValue());
            }
            logger.warn("Converting exact decimal into approximate decimal. Should be fixed once full decimal support is implemented.");
            return;
        case VARCHAR:
            if (isLiteralNull(literal)) {
                out.writeVarcharNull();
            } else {
                out.writeVarChar(((NlsString) literal.getValue()).getValue());
            }
            return;
        case SYMBOL:
            if (isLiteralNull(literal)) {
                out.writeVarcharNull();
            } else {
                out.writeVarChar(literal.getValue().toString());
            }
            return;
        case DATE:
            if (isLiteralNull(literal)) {
                out.writeDateNull();
            } else {
                out.writeDate(new DateTime(literal.getValue()));
            }
            return;
        case TIME:
            if (isLiteralNull(literal)) {
                out.writeTimeNull();
            } else {
                out.writeTime(new DateTime(literal.getValue()));
            }
            return;
        case TIMESTAMP:
            if (isLiteralNull(literal)) {
                out.writeTimestampNull();
            } else {
                out.writeTimestamp(new DateTime(literal.getValue()));
            }
            return;
        case INTERVAL_YEAR:
        case INTERVAL_YEAR_MONTH:
        case INTERVAL_MONTH:
            if (isLiteralNull(literal)) {
                out.writeIntervalNull();
            } else {
                int months = ((BigDecimal) (literal.getValue())).intValue();
                out.writeInterval(new Period().plusMonths(months));
            }
            return;
        case INTERVAL_DAY:
        case INTERVAL_DAY_HOUR:
        case INTERVAL_DAY_MINUTE:
        case INTERVAL_DAY_SECOND:
        case INTERVAL_HOUR:
        case INTERVAL_HOUR_MINUTE:
        case INTERVAL_HOUR_SECOND:
        case INTERVAL_MINUTE:
        case INTERVAL_MINUTE_SECOND:
        case INTERVAL_SECOND:
            if (isLiteralNull(literal)) {
                out.writeIntervalNull();
            } else {
                long millis = ((BigDecimal) (literal.getValue())).longValue();
                int days = (int) (millis / DateTimeConstants.MILLIS_PER_DAY);
                millis = millis - (days * DateTimeConstants.MILLIS_PER_DAY);
                out.writeInterval(new Period().plusDays(days).plusMillis((int) millis));
            }
            return;
        case NULL:
            out.writeUntypedNull();
            return;
        case ANY:
        default:
            throw new UnsupportedOperationException(String.format("Unable to convert the value of %s and type %s to a Drill constant expression.", literal, literal.getType().getSqlTypeName()));
    }
}
Also used : NlsString(org.apache.calcite.util.NlsString) Period(org.joda.time.Period) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal)

Example 9 with NlsString

use of org.apache.calcite.util.NlsString in project drill by apache.

the class DescribeTableHandler method rewrite.

/**
 * Rewrite the parse tree as SELECT ... FROM INFORMATION_SCHEMA.COLUMNS ...
 */
@Override
public SqlNode rewrite(SqlNode sqlNode) throws ForemanSetupException {
    DrillSqlDescribeTable node = unwrap(sqlNode, DrillSqlDescribeTable.class);
    try {
        List<SqlNode> selectList = Arrays.asList(new SqlIdentifier(COLS_COL_COLUMN_NAME, SqlParserPos.ZERO), new SqlIdentifier(COLS_COL_DATA_TYPE, SqlParserPos.ZERO), new SqlIdentifier(COLS_COL_IS_NULLABLE, SqlParserPos.ZERO));
        SqlNode fromClause = new SqlIdentifier(Arrays.asList(IS_SCHEMA_NAME, InfoSchemaTableType.COLUMNS.name()), SqlParserPos.ZERO);
        SchemaPlus defaultSchema = config.getConverter().getDefaultSchema();
        List<String> schemaPathGivenInCmd = Util.skipLast(node.getTable().names);
        SchemaPlus schema = SchemaUtilites.findSchema(defaultSchema, schemaPathGivenInCmd);
        if (schema == null) {
            SchemaUtilites.throwSchemaNotFoundException(defaultSchema, SchemaUtilites.getSchemaPath(schemaPathGivenInCmd));
        }
        if (SchemaUtilites.isRootSchema(schema)) {
            throw UserException.validationError().message("No schema selected.").build(logger);
        }
        // find resolved schema path
        AbstractSchema drillSchema = SchemaUtilites.unwrapAsDrillSchemaInstance(schema);
        String schemaPath = drillSchema.getFullSchemaName();
        String tableName = Util.last(node.getTable().names);
        if (schema.getTable(tableName) == null) {
            throw UserException.validationError().message("Unknown table [%s] in schema [%s]", tableName, schemaPath).build(logger);
        }
        SqlNode schemaCondition = null;
        if (!SchemaUtilites.isRootSchema(schema)) {
            schemaCondition = DrillParserUtil.createCondition(new SqlIdentifier(SHRD_COL_TABLE_SCHEMA, SqlParserPos.ZERO), SqlStdOperatorTable.EQUALS, SqlLiteral.createCharString(schemaPath, Util.getDefaultCharset().name(), SqlParserPos.ZERO));
        }
        SqlNode tableNameColumn = new SqlIdentifier(SHRD_COL_TABLE_NAME, SqlParserPos.ZERO);
        // if table names are case insensitive, wrap column values and condition in lower function
        if (!drillSchema.areTableNamesCaseSensitive()) {
            tableNameColumn = SqlStdOperatorTable.LOWER.createCall(SqlParserPos.ZERO, tableNameColumn);
            tableName = tableName.toLowerCase();
        }
        SqlNode where = DrillParserUtil.createCondition(tableNameColumn, SqlStdOperatorTable.EQUALS, SqlLiteral.createCharString(tableName, Util.getDefaultCharset().name(), SqlParserPos.ZERO));
        where = DrillParserUtil.createCondition(schemaCondition, SqlStdOperatorTable.AND, where);
        SqlNode columnFilter = null;
        if (node.getColumn() != null) {
            columnFilter = DrillParserUtil.createCondition(SqlStdOperatorTable.LOWER.createCall(SqlParserPos.ZERO, new SqlIdentifier(COLS_COL_COLUMN_NAME, SqlParserPos.ZERO)), SqlStdOperatorTable.EQUALS, SqlLiteral.createCharString(node.getColumn().toString().toLowerCase(), Util.getDefaultCharset().name(), SqlParserPos.ZERO));
        } else if (node.getColumnQualifier() != null) {
            SqlNode columnQualifier = node.getColumnQualifier();
            SqlNode column = new SqlIdentifier(COLS_COL_COLUMN_NAME, SqlParserPos.ZERO);
            if (columnQualifier instanceof SqlCharStringLiteral) {
                NlsString conditionString = ((SqlCharStringLiteral) columnQualifier).getNlsString();
                columnQualifier = SqlCharStringLiteral.createCharString(conditionString.getValue().toLowerCase(), conditionString.getCharsetName(), columnQualifier.getParserPosition());
                column = SqlStdOperatorTable.LOWER.createCall(SqlParserPos.ZERO, column);
            }
            columnFilter = DrillParserUtil.createCondition(column, SqlStdOperatorTable.LIKE, columnQualifier);
        }
        where = DrillParserUtil.createCondition(where, SqlStdOperatorTable.AND, columnFilter);
        return new SqlSelect(SqlParserPos.ZERO, null, new SqlNodeList(selectList, SqlParserPos.ZERO), fromClause, where, null, null, null, null, null, null);
    } catch (Exception ex) {
        throw UserException.planError(ex).message("Error while rewriting DESCRIBE query: %d", ex.getMessage()).build(logger);
    }
}
Also used : SchemaPlus(org.apache.calcite.schema.SchemaPlus) NlsString(org.apache.calcite.util.NlsString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) UserException(org.apache.drill.common.exceptions.UserException) ValidationException(org.apache.calcite.tools.ValidationException) ForemanSetupException(org.apache.drill.exec.work.foreman.ForemanSetupException) RelConversionException(org.apache.calcite.tools.RelConversionException) SqlSelect(org.apache.calcite.sql.SqlSelect) DrillSqlDescribeTable(org.apache.drill.exec.planner.sql.parser.DrillSqlDescribeTable) AbstractSchema(org.apache.drill.exec.store.AbstractSchema) NlsString(org.apache.calcite.util.NlsString) SqlNodeList(org.apache.calcite.sql.SqlNodeList) SqlCharStringLiteral(org.apache.calcite.sql.SqlCharStringLiteral) SqlNode(org.apache.calcite.sql.SqlNode)

Example 10 with NlsString

use of org.apache.calcite.util.NlsString in project drill by apache.

the class SimpleRexRemap method rewriteEqualOnCharToLike.

public RexNode rewriteEqualOnCharToLike(RexNode expr, Map<RexNode, LogicalExpression> equalOnCastCharExprs) {
    Map<RexNode, RexNode> srcToReplace = Maps.newIdentityHashMap();
    for (Map.Entry<RexNode, LogicalExpression> entry : equalOnCastCharExprs.entrySet()) {
        RexNode equalOp = entry.getKey();
        LogicalExpression opInput = entry.getValue();
        final List<RexNode> operands = ((RexCall) equalOp).getOperands();
        RexLiteral newLiteral = null;
        RexNode input = null;
        if (operands.size() == 2) {
            RexLiteral oplit = null;
            if (operands.get(0) instanceof RexLiteral) {
                oplit = (RexLiteral) operands.get(0);
                if (oplit.getTypeName() == SqlTypeName.CHAR) {
                    newLiteral = builder.makeLiteral(((NlsString) oplit.getValue()).getValue() + "%");
                    input = operands.get(1);
                }
            } else if (operands.get(1) instanceof RexLiteral) {
                oplit = (RexLiteral) operands.get(1);
                if (oplit.getTypeName() == SqlTypeName.CHAR) {
                    newLiteral = builder.makeLiteral(((NlsString) oplit.getValue()).getValue() + "%");
                    input = operands.get(0);
                }
            }
        }
        if (newLiteral != null) {
            srcToReplace.put(equalOp, builder.makeCall(SqlStdOperatorTable.LIKE, input, newLiteral));
        }
    }
    if (srcToReplace.size() > 0) {
        RexReplace replacer = new RexReplace(srcToReplace);
        RexNode resultRex = expr.accept(replacer);
        return resultRex;
    }
    return expr;
}
Also used : RexCall(org.apache.calcite.rex.RexCall) LogicalExpression(org.apache.drill.common.expression.LogicalExpression) RexLiteral(org.apache.calcite.rex.RexLiteral) NlsString(org.apache.calcite.util.NlsString) Map(java.util.Map) ImmutableMap(org.apache.drill.shaded.guava.com.google.common.collect.ImmutableMap) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

NlsString (org.apache.calcite.util.NlsString)32 BigDecimal (java.math.BigDecimal)13 TimestampString (org.apache.calcite.util.TimestampString)9 DateString (org.apache.calcite.util.DateString)8 RelDataType (org.apache.calcite.rel.type.RelDataType)7 TimeString (org.apache.calcite.util.TimeString)7 ByteString (org.apache.calcite.avatica.util.ByteString)6 RexLiteral (org.apache.calcite.rex.RexLiteral)6 RexNode (org.apache.calcite.rex.RexNode)6 SqlNode (org.apache.calcite.sql.SqlNode)6 RexCall (org.apache.calcite.rex.RexCall)5 Charset (java.nio.charset.Charset)4 ArrayList (java.util.ArrayList)4 Calendar (java.util.Calendar)4 SqlCharStringLiteral (org.apache.calcite.sql.SqlCharStringLiteral)4 SqlCollation (org.apache.calcite.sql.SqlCollation)4 SqlTypeName (org.apache.calcite.sql.type.SqlTypeName)4 ImmutableList (com.google.common.collect.ImmutableList)3 SimpleDateFormat (java.text.SimpleDateFormat)3 List (java.util.List)3