/** * Extracts the string value from a string literal, a chain of string literals, or a CAST of a * string literal. * * @deprecated Use {@link #value(SqlNode)} */ @Deprecated // to be removed before 2.0 public static String stringValue(SqlNode node) { if (node instanceof SqlLiteral) { SqlLiteral literal = (SqlLiteral) node; assert SqlTypeUtil.inCharFamily(literal.getTypeName()); return literal.toValue(); } else if (SqlUtil.isLiteralChain(node)) { final SqlLiteral literal = SqlLiteralChainOperator.concatenateOperands((SqlCall) node); assert SqlTypeUtil.inCharFamily(literal.getTypeName()); return literal.toValue(); } else if (node instanceof SqlCall && ((SqlCall) node).getOperator() == SqlStdOperatorTable.CAST) { return stringValue(((SqlCall) node).operand(0)); } else { throw Util.newInternal("invalid string literal: " + node); } }
/** * 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); } }
/** * Transforms this literal (which must be of type character) into a new one in which 4-digit * Unicode escape sequences have been replaced with the corresponding Unicode characters. * * @param unicodeEscapeChar escape character (e.g. backslash) for Unicode numeric sequences; 0 * implies no transformation * @return transformed literal */ public SqlLiteral unescapeUnicode(char unicodeEscapeChar) { if (unicodeEscapeChar == 0) { return this; } assert SqlTypeUtil.inCharFamily(getTypeName()); NlsString ns = (NlsString) value; String s = ns.getValue(); StringBuilder sb = new StringBuilder(); int n = s.length(); for (int i = 0; i < n; ++i) { char c = s.charAt(i); if (c == unicodeEscapeChar) { if (n > (i + 1)) { if (s.charAt(i + 1) == unicodeEscapeChar) { sb.append(unicodeEscapeChar); ++i; continue; } } if ((i + 5) > n) { throw SqlUtil.newContextException( getParserPosition(), RESOURCE.unicodeEscapeMalformed(i)); } final String u = s.substring(i + 1, i + 5); final int v; try { v = Integer.parseInt(u, 16); } catch (NumberFormatException ex) { throw SqlUtil.newContextException( getParserPosition(), RESOURCE.unicodeEscapeMalformed(i)); } sb.append((char) (v & 0xFFFF)); // skip hexits i += 4; } else { sb.append(c); } } ns = new NlsString(sb.toString(), ns.getCharsetName(), ns.getCollation()); return new SqlCharStringLiteral(ns, getParserPosition()); }
public static void checkCharsetAndCollateConsistentIfCharType(RelDataType type) { // (every charset must have a default collation) if (SqlTypeUtil.inCharFamily(type)) { Charset strCharset = type.getCharset(); Charset colCharset = type.getCollation().getCharset(); assert null != strCharset; assert null != colCharset; if (!strCharset.equals(colCharset)) { if (false) { // todo: enable this checking when we have a charset to // collation mapping throw new Error( type.toString() + " was found to have charset '" + strCharset.name() + "' and a mismatched collation charset '" + colCharset.name() + "'"); } } } }