/** * Extracts the value from a literal. * * <p>Cases: * * <ul> * <li>If the node is a character literal, a chain of string literals, or a CAST of a character * literal, returns the value as a {@link NlsString}. * <li>If the node is a numeric literal, or a negated numeric literal, returns the value as a * {@link BigDecimal}. * <li>If the node is a {@link SqlIntervalQualifier}, returns its {@link TimeUnitRange}. * <li>If the node is INTERVAL_DAY_TIME in {@link SqlTypeFamily}, returns its sign multiplied by * its millisecond equivalent value * <li>If the node is INTERVAL_YEAR_MONTH in {@link SqlTypeFamily}, returns its sign multiplied * by its months equivalent value * <li>Otherwise the behavior is not specified. * </ul> */ public static Comparable value(SqlNode node) { if (node instanceof SqlLiteral) { SqlLiteral literal = (SqlLiteral) node; switch (literal.getTypeName().getFamily()) { case CHARACTER: return (NlsString) literal.value; case NUMERIC: return (BigDecimal) literal.value; case INTERVAL_YEAR_MONTH: final SqlIntervalLiteral.IntervalValue valMonth = (SqlIntervalLiteral.IntervalValue) literal.value; return valMonth.getSign() * SqlParserUtil.intervalToMonths(valMonth); case INTERVAL_DAY_TIME: final SqlIntervalLiteral.IntervalValue valTime = (SqlIntervalLiteral.IntervalValue) literal.value; return valTime.getSign() * SqlParserUtil.intervalToMillis(valTime); } } if (SqlUtil.isLiteralChain(node)) { assert node instanceof SqlCall; final SqlLiteral literal = SqlLiteralChainOperator.concatenateOperands((SqlCall) node); assert SqlTypeUtil.inCharFamily(literal.getTypeName()); return (NlsString) literal.value; } if (node instanceof SqlIntervalQualifier) { SqlIntervalQualifier qualifier = (SqlIntervalQualifier) node; return qualifier.timeUnitRange; } switch (node.getKind()) { case CAST: assert node instanceof SqlCall; return value(((SqlCall) node).operand(0)); case MINUS_PREFIX: assert node instanceof SqlCall; Comparable o = value(((SqlCall) node).operand(0)); if (o instanceof BigDecimal) { BigDecimal bigDecimal = (BigDecimal) o; return bigDecimal.negate(); } // fall through default: throw Util.newInternal("invalid literal: " + node); } }
public RelDataType createSqlType(RelDataTypeFactory typeFactory) { BitString bitString; switch (typeName) { case NULL: case BOOLEAN: RelDataType ret = typeFactory.createSqlType(typeName); ret = typeFactory.createTypeWithNullability(ret, null == value); return ret; case BINARY: bitString = (BitString) value; int bitCount = bitString.getBitCount(); return typeFactory.createSqlType(SqlTypeName.BINARY, bitCount / 8); case CHAR: NlsString string = (NlsString) value; Charset charset = string.getCharset(); if (null == charset) { charset = typeFactory.getDefaultCharset(); } SqlCollation collation = string.getCollation(); if (null == collation) { collation = SqlCollation.COERCIBLE; } RelDataType type = typeFactory.createSqlType(SqlTypeName.CHAR, string.getValue().length()); type = typeFactory.createTypeWithCharsetAndCollation(type, charset, collation); return type; case INTERVAL_YEAR_MONTH: case INTERVAL_DAY_TIME: SqlIntervalLiteral.IntervalValue intervalValue = (SqlIntervalLiteral.IntervalValue) value; return typeFactory.createSqlIntervalType(intervalValue.getIntervalQualifier()); case SYMBOL: return typeFactory.createSqlType(SqlTypeName.SYMBOL); case INTEGER: // handled in derived class case TIME: // handled in derived class case VARCHAR: // should never happen case VARBINARY: // should never happen default: throw Util.needToImplement(toString() + ", operand=" + value); } }