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));
}
}
}
}
}
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);
}
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()));
}
}
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);
}
}
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;
}
Aggregations