Example #1
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 #2
0
  public static SqlNumericLiteral createExactNumeric(String s, SqlParserPos pos) {
    BigDecimal value;
    int prec;
    int scale;

    int i = s.indexOf('.');
    if ((i >= 0) && ((s.length() - 1) != i)) {
      value = SqlParserUtil.parseDecimal(s);
      scale = s.length() - i - 1;
      assert scale == value.scale() : s;
      prec = s.length() - 1;
    } else if ((i >= 0) && ((s.length() - 1) == i)) {
      value = SqlParserUtil.parseInteger(s.substring(0, i));
      scale = 0;
      prec = s.length() - 1;
    } else {
      value = SqlParserUtil.parseInteger(s);
      scale = 0;
      prec = s.length();
    }
    return new SqlNumericLiteral(value, prec, scale, true, pos);
  }
  /**
   * Checks whether an exception matches the expected pattern. If <code>
   * sap</code> contains an error location, checks this too.
   *
   * @param ex Exception thrown
   * @param expectedMsgPattern Expected pattern
   * @param sap Query and (optional) position in query
   */
  public static void checkEx(
      Throwable ex, String expectedMsgPattern, SqlParserUtil.StringAndPos sap) {
    if (null == ex) {
      if (expectedMsgPattern == null) {
        // No error expected, and no error happened.
        return;
      } else {
        throw new AssertionError(
            "Expected query to throw exception, "
                + "but it did not; query ["
                + sap.sql
                + "]; expected ["
                + expectedMsgPattern
                + "]");
      }
    }
    Throwable actualException = ex;
    String actualMessage = actualException.getMessage();
    int actualLine = -1;
    int actualColumn = -1;
    int actualEndLine = 100;
    int actualEndColumn = 99;

    // Search for an CalciteContextException somewhere in the stack.
    CalciteContextException ece = null;
    for (Throwable x = ex; x != null; x = x.getCause()) {
      if (x instanceof CalciteContextException) {
        ece = (CalciteContextException) x;
        break;
      }
      if (x.getCause() == x) {
        break;
      }
    }

    // Search for a SqlParseException -- with its position set -- somewhere
    // in the stack.
    SqlParseException spe = null;
    for (Throwable x = ex; x != null; x = x.getCause()) {
      if ((x instanceof SqlParseException) && (((SqlParseException) x).getPos() != null)) {
        spe = (SqlParseException) x;
        break;
      }
      if (x.getCause() == x) {
        break;
      }
    }

    if (ece != null) {
      actualLine = ece.getPosLine();
      actualColumn = ece.getPosColumn();
      actualEndLine = ece.getEndPosLine();
      actualEndColumn = ece.getEndPosColumn();
      if (ece.getCause() != null) {
        actualException = ece.getCause();
        actualMessage = actualException.getMessage();
      }
    } else if (spe != null) {
      actualLine = spe.getPos().getLineNum();
      actualColumn = spe.getPos().getColumnNum();
      actualEndLine = spe.getPos().getEndLineNum();
      actualEndColumn = spe.getPos().getEndColumnNum();
      if (spe.getCause() != null) {
        actualException = spe.getCause();
        actualMessage = actualException.getMessage();
      }
    } else {
      final String message = ex.getMessage();
      if (message != null) {
        Matcher matcher = LINE_COL_TWICE_PATTERN.matcher(message);
        if (matcher.matches()) {
          actualLine = Integer.parseInt(matcher.group(1));
          actualColumn = Integer.parseInt(matcher.group(2));
          actualEndLine = Integer.parseInt(matcher.group(3));
          actualEndColumn = Integer.parseInt(matcher.group(4));
          actualMessage = matcher.group(5);
        } else {
          matcher = LINE_COL_PATTERN.matcher(message);
          if (matcher.matches()) {
            actualLine = Integer.parseInt(matcher.group(1));
            actualColumn = Integer.parseInt(matcher.group(2));
          }
        }
      }
    }

    if (null == expectedMsgPattern) {
      if (null != actualException) {
        actualException.printStackTrace();
        fail(
            "Validator threw unexpected exception"
                + "; query ["
                + sap.sql
                + "]; exception ["
                + actualMessage
                + "]; class ["
                + actualException.getClass()
                + "]; pos [line "
                + actualLine
                + " col "
                + actualColumn
                + " thru line "
                + actualLine
                + " col "
                + actualColumn
                + "]");
      }
    } else {
      if (null == actualException) {
        fail(
            "Expected validator to throw "
                + "exception, but it did not; query ["
                + sap.sql
                + "]; expected ["
                + expectedMsgPattern
                + "]");
      } else {
        String sqlWithCarets;
        if ((actualColumn <= 0)
            || (actualLine <= 0)
            || (actualEndColumn <= 0)
            || (actualEndLine <= 0)) {
          if (sap.pos != null) {
            AssertionError e =
                new AssertionError(
                    "Expected error to have position,"
                        + " but actual error did not: "
                        + " actual pos [line "
                        + actualLine
                        + " col "
                        + actualColumn
                        + " thru line "
                        + actualEndLine
                        + " col "
                        + actualEndColumn
                        + "]");
            e.initCause(actualException);
            throw e;
          }
          sqlWithCarets = sap.sql;
        } else {
          sqlWithCarets =
              SqlParserUtil.addCarets(
                  sap.sql, actualLine, actualColumn, actualEndLine, actualEndColumn + 1);
          if (sap.pos == null) {
            throw new AssertionError(
                "Actual error had a position, but expected error"
                    + " did not. Add error position carets to sql:\n"
                    + sqlWithCarets);
          }
        }
        if (actualMessage != null) {
          actualMessage = Util.toLinux(actualMessage);
        }
        if ((actualMessage == null) || !actualMessage.matches(expectedMsgPattern)) {
          actualException.printStackTrace();
          final String actualJavaRegexp =
              (actualMessage == null)
                  ? "null"
                  : TestUtil.quoteForJava(TestUtil.quotePattern(actualMessage));
          fail(
              "Validator threw different "
                  + "exception than expected; query ["
                  + sap.sql
                  + "];\n"
                  + " expected pattern ["
                  + expectedMsgPattern
                  + "];\n"
                  + " actual ["
                  + actualMessage
                  + "];\n"
                  + " actual as java regexp ["
                  + actualJavaRegexp
                  + "]; pos ["
                  + actualLine
                  + " col "
                  + actualColumn
                  + " thru line "
                  + actualEndLine
                  + " col "
                  + actualEndColumn
                  + "]; sql ["
                  + sqlWithCarets
                  + "]");
        } else if ((sap.pos != null)
            && ((actualLine != sap.pos.getLineNum())
                || (actualColumn != sap.pos.getColumnNum())
                || (actualEndLine != sap.pos.getEndLineNum())
                || (actualEndColumn != sap.pos.getEndColumnNum()))) {
          fail(
              "Validator threw expected "
                  + "exception ["
                  + actualMessage
                  + "];\nbut at pos [line "
                  + actualLine
                  + " col "
                  + actualColumn
                  + " thru line "
                  + actualEndLine
                  + " col "
                  + actualEndColumn
                  + "];\nsql ["
                  + sqlWithCarets
                  + "]");
        }
      }
    }
  }
Example #4
0
 public static SqlNumericLiteral createApproxNumeric(String s, SqlParserPos pos) {
   BigDecimal value = SqlParserUtil.parseDecimal(s);
   return new SqlNumericLiteral(value, null, null, false, pos);
 }