Skip to content

Commit

Permalink
SQL: Remove more ANTLR4 grammar ambiguities (#34074)
Browse files Browse the repository at this point in the history
The `-` and `+` as a number literal prefix are already
parsed by the rule in `valueExpression`. To accommodate
this, there are some code changes that enables the
`ExpressionBuilder` to parse Literal integers and decimals
together with the `-/+` prefix sign (if exists) and validate
them (wrong format, large numbers, etc.).

Follows: #33854
  • Loading branch information
Marios Trivyzas authored Oct 2, 2018
1 parent 10201e0 commit 2ba18f5
Show file tree
Hide file tree
Showing 5 changed files with 355 additions and 293 deletions.
4 changes: 2 additions & 2 deletions x-pack/plugin/sql/src/main/antlr/SqlBase.g4
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,8 @@ unquoteIdentifier
;

number
: (PLUS | MINUS)? DECIMAL_VALUE #decimalLiteral
| (PLUS | MINUS)? INTEGER_VALUE #integerLiteral
: DECIMAL_VALUE #decimalLiteral
| INTEGER_VALUE #integerLiteral
;

string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,9 @@ public Object visitArithmeticUnary(ArithmeticUnaryContext ctx) {
case SqlBaseParser.PLUS:
return value;
case SqlBaseParser.MINUS:
if (value instanceof Literal) { // Minus already processed together with literal number
return value;
}
return new Neg(source(ctx.operator), value);
default:
throw new ParsingException(loc, "Unknown arithemtic {}", ctx.operator.getText());
Expand Down Expand Up @@ -483,38 +486,40 @@ public Expression visitStringLiteral(StringLiteralContext ctx) {

@Override
public Literal visitDecimalLiteral(DecimalLiteralContext ctx) {
String ctxText = (hasMinusFromParent(ctx) ? "-" : "") + ctx.getText();
double value;
try {
value = Double.parseDouble(ctx.getText());
value = Double.parseDouble(ctxText);
} catch (NumberFormatException nfe) {
throw new ParsingException(source(ctx), "Cannot parse number [{}]", ctx.getText());
throw new ParsingException(source(ctx), "Cannot parse number [{}]", ctxText);
}
if (Double.isInfinite(value)) {
throw new ParsingException(source(ctx), "Number [{}] is too large", ctx.getText());
throw new ParsingException(source(ctx), "Number [{}] is too large", ctxText);
}
if (Double.isNaN(value)) {
throw new ParsingException(source(ctx), "[{}] cannot be parsed as a number (NaN)", ctx.getText());
throw new ParsingException(source(ctx), "[{}] cannot be parsed as a number (NaN)", ctxText);
}
return new Literal(source(ctx), Double.valueOf(value), DataType.DOUBLE);
}

@Override
public Literal visitIntegerLiteral(IntegerLiteralContext ctx) {
String ctxText = (hasMinusFromParent(ctx) ? "-" : "") + ctx.getText();
long value;
try {
value = Long.parseLong(ctx.getText());
value = Long.parseLong(ctxText);
} catch (NumberFormatException nfe) {
try {
BigInteger bi = new BigInteger(ctx.getText());
BigInteger bi = new BigInteger(ctxText);
try {
bi.longValueExact();
} catch (ArithmeticException ae) {
throw new ParsingException(source(ctx), "Number [{}] is too large", ctx.getText());
throw new ParsingException(source(ctx), "Number [{}] is too large", ctxText);
}
} catch (NumberFormatException ex) {
// parsing fails, go through
}
throw new ParsingException(source(ctx), "Cannot parse number [{}]", ctx.getText());
throw new ParsingException(source(ctx), "Cannot parse number [{}]", ctxText);
}

DataType type = DataType.LONG;
Expand Down Expand Up @@ -681,4 +686,21 @@ public Literal visitGuidEscapedLiteral(GuidEscapedLiteralContext ctx) {

return new Literal(source(ctx), string, DataType.KEYWORD);
}

private boolean hasMinusFromParent(SqlBaseParser.NumberContext ctx) {
ParserRuleContext parentCtx = ctx.getParent();
if (parentCtx != null && parentCtx instanceof SqlBaseParser.NumericLiteralContext) {
parentCtx = parentCtx.getParent();
if (parentCtx != null && parentCtx instanceof SqlBaseParser.ConstantDefaultContext) {
parentCtx = parentCtx.getParent();
if (parentCtx != null && parentCtx instanceof SqlBaseParser.ValueExpressionDefaultContext) {
parentCtx = parentCtx.getParent();
if (parentCtx != null && parentCtx instanceof SqlBaseParser.ArithmeticUnaryContext) {
return ((ArithmeticUnaryContext) parentCtx).MINUS() != null;
}
}
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,8 @@ public SqlBaseLexer(CharStream input) {
"\u0316\u0319\5\u00cfh\2\u0317\u0319\t\4\2\2\u0318\u0315\3\2\2\2\u0318"+
"\u0316\3\2\2\2\u0318\u0317\3\2\2\2\u0319\u031a\3\2\2\2\u031a\u0318\3\2"+
"\2\2\u031a\u031b\3\2\2\2\u031b\u00c6\3\2\2\2\u031c\u0320\5\u00d1i\2\u031d"+
"\u0320\5\u00cfh\2\u031e\u0320\t\3\2\2\u031f\u031c\3\2\2\2\u031f\u031d"+
"\3\2\2\2\u031f\u031e\3\2\2\2\u0320\u0321\3\2\2\2\u0321\u031f\3\2\2\2\u0321"+
"\u0320\5\u00cfh\2\u031e\u0320\7a\2\2\u031f\u031c\3\2\2\2\u031f\u031d\3"+
"\2\2\2\u031f\u031e\3\2\2\2\u0320\u0321\3\2\2\2\u0321\u031f\3\2\2\2\u0321"+
"\u0322\3\2\2\2\u0322\u00c8\3\2\2\2\u0323\u0329\7$\2\2\u0324\u0328\n\5"+
"\2\2\u0325\u0326\7$\2\2\u0326\u0328\7$\2\2\u0327\u0324\3\2\2\2\u0327\u0325"+
"\3\2\2\2\u0328\u032b\3\2\2\2\u0329\u0327\3\2\2\2\u0329\u032a\3\2\2\2\u032a"+
Expand Down
Loading

0 comments on commit 2ba18f5

Please sign in to comment.