use of org.apache.calcite.util.NlsString in project drill by apache.
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:
// so the resulting scale wouldn't be calculated correctly
if (isLiteralNull(literal)) {
out.writeDoubleNull();
} else {
out.writeDouble(((BigDecimal) literal.getValue()).doubleValue());
}
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(LocalDateTime.ofInstant(Instant.ofEpochMilli(new DateTime(literal.getValue()).getMillis()), ZoneOffset.UTC).toLocalDate());
}
return;
case TIME:
if (isLiteralNull(literal)) {
out.writeTimeNull();
} else {
out.writeTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(new DateTime(literal.getValue()).getMillis()), ZoneOffset.UTC).toLocalTime());
}
return;
case TIMESTAMP:
if (isLiteralNull(literal)) {
out.writeTimestampNull();
} else {
out.writeTimestamp(LocalDateTime.ofInstant(Instant.ofEpochMilli(new DateTime(literal.getValue()).getMillis()), ZoneOffset.UTC));
}
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 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) {
LogicalProject newProject = project.copy(project.getTraitSet(), project.getInput(0), exprList, project.getRowType());
return visitChild(newProject, 0, project.getInput());
}
return visitChild(project, 0, project.getInput());
}
Aggregations