use of org.apache.calcite.util.NlsString in project drill by axbaretto.
the class PreProcessLogicalRel method visit.
@Override
public RelNode visit(LogicalProject project) {
final List<RexNode> projExpr = Lists.newArrayList();
for (RexNode rexNode : project.getChildExps()) {
projExpr.add(rexNode.accept(unwrappingExpressionVisitor));
}
project = project.copy(project.getTraitSet(), project.getInput(), projExpr, project.getRowType());
List<RexNode> exprList = new ArrayList<>();
boolean rewrite = false;
for (RexNode rex : project.getChildExps()) {
RexNode newExpr = rex;
if (rex instanceof RexCall) {
RexCall function = (RexCall) rex;
String functionName = function.getOperator().getName();
int nArgs = function.getOperands().size();
// check if its a convert_from or convert_to function
if (functionName.equalsIgnoreCase("convert_from") || functionName.equalsIgnoreCase("convert_to")) {
String literal;
if (nArgs == 2) {
if (function.getOperands().get(1) instanceof RexLiteral) {
try {
literal = ((NlsString) (((RexLiteral) function.getOperands().get(1)).getValue())).getValue();
} catch (final ClassCastException e) {
// Caused by user entering a value with a non-string literal
throw getConvertFunctionInvalidTypeException(function);
}
} else {
// caused by user entering a non-literal
throw getConvertFunctionInvalidTypeException(function);
}
} else {
// Second operand is missing
throw UserException.parseError().message("'%s' expects a string literal as a second argument.", functionName).build(logger);
}
RexBuilder builder = new RexBuilder(factory);
// construct the new function name based on the input argument
String newFunctionName = functionName + literal;
// Look up the new function name in the drill operator table
List<SqlOperator> operatorList = table.getSqlOperator(newFunctionName);
if (operatorList.size() == 0) {
// User typed in an invalid type name
throw getConvertFunctionException(functionName, literal);
}
SqlFunction newFunction = null;
// Find the SqlFunction with the correct args
for (SqlOperator op : operatorList) {
if (op.getOperandTypeChecker().getOperandCountRange().isValidCount(nArgs - 1)) {
newFunction = (SqlFunction) op;
break;
}
}
if (newFunction == null) {
// we are here because we found some dummy convert function. (See DummyConvertFrom and DummyConvertTo)
throw getConvertFunctionException(functionName, literal);
}
// create the new expression to be used in the rewritten project
newExpr = builder.makeCall(newFunction, function.getOperands().subList(0, 1));
rewrite = true;
}
}
exprList.add(newExpr);
}
if (rewrite == true) {
LogicalProject newProject = project.copy(project.getTraitSet(), project.getInput(0), exprList, project.getRowType());
return visitChild(newProject, 0, project.getInput());
}
return visitChild(project, 0, project.getInput());
}
use of org.apache.calcite.util.NlsString in project calcite by apache.
the class RexBuilder method makeLiteral.
/**
* Creates a literal of a given type. The value is assumed to be
* compatible with the type.
*
* @param value Value
* @param type Type
* @param allowCast Whether to allow a cast. If false, value is always a
* {@link RexLiteral} but may not be the exact type
* @return Simple literal, or cast simple literal
*/
public RexNode makeLiteral(Object value, RelDataType type, boolean allowCast) {
if (value == null) {
return makeCast(type, constantNull);
}
if (type.isNullable()) {
final RelDataType typeNotNull = typeFactory.createTypeWithNullability(type, false);
RexNode literalNotNull = makeLiteral(value, typeNotNull, allowCast);
return makeAbstractCast(type, literalNotNull);
}
value = clean(value, type);
RexLiteral literal;
final List<RexNode> operands;
switch(type.getSqlTypeName()) {
case CHAR:
return makeCharLiteral(padRight((NlsString) value, type.getPrecision()));
case VARCHAR:
literal = makeCharLiteral((NlsString) value);
if (allowCast) {
return makeCast(type, literal);
} else {
return literal;
}
case BINARY:
return makeBinaryLiteral(padRight((ByteString) value, type.getPrecision()));
case VARBINARY:
literal = makeBinaryLiteral((ByteString) value);
if (allowCast) {
return makeCast(type, literal);
} else {
return literal;
}
case TINYINT:
case SMALLINT:
case INTEGER:
case BIGINT:
case DECIMAL:
return makeExactLiteral((BigDecimal) value, type);
case FLOAT:
case REAL:
case DOUBLE:
return makeApproxLiteral((BigDecimal) value, type);
case BOOLEAN:
return (Boolean) value ? booleanTrue : booleanFalse;
case TIME:
return makeTimeLiteral((TimeString) value, type.getPrecision());
case TIME_WITH_LOCAL_TIME_ZONE:
return makeTimeWithLocalTimeZoneLiteral((TimeString) value, type.getPrecision());
case DATE:
return makeDateLiteral((DateString) value);
case TIMESTAMP:
return makeTimestampLiteral((TimestampString) value, type.getPrecision());
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
return makeTimestampWithLocalTimeZoneLiteral((TimestampString) value, type.getPrecision());
case INTERVAL_YEAR:
case INTERVAL_YEAR_MONTH:
case INTERVAL_MONTH:
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:
return makeIntervalLiteral((BigDecimal) value, type.getIntervalQualifier());
case MAP:
final MapSqlType mapType = (MapSqlType) type;
@SuppressWarnings("unchecked") final Map<Object, Object> map = (Map) value;
operands = new ArrayList<>();
for (Map.Entry<Object, Object> entry : map.entrySet()) {
operands.add(makeLiteral(entry.getKey(), mapType.getKeyType(), allowCast));
operands.add(makeLiteral(entry.getValue(), mapType.getValueType(), allowCast));
}
return makeCall(SqlStdOperatorTable.MAP_VALUE_CONSTRUCTOR, operands);
case ARRAY:
final ArraySqlType arrayType = (ArraySqlType) type;
@SuppressWarnings("unchecked") final List<Object> listValue = (List) value;
operands = new ArrayList<>();
for (Object entry : listValue) {
operands.add(makeLiteral(entry, arrayType.getComponentType(), allowCast));
}
return makeCall(SqlStdOperatorTable.ARRAY_VALUE_CONSTRUCTOR, operands);
case MULTISET:
final MultisetSqlType multisetType = (MultisetSqlType) type;
operands = new ArrayList<>();
for (Object entry : (List) value) {
final RexNode e = entry instanceof RexLiteral ? (RexNode) entry : makeLiteral(entry, multisetType.getComponentType(), allowCast);
operands.add(e);
}
if (allowCast) {
return makeCall(SqlStdOperatorTable.MULTISET_VALUE, operands);
} else {
return new RexLiteral((Comparable) FlatLists.of(operands), type, type.getSqlTypeName());
}
case ROW:
operands = new ArrayList<>();
// noinspection unchecked
for (Pair<RelDataTypeField, Object> pair : Pair.zip(type.getFieldList(), (List<Object>) value)) {
final RexNode e = pair.right instanceof RexLiteral ? (RexNode) pair.right : makeLiteral(pair.right, pair.left.getType(), allowCast);
operands.add(e);
}
return new RexLiteral((Comparable) FlatLists.of(operands), type, type.getSqlTypeName());
case ANY:
return makeLiteral(value, guessType(value), allowCast);
default:
throw Util.unexpected(type.getSqlTypeName());
}
}
use of org.apache.calcite.util.NlsString in project calcite by apache.
the class RexLiteral method printAsJava.
/**
* Prints a value as a Java string. The value must be consistent with the
* type, as per {@link #valueMatchesType}.
*
* <p>Typical return values:
*
* <ul>
* <li>true</li>
* <li>null</li>
* <li>"Hello, world!"</li>
* <li>1.25</li>
* <li>1234ABCD</li>
* </ul>
*
* @param value Value
* @param pw Writer to write to
* @param typeName Type family
*/
private static void printAsJava(Comparable value, PrintWriter pw, SqlTypeName typeName, boolean java) {
switch(typeName) {
case CHAR:
NlsString nlsString = (NlsString) value;
if (java) {
Util.printJavaString(pw, nlsString.getValue(), true);
} else {
boolean includeCharset = (nlsString.getCharsetName() != null) && !nlsString.getCharsetName().equals(SaffronProperties.INSTANCE.defaultCharset().get());
pw.print(nlsString.asSql(includeCharset, false));
}
break;
case BOOLEAN:
assert value instanceof Boolean;
pw.print(((Boolean) value).booleanValue());
break;
case DECIMAL:
assert value instanceof BigDecimal;
pw.print(value.toString());
break;
case DOUBLE:
assert value instanceof BigDecimal;
pw.print(Util.toScientificNotation((BigDecimal) value));
break;
case BIGINT:
assert value instanceof BigDecimal;
pw.print(((BigDecimal) value).longValue());
pw.print('L');
break;
case BINARY:
assert value instanceof ByteString;
pw.print("X'");
pw.print(((ByteString) value).toString(16));
pw.print("'");
break;
case NULL:
assert value == null;
pw.print("null");
break;
case SYMBOL:
assert value instanceof Enum;
pw.print("FLAG(");
pw.print(value);
pw.print(")");
break;
case DATE:
assert value instanceof DateString;
pw.print(value);
break;
case TIME:
assert value instanceof TimeString;
pw.print(value);
break;
case TIME_WITH_LOCAL_TIME_ZONE:
assert value instanceof TimeString;
pw.print(value);
break;
case TIMESTAMP:
assert value instanceof TimestampString;
pw.print(value);
break;
case TIMESTAMP_WITH_LOCAL_TIME_ZONE:
assert value instanceof TimestampString;
pw.print(value);
break;
case INTERVAL_YEAR:
case INTERVAL_YEAR_MONTH:
case INTERVAL_MONTH:
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 (value instanceof BigDecimal) {
pw.print(value.toString());
} else {
assert value == null;
pw.print("null");
}
break;
case MULTISET:
case ROW:
@SuppressWarnings("unchecked") final List<RexLiteral> list = (List) value;
pw.print(new AbstractList<String>() {
public String get(int index) {
return list.get(index).digest;
}
public int size() {
return list.size();
}
});
break;
default:
assert valueMatchesType(value, typeName, true);
throw Util.needToImplement(typeName);
}
}
use of org.apache.calcite.util.NlsString in project calcite by apache.
the class RexLiteral method fromJdbcString.
/**
* Converts a Jdbc string into a RexLiteral. This method accepts a string,
* as returned by the Jdbc method ResultSet.getString(), and restores the
* string into an equivalent RexLiteral. It allows one to use Jdbc strings
* as a common format for data.
*
* <p>If a null literal is provided, then a null pointer will be returned.
*
* @param type data type of literal to be read
* @param typeName type family of literal
* @param literal the (non-SQL encoded) string representation, as returned
* by the Jdbc call to return a column as a string
* @return a typed RexLiteral, or null
*/
public static RexLiteral fromJdbcString(RelDataType type, SqlTypeName typeName, String literal) {
if (literal == null) {
return null;
}
switch(typeName) {
case CHAR:
Charset charset = type.getCharset();
SqlCollation collation = type.getCollation();
NlsString str = new NlsString(literal, charset.name(), collation);
return new RexLiteral(str, type, typeName);
case BOOLEAN:
boolean b = ConversionUtil.toBoolean(literal);
return new RexLiteral(b, type, typeName);
case DECIMAL:
case DOUBLE:
BigDecimal d = new BigDecimal(literal);
return new RexLiteral(d, type, typeName);
case BINARY:
byte[] bytes = ConversionUtil.toByteArrayFromString(literal, 16);
return new RexLiteral(new ByteString(bytes), type, typeName);
case NULL:
return new RexLiteral(null, type, typeName);
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:
long millis = SqlParserUtil.intervalToMillis(literal, type.getIntervalQualifier());
return new RexLiteral(BigDecimal.valueOf(millis), type, typeName);
case INTERVAL_YEAR:
case INTERVAL_YEAR_MONTH:
case INTERVAL_MONTH:
long months = SqlParserUtil.intervalToMonths(literal, type.getIntervalQualifier());
return new RexLiteral(BigDecimal.valueOf(months), type, typeName);
case DATE:
case TIME:
case TIMESTAMP:
String format = getCalendarFormat(typeName);
TimeZone tz = DateTimeUtils.UTC_ZONE;
final Comparable v;
switch(typeName) {
case DATE:
final Calendar cal = DateTimeUtils.parseDateFormat(literal, new SimpleDateFormat(format, Locale.ROOT), tz);
if (cal == null) {
throw new AssertionError("fromJdbcString: invalid date/time value '" + literal + "'");
}
v = DateString.fromCalendarFields(cal);
break;
default:
// Allow fractional seconds for times and timestamps
assert format != null;
final DateTimeUtils.PrecisionTime ts = DateTimeUtils.parsePrecisionDateTimeLiteral(literal, new SimpleDateFormat(format, Locale.ROOT), tz, -1);
if (ts == null) {
throw new AssertionError("fromJdbcString: invalid date/time value '" + literal + "'");
}
switch(typeName) {
case TIMESTAMP:
v = TimestampString.fromCalendarFields(ts.getCalendar()).withFraction(ts.getFraction());
break;
case TIME:
v = TimeString.fromCalendarFields(ts.getCalendar()).withFraction(ts.getFraction());
break;
default:
throw new AssertionError();
}
}
return new RexLiteral(v, type, typeName);
case SYMBOL:
// Symbols are for internal use
default:
throw new AssertionError("fromJdbcString: unsupported type");
}
}
use of org.apache.calcite.util.NlsString in project calcite by apache.
the class SqlCharStringLiteral method unparse.
public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
if (false) {
Util.discard(Bug.FRG78_FIXED);
String stringValue = ((NlsString) value).getValue();
writer.literal(writer.getDialect().quoteStringLiteral(stringValue));
}
assert value instanceof NlsString;
writer.literal(value.toString());
}
Aggregations