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 <[email protected]>
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)

Reply via email to