private static Comparable zeroValue(RelDataType type) { switch (type.getSqlTypeName()) { case CHAR: return new NlsString(Spaces.of(type.getPrecision()), null, null); case VARCHAR: return new NlsString("", null, null); case BINARY: return new ByteString(new byte[type.getPrecision()]); case VARBINARY: return ByteString.EMPTY; case TINYINT: case SMALLINT: case INTEGER: case BIGINT: case DECIMAL: case FLOAT: case REAL: case DOUBLE: return BigDecimal.ZERO; case BOOLEAN: return false; case TIME: case DATE: case TIMESTAMP: return DateTimeUtils.ZERO_CALENDAR; default: throw Util.unexpected(type.getSqlTypeName()); } }
public void unparse(SqlWriter writer, int leftPrec, int rightPrec) { switch (typeName) { case BOOLEAN: writer.keyword(value == null ? "UNKNOWN" : (Boolean) value ? "TRUE" : "FALSE"); break; case NULL: writer.keyword("NULL"); break; case CHAR: case DECIMAL: case DOUBLE: case BINARY: // should be handled in subtype throw Util.unexpected(typeName); case SYMBOL: if (value instanceof Enum) { Enum enumVal = (Enum) value; writer.keyword(enumVal.toString()); } else { writer.keyword(String.valueOf(value)); } break; default: writer.literal(value.toString()); } }
/** @return whether value is appropriate for its type (we have rules about these things) */ public static boolean valueMatchesType(Object value, SqlTypeName typeName) { switch (typeName) { case BOOLEAN: return (value == null) || (value instanceof Boolean); case NULL: return value == null; case DECIMAL: case DOUBLE: return value instanceof BigDecimal; case DATE: case TIME: case TIMESTAMP: return value instanceof Calendar; case INTERVAL_DAY_TIME: case INTERVAL_YEAR_MONTH: return value instanceof SqlIntervalLiteral.IntervalValue; case BINARY: return value instanceof BitString; case CHAR: return value instanceof NlsString; case SYMBOL: return (value instanceof SqlSymbol) || (value instanceof SqlSampleSpec) || (value instanceof TimeUnitRange); case MULTISET: return true; case INTEGER: // not allowed -- use Decimal case VARCHAR: // not allowed -- use Char case VARBINARY: // not allowed -- use Binary default: throw Util.unexpected(typeName); } }
/** Returns a numeric literal's value as a {@link BigDecimal}. */ public BigDecimal bigDecimalValue() { switch (typeName) { case DECIMAL: case DOUBLE: return (BigDecimal) value; default: throw Util.unexpected(typeName); } }
/** * Returns the long value of this literal. * * @param exact Whether the value has to be exact. If true, and the literal is a fraction (e.g. * 3.14), throws. If false, discards the fractional part of the value. * @return Long value of this literal */ public long longValue(boolean exact) { switch (typeName) { case DECIMAL: case DOUBLE: BigDecimal bd = (BigDecimal) value; if (exact) { try { return bd.longValueExact(); } catch (ArithmeticException e) { throw SqlUtil.newContextException( getParserPosition(), RESOURCE.numberLiteralOutOfRange(bd.toString())); } } else { return bd.longValue(); } default: throw Util.unexpected(typeName); } }
/** * 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((Calendar) value, type.getPrecision()); case DATE: return makeDateLiteral((Calendar) value); case TIMESTAMP: return makeTimestampLiteral((Calendar) value, type.getPrecision()); case INTERVAL_YEAR_MONTH: case INTERVAL_DAY_TIME: 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<RexNode>(); 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<RexNode>(); for (Object entry : listValue) { operands.add(makeLiteral(entry, arrayType.getComponentType(), allowCast)); } return makeCall(SqlStdOperatorTable.ARRAY_VALUE_CONSTRUCTOR, operands); case ANY: return makeLiteral(value, guessType(value), allowCast); default: throw Util.unexpected(type.getSqlTypeName()); } }