You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2023/02/10 16:57:25 UTC
[calcite] 02/05: [CALCITE-5505] JavaCC warns about missing LOOKAHEAD directives in Parser.jj
This is an automated email from the ASF dual-hosted git repository.
jhyde pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
commit 3eaf13bdcdcd167bb8a05484e1e1af7a94bf194e
Author: Julian Hyde <jh...@apache.org>
AuthorDate: Mon Jan 30 10:07:49 2023 -0800
[CALCITE-5505] JavaCC warns about missing LOOKAHEAD directives in Parser.jj
---
core/src/main/codegen/templates/Parser.jj | 62 ++++++++++++++++++-------------
1 file changed, 37 insertions(+), 25 deletions(-)
diff --git a/core/src/main/codegen/templates/Parser.jj b/core/src/main/codegen/templates/Parser.jj
index 4db4d15083..c738e2b151 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -5054,34 +5054,45 @@ SqlIntervalQualifier TimeUnitOrName() : {
final SqlIdentifier unitName;
}
{
+ // When we see a time unit that is also a non-reserved keyword, such as
+ // NANOSECOND, there is a choice between using the TimeUnit enum
+ // (TimeUnit.NANOSECOND) or the name. The following LOOKAHEAD directive
+ // tells the parser that we prefer the former.
+ //
+ // Reserved keywords, such as SECOND, cannot be identifiers, and are
+ // therefore not ambiguous.
LOOKAHEAD(2)
- <NANOSECOND> { return new SqlIntervalQualifier(TimeUnit.NANOSECOND, null, getPos()); }
-| <MICROSECOND> { return new SqlIntervalQualifier(TimeUnit.MICROSECOND, null, getPos()); }
-| <MILLISECOND> { return new SqlIntervalQualifier(TimeUnit.MILLISECOND, null, getPos()); }
-| <SECOND> { return new SqlIntervalQualifier(TimeUnit.SECOND, null, getPos()); }
-| <MINUTE> { return new SqlIntervalQualifier(TimeUnit.MINUTE, null, getPos()); }
-| <HOUR> { return new SqlIntervalQualifier(TimeUnit.HOUR, null, getPos()); }
-| <DAY> { return new SqlIntervalQualifier(TimeUnit.DAY, null, getPos()); }
-| <DOW> { return new SqlIntervalQualifier(TimeUnit.DOW, null, getPos()); }
-| <DOY> { return new SqlIntervalQualifier(TimeUnit.DOY, null, getPos()); }
-| <ISODOW> { return new SqlIntervalQualifier(TimeUnit.ISODOW, null, getPos()); }
-| <ISOYEAR> { return new SqlIntervalQualifier(TimeUnit.ISOYEAR, null, getPos()); }
-| <WEEK> { span = span(); }
(
- LOOKAHEAD(2)
- <LPAREN> w = weekdayName() <RPAREN> {
- return new SqlIntervalQualifier(w, span.end(this));
- }
- |
- { return new SqlIntervalQualifier(TimeUnit.WEEK, null, getPos()); }
+ <NANOSECOND> { return new SqlIntervalQualifier(TimeUnit.NANOSECOND, null, getPos()); }
+ | <MICROSECOND> { return new SqlIntervalQualifier(TimeUnit.MICROSECOND, null, getPos()); }
+ | <MILLISECOND> { return new SqlIntervalQualifier(TimeUnit.MILLISECOND, null, getPos()); }
+ | <SECOND> { return new SqlIntervalQualifier(TimeUnit.SECOND, null, getPos()); }
+ | <MINUTE> { return new SqlIntervalQualifier(TimeUnit.MINUTE, null, getPos()); }
+ | <HOUR> { return new SqlIntervalQualifier(TimeUnit.HOUR, null, getPos()); }
+ | <DAY> { return new SqlIntervalQualifier(TimeUnit.DAY, null, getPos()); }
+ | <DOW> { return new SqlIntervalQualifier(TimeUnit.DOW, null, getPos()); }
+ | <DOY> { return new SqlIntervalQualifier(TimeUnit.DOY, null, getPos()); }
+ | <ISODOW> { return new SqlIntervalQualifier(TimeUnit.ISODOW, null, getPos()); }
+ | <ISOYEAR> { return new SqlIntervalQualifier(TimeUnit.ISOYEAR, null, getPos()); }
+ | <WEEK> { span = span(); }
+ (
+ // There is a choice between "WEEK(weekday)" and "WEEK". We prefer
+ // the former, and the parser will look ahead for '('.
+ LOOKAHEAD(2)
+ <LPAREN> w = weekdayName() <RPAREN> {
+ return new SqlIntervalQualifier(w, span.end(this));
+ }
+ |
+ { return new SqlIntervalQualifier(TimeUnit.WEEK, null, getPos()); }
+ )
+ | <MONTH> { return new SqlIntervalQualifier(TimeUnit.MONTH, null, getPos()); }
+ | <QUARTER> { return new SqlIntervalQualifier(TimeUnit.QUARTER, null, getPos()); }
+ | <YEAR> { return new SqlIntervalQualifier(TimeUnit.YEAR, null, getPos()); }
+ | <EPOCH> { return new SqlIntervalQualifier(TimeUnit.EPOCH, null, getPos()); }
+ | <DECADE> { return new SqlIntervalQualifier(TimeUnit.DECADE, null, getPos()); }
+ | <CENTURY> { return new SqlIntervalQualifier(TimeUnit.CENTURY, null, getPos()); }
+ | <MILLENNIUM> { return new SqlIntervalQualifier(TimeUnit.MILLENNIUM, null, getPos()); }
)
-| <MONTH> { return new SqlIntervalQualifier(TimeUnit.MONTH, null, getPos()); }
-| <QUARTER> { return new SqlIntervalQualifier(TimeUnit.QUARTER, null, getPos()); }
-| <YEAR> { return new SqlIntervalQualifier(TimeUnit.YEAR, null, getPos()); }
-| <EPOCH> { return new SqlIntervalQualifier(TimeUnit.EPOCH, null, getPos()); }
-| <DECADE> { return new SqlIntervalQualifier(TimeUnit.DECADE, null, getPos()); }
-| <CENTURY> { return new SqlIntervalQualifier(TimeUnit.CENTURY, null, getPos()); }
-| <MILLENNIUM> { return new SqlIntervalQualifier(TimeUnit.MILLENNIUM, null, getPos()); }
| unitName = SimpleIdentifier() {
return new SqlIntervalQualifier(unitName.getSimple(),
unitName.getParserPosition());
@@ -6690,6 +6701,7 @@ SqlCall DateTruncFunctionCall() :
// the BigQuery variant, e.g. "DATE_TRUNC(d, YEAR)",
// and the Redshift variant, e.g. "DATE_TRUNC('year', DATE '2008-09-08')".
(
+ LOOKAHEAD(2)
unit = TimeUnitOrName() { args.add(unit); }
|
AddExpression(args, ExprContext.ACCEPT_SUB_QUERY)