Example #1
0
 /**
  * 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);
   }
 }
Example #2
0
 /**
  * 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);
   }
 }
Example #3
0
  /**
   * 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());
  }
Example #4
0
 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()
                 + "'");
       }
     }
   }
 }