SQL: Implement CURRENT_TIME/CURTIME functions (#40662)

After `TIME` SQL data type is introduced, implement
`CURRENT_TIME/CURTIME` functions similarly to CURRENT_TIMESTAMP
that return the system's current time (only, without the date part).

Closes: #40468
(cherry picked from commit 9feede781409d0e264ce45951a25b28ff129b187)
This commit is contained in:
Marios Trivyzas 2019-04-03 19:35:37 +02:00
parent 670e76669c
commit f3c207d27b
21 changed files with 1641 additions and 1297 deletions

View File

@ -35,6 +35,7 @@ s|SQL-92
|`CONVERT` |reserved |reserved |`CONVERT` |reserved |reserved
|`CURRENT_DATE` |reserved |reserved |`CURRENT_DATE` |reserved |reserved
|`CURRENT_TIMESTAMP` |reserved |reserved |`CURRENT_TIMESTAMP` |reserved |reserved
|`CURRENT_TIME` |reserved |reserved
|`DAY` |reserved |reserved |`DAY` |reserved |reserved
|`DAYS` | | |`DAYS` | |
|`DESC` |reserved |reserved |`DESC` |reserved |reserved

View File

@ -139,6 +139,63 @@ is used for relative date filtering:
include-tagged::{sql-specs}/docs/docs.csv-spec[filterToday] include-tagged::{sql-specs}/docs/docs.csv-spec[filterToday]
-------------------------------------------------- --------------------------------------------------
[[sql-functions-current-time]]
==== `CURRENT_TIME/CURTIME`
.Synopsis:
[source, sql]
--------------------------------------------------
CURRENT_TIME
CURRENT_TIME([precision <1>])
CURTIME
--------------------------------------------------
*Input*:
<1> fractional digits; optional
*Output*: time
.Description:
Returns the time when the current query reached the server.
As a function, `CURRENT_TIME()` accepts _precision_ as an optional
parameter for rounding the second fractional digits (nanoseconds). The default _precision_ is 3,
meaning a milliseconds precision current time will be returned.
This method always returns the same value for its every occurrence within the same query.
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/docs/docs.csv-spec[currentTime]
--------------------------------------------------
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/docs/docs.csv-spec[currentTimeFunction]
--------------------------------------------------
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/docs/docs.csv-spec[curTimeFunction]
--------------------------------------------------
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/docs/docs.csv-spec[currentTimeFunctionPrecision]
--------------------------------------------------
Typically, this function is used for relative date/time filtering:
["source","sql",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{sql-specs}/docs/docs.csv-spec[filterCurrentTime]
--------------------------------------------------
[IMPORTANT]
Currently, using a _precision_ greater than 3 doesn't make any difference to the output of the
function as the maximum number of second fractional digits returned is 3 (milliseconds).
[[sql-functions-current-timestamp]] [[sql-functions-current-timestamp]]
==== `CURRENT_TIMESTAMP` ==== `CURRENT_TIMESTAMP`

View File

@ -49,6 +49,7 @@
* <<sql-functions-datetime-interval, Date-Time Operators>> * <<sql-functions-datetime-interval, Date-Time Operators>>
* <<sql-functions-current-date, Date-Time Functions>> * <<sql-functions-current-date, Date-Time Functions>>
** <<sql-functions-current-date>> ** <<sql-functions-current-date>>
** <<sql-functions-current-time>>
** <<sql-functions-current-timestamp>> ** <<sql-functions-current-timestamp>>
** <<sql-functions-datetime-day>> ** <<sql-functions-datetime-day>>
** <<sql-functions-datetime-dow>> ** <<sql-functions-datetime-dow>>

View File

@ -34,7 +34,9 @@ NULLIF |CONDITIONAL
NVL |CONDITIONAL NVL |CONDITIONAL
CURDATE |SCALAR CURDATE |SCALAR
CURRENT_DATE |SCALAR CURRENT_DATE |SCALAR
CURRENT_TIME |SCALAR
CURRENT_TIMESTAMP|SCALAR CURRENT_TIMESTAMP|SCALAR
CURTIME |SCALAR
DAY |SCALAR DAY |SCALAR
DAYNAME |SCALAR DAYNAME |SCALAR
DAYOFMONTH |SCALAR DAYOFMONTH |SCALAR

View File

@ -211,7 +211,9 @@ NULLIF |CONDITIONAL
NVL |CONDITIONAL NVL |CONDITIONAL
CURDATE |SCALAR CURDATE |SCALAR
CURRENT_DATE |SCALAR CURRENT_DATE |SCALAR
CURRENT_TIME |SCALAR
CURRENT_TIMESTAMP|SCALAR CURRENT_TIMESTAMP|SCALAR
CURTIME |SCALAR
DAY |SCALAR DAY |SCALAR
DAYNAME |SCALAR DAYNAME |SCALAR
DAYOFMONTH |SCALAR DAYOFMONTH |SCALAR
@ -2412,6 +2414,63 @@ Mingsen
// end::filterToday // end::filterToday
; ;
currentTime-Ignore
// tag::currentTime
SELECT CURRENT_TIME AS result;
result
------------------------
12:31:27.237Z
// end::currentTime
;
currentTimeFunction-Ignore
// tag::currentTimeFunction
SELECT CURRENT_TIME() AS result;
result
------------------------
12:31:27.237Z
// end::currentTimeFunction
;
curTimeFunction-Ignore
// tag::curTimeFunction
SELECT CURTIME() AS result;
result
------------------------
12:31:27.237Z
// end::curTimeFunction
;
currentTimeFunctionPrecision-Ignore
// tag::currentTimeFunctionPrecision
SELECT CURRENT_TIME(1) AS result;
result
------------------------
12:31:27.2Z
// end::currentTimeFunctionPrecision
;
filterCurrentTime-Ignore
// tag::filterCurrentTime
SELECT first_name FROM emp WHERE CAST(hire_date AS TIME) > CURRENT_TIME() - INTERVAL 20 MINUTES ORDER BY first_name ASC LIMIT 5;
first_name
---------------
Alejandro
Amabile
Anneke
Anoosh
Arumugam
// end::filterCurrentTime
;
currentTimestamp-Ignore currentTimestamp-Ignore
// tag::curTs // tag::curTs
SELECT CURRENT_TIMESTAMP AS result; SELECT CURRENT_TIMESTAMP AS result;

View File

@ -81,3 +81,24 @@ SELECT HOUR(CAST('10:11:12.345' AS TIME) + INTERVAL '20' HOURS) AS h, SECOND(INT
h:i | m:i h:i | m:i
6 | 52 6 | 52
; ;
orderByCurrentTime
SELECT first_name FROM test_emp ORDER BY CURRENT_TIME(), first_name LIMIT 5;
first_name
---------------
Alejandro
Amabile
Anneke
Anoosh
Arumugam
;
// Awaits Fix https://github.com/elastic/elasticsearch/issues/40639
groupByCurrentTime-Ignore
SELECT MAX(salary) FROM test_emp GROUP BY CURRENT_TIME;
MAX(salary)
---------------
74999
;

View File

@ -226,8 +226,9 @@ primaryExpression
; ;
builtinDateTimeFunction builtinDateTimeFunction
: name=CURRENT_DATE ('(' ')')? : name=CURRENT_TIMESTAMP ('(' precision=INTEGER_VALUE? ')')?
| name=CURRENT_TIMESTAMP ('(' precision=INTEGER_VALUE? ')')? | name=CURRENT_DATE ('(' ')')?
| name=CURRENT_TIME ('(' precision=INTEGER_VALUE? ')')?
; ;
castExpression castExpression
@ -373,6 +374,7 @@ CATALOGS: 'CATALOGS';
COLUMNS: 'COLUMNS'; COLUMNS: 'COLUMNS';
CONVERT: 'CONVERT'; CONVERT: 'CONVERT';
CURRENT_DATE : 'CURRENT_DATE'; CURRENT_DATE : 'CURRENT_DATE';
CURRENT_TIME : 'CURRENT_TIME';
CURRENT_TIMESTAMP : 'CURRENT_TIMESTAMP'; CURRENT_TIMESTAMP : 'CURRENT_TIMESTAMP';
DAY: 'DAY'; DAY: 'DAY';
DAYS: 'DAYS'; DAYS: 'DAYS';

View File

@ -17,115 +17,116 @@ CATALOGS=16
COLUMNS=17 COLUMNS=17
CONVERT=18 CONVERT=18
CURRENT_DATE=19 CURRENT_DATE=19
CURRENT_TIMESTAMP=20 CURRENT_TIME=20
DAY=21 CURRENT_TIMESTAMP=21
DAYS=22 DAY=22
DEBUG=23 DAYS=23
DESC=24 DEBUG=24
DESCRIBE=25 DESC=25
DISTINCT=26 DESCRIBE=26
ESCAPE=27 DISTINCT=27
EXECUTABLE=28 ESCAPE=28
EXISTS=29 EXECUTABLE=29
EXPLAIN=30 EXISTS=30
EXTRACT=31 EXPLAIN=31
FALSE=32 EXTRACT=32
FIRST=33 FALSE=33
FORMAT=34 FIRST=34
FROM=35 FORMAT=35
FULL=36 FROM=36
FUNCTIONS=37 FULL=37
GRAPHVIZ=38 FUNCTIONS=38
GROUP=39 GRAPHVIZ=39
HAVING=40 GROUP=40
HOUR=41 HAVING=41
HOURS=42 HOUR=42
IN=43 HOURS=43
INNER=44 IN=44
INTERVAL=45 INNER=45
IS=46 INTERVAL=46
JOIN=47 IS=47
LAST=48 JOIN=48
LEFT=49 LAST=49
LIKE=50 LEFT=50
LIMIT=51 LIKE=51
MAPPED=52 LIMIT=52
MATCH=53 MAPPED=53
MINUTE=54 MATCH=54
MINUTES=55 MINUTE=55
MONTH=56 MINUTES=56
MONTHS=57 MONTH=57
NATURAL=58 MONTHS=58
NOT=59 NATURAL=59
NULL=60 NOT=60
NULLS=61 NULL=61
ON=62 NULLS=62
OPTIMIZED=63 ON=63
OR=64 OPTIMIZED=64
ORDER=65 OR=65
OUTER=66 ORDER=66
PARSED=67 OUTER=67
PHYSICAL=68 PARSED=68
PLAN=69 PHYSICAL=69
RIGHT=70 PLAN=70
RLIKE=71 RIGHT=71
QUERY=72 RLIKE=72
SCHEMAS=73 QUERY=73
SECOND=74 SCHEMAS=74
SECONDS=75 SECOND=75
SELECT=76 SECONDS=76
SHOW=77 SELECT=77
SYS=78 SHOW=78
TABLE=79 SYS=79
TABLES=80 TABLE=80
TEXT=81 TABLES=81
TRUE=82 TEXT=82
TO=83 TRUE=83
TYPE=84 TO=84
TYPES=85 TYPE=85
USING=86 TYPES=86
VERIFY=87 USING=87
WHERE=88 VERIFY=88
WITH=89 WHERE=89
YEAR=90 WITH=90
YEARS=91 YEAR=91
ESCAPE_ESC=92 YEARS=92
FUNCTION_ESC=93 ESCAPE_ESC=93
LIMIT_ESC=94 FUNCTION_ESC=94
DATE_ESC=95 LIMIT_ESC=95
TIME_ESC=96 DATE_ESC=96
TIMESTAMP_ESC=97 TIME_ESC=97
GUID_ESC=98 TIMESTAMP_ESC=98
ESC_END=99 GUID_ESC=99
EQ=100 ESC_END=100
NULLEQ=101 EQ=101
NEQ=102 NULLEQ=102
LT=103 NEQ=103
LTE=104 LT=104
GT=105 LTE=105
GTE=106 GT=106
PLUS=107 GTE=107
MINUS=108 PLUS=108
ASTERISK=109 MINUS=109
SLASH=110 ASTERISK=110
PERCENT=111 SLASH=111
CAST_OP=112 PERCENT=112
CONCAT=113 CAST_OP=113
DOT=114 CONCAT=114
PARAM=115 DOT=115
STRING=116 PARAM=116
INTEGER_VALUE=117 STRING=117
DECIMAL_VALUE=118 INTEGER_VALUE=118
IDENTIFIER=119 DECIMAL_VALUE=119
DIGIT_IDENTIFIER=120 IDENTIFIER=120
TABLE_IDENTIFIER=121 DIGIT_IDENTIFIER=121
QUOTED_IDENTIFIER=122 TABLE_IDENTIFIER=122
BACKQUOTED_IDENTIFIER=123 QUOTED_IDENTIFIER=123
SIMPLE_COMMENT=124 BACKQUOTED_IDENTIFIER=124
BRACKETED_COMMENT=125 SIMPLE_COMMENT=125
WS=126 BRACKETED_COMMENT=126
UNRECOGNIZED=127 WS=127
DELIMITER=128 UNRECOGNIZED=128
DELIMITER=129
'('=1 '('=1
')'=2 ')'=2
','=3 ','=3
@ -145,98 +146,99 @@ DELIMITER=128
'COLUMNS'=17 'COLUMNS'=17
'CONVERT'=18 'CONVERT'=18
'CURRENT_DATE'=19 'CURRENT_DATE'=19
'CURRENT_TIMESTAMP'=20 'CURRENT_TIME'=20
'DAY'=21 'CURRENT_TIMESTAMP'=21
'DAYS'=22 'DAY'=22
'DEBUG'=23 'DAYS'=23
'DESC'=24 'DEBUG'=24
'DESCRIBE'=25 'DESC'=25
'DISTINCT'=26 'DESCRIBE'=26
'ESCAPE'=27 'DISTINCT'=27
'EXECUTABLE'=28 'ESCAPE'=28
'EXISTS'=29 'EXECUTABLE'=29
'EXPLAIN'=30 'EXISTS'=30
'EXTRACT'=31 'EXPLAIN'=31
'FALSE'=32 'EXTRACT'=32
'FIRST'=33 'FALSE'=33
'FORMAT'=34 'FIRST'=34
'FROM'=35 'FORMAT'=35
'FULL'=36 'FROM'=36
'FUNCTIONS'=37 'FULL'=37
'GRAPHVIZ'=38 'FUNCTIONS'=38
'GROUP'=39 'GRAPHVIZ'=39
'HAVING'=40 'GROUP'=40
'HOUR'=41 'HAVING'=41
'HOURS'=42 'HOUR'=42
'IN'=43 'HOURS'=43
'INNER'=44 'IN'=44
'INTERVAL'=45 'INNER'=45
'IS'=46 'INTERVAL'=46
'JOIN'=47 'IS'=47
'LAST'=48 'JOIN'=48
'LEFT'=49 'LAST'=49
'LIKE'=50 'LEFT'=50
'LIMIT'=51 'LIKE'=51
'MAPPED'=52 'LIMIT'=52
'MATCH'=53 'MAPPED'=53
'MINUTE'=54 'MATCH'=54
'MINUTES'=55 'MINUTE'=55
'MONTH'=56 'MINUTES'=56
'MONTHS'=57 'MONTH'=57
'NATURAL'=58 'MONTHS'=58
'NOT'=59 'NATURAL'=59
'NULL'=60 'NOT'=60
'NULLS'=61 'NULL'=61
'ON'=62 'NULLS'=62
'OPTIMIZED'=63 'ON'=63
'OR'=64 'OPTIMIZED'=64
'ORDER'=65 'OR'=65
'OUTER'=66 'ORDER'=66
'PARSED'=67 'OUTER'=67
'PHYSICAL'=68 'PARSED'=68
'PLAN'=69 'PHYSICAL'=69
'RIGHT'=70 'PLAN'=70
'RLIKE'=71 'RIGHT'=71
'QUERY'=72 'RLIKE'=72
'SCHEMAS'=73 'QUERY'=73
'SECOND'=74 'SCHEMAS'=74
'SECONDS'=75 'SECOND'=75
'SELECT'=76 'SECONDS'=76
'SHOW'=77 'SELECT'=77
'SYS'=78 'SHOW'=78
'TABLE'=79 'SYS'=79
'TABLES'=80 'TABLE'=80
'TEXT'=81 'TABLES'=81
'TRUE'=82 'TEXT'=82
'TO'=83 'TRUE'=83
'TYPE'=84 'TO'=84
'TYPES'=85 'TYPE'=85
'USING'=86 'TYPES'=86
'VERIFY'=87 'USING'=87
'WHERE'=88 'VERIFY'=88
'WITH'=89 'WHERE'=89
'YEAR'=90 'WITH'=90
'YEARS'=91 'YEAR'=91
'{ESCAPE'=92 'YEARS'=92
'{FN'=93 '{ESCAPE'=93
'{LIMIT'=94 '{FN'=94
'{D'=95 '{LIMIT'=95
'{T'=96 '{D'=96
'{TS'=97 '{T'=97
'{GUID'=98 '{TS'=98
'}'=99 '{GUID'=99
'='=100 '}'=100
'<=>'=101 '='=101
'<'=103 '<=>'=102
'<='=104 '<'=104
'>'=105 '<='=105
'>='=106 '>'=106
'+'=107 '>='=107
'-'=108 '+'=108
'*'=109 '-'=109
'/'=110 '*'=110
'%'=111 '/'=111
'::'=112 '%'=112
'||'=113 '::'=113
'.'=114 '||'=114
'?'=115 '.'=115
'?'=116

View File

@ -17,114 +17,115 @@ CATALOGS=16
COLUMNS=17 COLUMNS=17
CONVERT=18 CONVERT=18
CURRENT_DATE=19 CURRENT_DATE=19
CURRENT_TIMESTAMP=20 CURRENT_TIME=20
DAY=21 CURRENT_TIMESTAMP=21
DAYS=22 DAY=22
DEBUG=23 DAYS=23
DESC=24 DEBUG=24
DESCRIBE=25 DESC=25
DISTINCT=26 DESCRIBE=26
ESCAPE=27 DISTINCT=27
EXECUTABLE=28 ESCAPE=28
EXISTS=29 EXECUTABLE=29
EXPLAIN=30 EXISTS=30
EXTRACT=31 EXPLAIN=31
FALSE=32 EXTRACT=32
FIRST=33 FALSE=33
FORMAT=34 FIRST=34
FROM=35 FORMAT=35
FULL=36 FROM=36
FUNCTIONS=37 FULL=37
GRAPHVIZ=38 FUNCTIONS=38
GROUP=39 GRAPHVIZ=39
HAVING=40 GROUP=40
HOUR=41 HAVING=41
HOURS=42 HOUR=42
IN=43 HOURS=43
INNER=44 IN=44
INTERVAL=45 INNER=45
IS=46 INTERVAL=46
JOIN=47 IS=47
LAST=48 JOIN=48
LEFT=49 LAST=49
LIKE=50 LEFT=50
LIMIT=51 LIKE=51
MAPPED=52 LIMIT=52
MATCH=53 MAPPED=53
MINUTE=54 MATCH=54
MINUTES=55 MINUTE=55
MONTH=56 MINUTES=56
MONTHS=57 MONTH=57
NATURAL=58 MONTHS=58
NOT=59 NATURAL=59
NULL=60 NOT=60
NULLS=61 NULL=61
ON=62 NULLS=62
OPTIMIZED=63 ON=63
OR=64 OPTIMIZED=64
ORDER=65 OR=65
OUTER=66 ORDER=66
PARSED=67 OUTER=67
PHYSICAL=68 PARSED=68
PLAN=69 PHYSICAL=69
RIGHT=70 PLAN=70
RLIKE=71 RIGHT=71
QUERY=72 RLIKE=72
SCHEMAS=73 QUERY=73
SECOND=74 SCHEMAS=74
SECONDS=75 SECOND=75
SELECT=76 SECONDS=76
SHOW=77 SELECT=77
SYS=78 SHOW=78
TABLE=79 SYS=79
TABLES=80 TABLE=80
TEXT=81 TABLES=81
TRUE=82 TEXT=82
TO=83 TRUE=83
TYPE=84 TO=84
TYPES=85 TYPE=85
USING=86 TYPES=86
VERIFY=87 USING=87
WHERE=88 VERIFY=88
WITH=89 WHERE=89
YEAR=90 WITH=90
YEARS=91 YEAR=91
ESCAPE_ESC=92 YEARS=92
FUNCTION_ESC=93 ESCAPE_ESC=93
LIMIT_ESC=94 FUNCTION_ESC=94
DATE_ESC=95 LIMIT_ESC=95
TIME_ESC=96 DATE_ESC=96
TIMESTAMP_ESC=97 TIME_ESC=97
GUID_ESC=98 TIMESTAMP_ESC=98
ESC_END=99 GUID_ESC=99
EQ=100 ESC_END=100
NULLEQ=101 EQ=101
NEQ=102 NULLEQ=102
LT=103 NEQ=103
LTE=104 LT=104
GT=105 LTE=105
GTE=106 GT=106
PLUS=107 GTE=107
MINUS=108 PLUS=108
ASTERISK=109 MINUS=109
SLASH=110 ASTERISK=110
PERCENT=111 SLASH=111
CAST_OP=112 PERCENT=112
CONCAT=113 CAST_OP=113
DOT=114 CONCAT=114
PARAM=115 DOT=115
STRING=116 PARAM=116
INTEGER_VALUE=117 STRING=117
DECIMAL_VALUE=118 INTEGER_VALUE=118
IDENTIFIER=119 DECIMAL_VALUE=119
DIGIT_IDENTIFIER=120 IDENTIFIER=120
TABLE_IDENTIFIER=121 DIGIT_IDENTIFIER=121
QUOTED_IDENTIFIER=122 TABLE_IDENTIFIER=122
BACKQUOTED_IDENTIFIER=123 QUOTED_IDENTIFIER=123
SIMPLE_COMMENT=124 BACKQUOTED_IDENTIFIER=124
BRACKETED_COMMENT=125 SIMPLE_COMMENT=125
WS=126 BRACKETED_COMMENT=126
UNRECOGNIZED=127 WS=127
UNRECOGNIZED=128
'('=1 '('=1
')'=2 ')'=2
','=3 ','=3
@ -144,98 +145,99 @@ UNRECOGNIZED=127
'COLUMNS'=17 'COLUMNS'=17
'CONVERT'=18 'CONVERT'=18
'CURRENT_DATE'=19 'CURRENT_DATE'=19
'CURRENT_TIMESTAMP'=20 'CURRENT_TIME'=20
'DAY'=21 'CURRENT_TIMESTAMP'=21
'DAYS'=22 'DAY'=22
'DEBUG'=23 'DAYS'=23
'DESC'=24 'DEBUG'=24
'DESCRIBE'=25 'DESC'=25
'DISTINCT'=26 'DESCRIBE'=26
'ESCAPE'=27 'DISTINCT'=27
'EXECUTABLE'=28 'ESCAPE'=28
'EXISTS'=29 'EXECUTABLE'=29
'EXPLAIN'=30 'EXISTS'=30
'EXTRACT'=31 'EXPLAIN'=31
'FALSE'=32 'EXTRACT'=32
'FIRST'=33 'FALSE'=33
'FORMAT'=34 'FIRST'=34
'FROM'=35 'FORMAT'=35
'FULL'=36 'FROM'=36
'FUNCTIONS'=37 'FULL'=37
'GRAPHVIZ'=38 'FUNCTIONS'=38
'GROUP'=39 'GRAPHVIZ'=39
'HAVING'=40 'GROUP'=40
'HOUR'=41 'HAVING'=41
'HOURS'=42 'HOUR'=42
'IN'=43 'HOURS'=43
'INNER'=44 'IN'=44
'INTERVAL'=45 'INNER'=45
'IS'=46 'INTERVAL'=46
'JOIN'=47 'IS'=47
'LAST'=48 'JOIN'=48
'LEFT'=49 'LAST'=49
'LIKE'=50 'LEFT'=50
'LIMIT'=51 'LIKE'=51
'MAPPED'=52 'LIMIT'=52
'MATCH'=53 'MAPPED'=53
'MINUTE'=54 'MATCH'=54
'MINUTES'=55 'MINUTE'=55
'MONTH'=56 'MINUTES'=56
'MONTHS'=57 'MONTH'=57
'NATURAL'=58 'MONTHS'=58
'NOT'=59 'NATURAL'=59
'NULL'=60 'NOT'=60
'NULLS'=61 'NULL'=61
'ON'=62 'NULLS'=62
'OPTIMIZED'=63 'ON'=63
'OR'=64 'OPTIMIZED'=64
'ORDER'=65 'OR'=65
'OUTER'=66 'ORDER'=66
'PARSED'=67 'OUTER'=67
'PHYSICAL'=68 'PARSED'=68
'PLAN'=69 'PHYSICAL'=69
'RIGHT'=70 'PLAN'=70
'RLIKE'=71 'RIGHT'=71
'QUERY'=72 'RLIKE'=72
'SCHEMAS'=73 'QUERY'=73
'SECOND'=74 'SCHEMAS'=74
'SECONDS'=75 'SECOND'=75
'SELECT'=76 'SECONDS'=76
'SHOW'=77 'SELECT'=77
'SYS'=78 'SHOW'=78
'TABLE'=79 'SYS'=79
'TABLES'=80 'TABLE'=80
'TEXT'=81 'TABLES'=81
'TRUE'=82 'TEXT'=82
'TO'=83 'TRUE'=83
'TYPE'=84 'TO'=84
'TYPES'=85 'TYPE'=85
'USING'=86 'TYPES'=86
'VERIFY'=87 'USING'=87
'WHERE'=88 'VERIFY'=88
'WITH'=89 'WHERE'=89
'YEAR'=90 'WITH'=90
'YEARS'=91 'YEAR'=91
'{ESCAPE'=92 'YEARS'=92
'{FN'=93 '{ESCAPE'=93
'{LIMIT'=94 '{FN'=94
'{D'=95 '{LIMIT'=95
'{T'=96 '{D'=96
'{TS'=97 '{T'=97
'{GUID'=98 '{TS'=98
'}'=99 '{GUID'=99
'='=100 '}'=100
'<=>'=101 '='=101
'<'=103 '<=>'=102
'<='=104 '<'=104
'>'=105 '<='=105
'>='=106 '>'=106
'+'=107 '>='=107
'-'=108 '+'=108
'*'=109 '-'=109
'/'=110 '*'=110
'%'=111 '/'=111
'::'=112 '%'=112
'||'=113 '::'=113
'.'=114 '||'=114
'?'=115 '.'=115
'?'=116

View File

@ -30,6 +30,7 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.Database;
import org.elasticsearch.xpack.sql.expression.function.scalar.User; import org.elasticsearch.xpack.sql.expression.function.scalar.User;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.CurrentDate; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.CurrentDate;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.CurrentDateTime; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.CurrentDateTime;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.CurrentTime;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayName; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayName;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayOfMonth; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayOfMonth;
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayOfWeek; import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayOfWeek;
@ -175,6 +176,7 @@ public class FunctionRegistry {
def(Least.class, Least::new, "LEAST")); def(Least.class, Least::new, "LEAST"));
// Date // Date
addToMap(def(CurrentDate.class, CurrentDate::new, "CURRENT_DATE", "CURDATE", "TODAY"), addToMap(def(CurrentDate.class, CurrentDate::new, "CURRENT_DATE", "CURDATE", "TODAY"),
def(CurrentTime.class, CurrentTime::new, "CURRENT_TIME", "CURTIME"),
def(CurrentDateTime.class, CurrentDateTime::new, "CURRENT_TIMESTAMP", "NOW"), def(CurrentDateTime.class, CurrentDateTime::new, "CURRENT_TIMESTAMP", "NOW"),
def(DayName.class, DayName::new, "DAY_NAME", "DAYNAME"), def(DayName.class, DayName::new, "DAY_NAME", "DAYNAME"),
def(DayOfMonth.class, DayOfMonth::new, "DAY_OF_MONTH", "DAYOFMONTH", "DAY", "DOM"), def(DayOfMonth.class, DayOfMonth::new, "DAY_OF_MONTH", "DAYOFMONTH", "DAY", "DOM"),

View File

@ -12,7 +12,9 @@ import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import org.elasticsearch.xpack.sql.util.DateUtils; import org.elasticsearch.xpack.sql.util.DateUtils;
public class CurrentDate extends CurrentFunction { import java.time.ZonedDateTime;
public class CurrentDate extends CurrentFunction<ZonedDateTime> {
public CurrentDate(Source source, Configuration configuration) { public CurrentDate(Source source, Configuration configuration) {
super(source, configuration, DateUtils.asDateOnly(configuration.now()), DataType.DATE); super(source, configuration, DateUtils.asDateOnly(configuration.now()), DataType.DATE);

View File

@ -15,7 +15,7 @@ import org.elasticsearch.xpack.sql.type.DataType;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
public class CurrentDateTime extends CurrentFunction { public class CurrentDateTime extends CurrentFunction<ZonedDateTime> {
private final Expression precision; private final Expression precision;

View File

@ -11,28 +11,29 @@ import org.elasticsearch.xpack.sql.session.Configuration;
import org.elasticsearch.xpack.sql.tree.Source; import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataType;
import java.time.ZonedDateTime; import java.time.temporal.Temporal;
import java.util.Objects; import java.util.Objects;
abstract class CurrentFunction extends ConfigurationFunction { abstract class CurrentFunction<T extends Temporal> extends ConfigurationFunction {
private final ZonedDateTime date; private final T current;
CurrentFunction(Source source, Configuration configuration, ZonedDateTime date, DataType dataType) { CurrentFunction(Source source, Configuration configuration, T current, DataType dataType) {
super(source, configuration, dataType); super(source, configuration, dataType);
this.date = date; this.current = current;
} }
@Override @Override
public Object fold() { public Object fold() {
return date; return current;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(date); return Objects.hash(current);
} }
@SuppressWarnings("rawtypes")
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) { if (this == obj) {
@ -44,6 +45,6 @@ abstract class CurrentFunction extends ConfigurationFunction {
} }
CurrentFunction other = (CurrentFunction) obj; CurrentFunction other = (CurrentFunction) obj;
return Objects.equals(date, other.date); return Objects.equals(current, other.current);
} }
} }

View File

@ -0,0 +1,47 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.datetime;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Foldables;
import org.elasticsearch.xpack.sql.session.Configuration;
import org.elasticsearch.xpack.sql.tree.NodeInfo;
import org.elasticsearch.xpack.sql.tree.Source;
import org.elasticsearch.xpack.sql.type.DataType;
import java.time.OffsetTime;
public class CurrentTime extends CurrentFunction<OffsetTime> {
private final Expression precision;
public CurrentTime(Source source, Expression precision, Configuration configuration) {
super(source, configuration, nanoPrecision(configuration.now().toOffsetDateTime().toOffsetTime(), precision),
DataType.TIME);
this.precision = precision;
}
Expression precision() {
return precision;
}
@Override
protected NodeInfo<CurrentTime> info() {
return NodeInfo.create(this, CurrentTime::new, precision, configuration());
}
static OffsetTime nanoPrecision(OffsetTime ot, Expression precisionExpression) {
int precision = precisionExpression != null ? Foldables.intValueOf(precisionExpression) : 3;
int nano = ot.getNano();
if (precision >= 0 && precision < 10) {
// remove the remainder
nano = nano - nano % (int) Math.pow(10, (9 - precision));
return ot.withNano(nano);
}
return ot;
}
}

View File

@ -449,9 +449,11 @@ abstract class ExpressionBuilder extends IdentifierBuilder {
String functionName = ctx.name.getText(); String functionName = ctx.name.getText();
switch (ctx.name.getType()) { switch (ctx.name.getType()) {
case SqlBaseLexer.CURRENT_TIMESTAMP:
return new UnresolvedFunction(source, functionName, ResolutionType.STANDARD, p != null ? singletonList(p) : emptyList());
case SqlBaseLexer.CURRENT_DATE: case SqlBaseLexer.CURRENT_DATE:
return new UnresolvedFunction(source, functionName, ResolutionType.STANDARD, emptyList()); return new UnresolvedFunction(source, functionName, ResolutionType.STANDARD, emptyList());
case SqlBaseLexer.CURRENT_TIMESTAMP: case SqlBaseLexer.CURRENT_TIME:
return new UnresolvedFunction(source, functionName, ResolutionType.STANDARD, p != null ? singletonList(p) : emptyList()); return new UnresolvedFunction(source, functionName, ResolutionType.STANDARD, p != null ? singletonList(p) : emptyList());
default: default:
throw new ParsingException(source, "Unknown function [{}]", functionName); throw new ParsingException(source, "Unknown function [{}]", functionName);

View File

@ -19,23 +19,24 @@ class SqlBaseLexer extends Lexer {
public static final int public static final int
T__0=1, T__1=2, T__2=3, T__3=4, ALL=5, ANALYZE=6, ANALYZED=7, AND=8, ANY=9, T__0=1, T__1=2, T__2=3, T__3=4, ALL=5, ANALYZE=6, ANALYZED=7, AND=8, ANY=9,
AS=10, ASC=11, BETWEEN=12, BY=13, CAST=14, CATALOG=15, CATALOGS=16, COLUMNS=17, AS=10, ASC=11, BETWEEN=12, BY=13, CAST=14, CATALOG=15, CATALOGS=16, COLUMNS=17,
CONVERT=18, CURRENT_DATE=19, CURRENT_TIMESTAMP=20, DAY=21, DAYS=22, DEBUG=23, CONVERT=18, CURRENT_DATE=19, CURRENT_TIME=20, CURRENT_TIMESTAMP=21, DAY=22,
DESC=24, DESCRIBE=25, DISTINCT=26, ESCAPE=27, EXECUTABLE=28, EXISTS=29, DAYS=23, DEBUG=24, DESC=25, DESCRIBE=26, DISTINCT=27, ESCAPE=28, EXECUTABLE=29,
EXPLAIN=30, EXTRACT=31, FALSE=32, FIRST=33, FORMAT=34, FROM=35, FULL=36, EXISTS=30, EXPLAIN=31, EXTRACT=32, FALSE=33, FIRST=34, FORMAT=35, FROM=36,
FUNCTIONS=37, GRAPHVIZ=38, GROUP=39, HAVING=40, HOUR=41, HOURS=42, IN=43, FULL=37, FUNCTIONS=38, GRAPHVIZ=39, GROUP=40, HAVING=41, HOUR=42, HOURS=43,
INNER=44, INTERVAL=45, IS=46, JOIN=47, LAST=48, LEFT=49, LIKE=50, LIMIT=51, IN=44, INNER=45, INTERVAL=46, IS=47, JOIN=48, LAST=49, LEFT=50, LIKE=51,
MAPPED=52, MATCH=53, MINUTE=54, MINUTES=55, MONTH=56, MONTHS=57, NATURAL=58, LIMIT=52, MAPPED=53, MATCH=54, MINUTE=55, MINUTES=56, MONTH=57, MONTHS=58,
NOT=59, NULL=60, NULLS=61, ON=62, OPTIMIZED=63, OR=64, ORDER=65, OUTER=66, NATURAL=59, NOT=60, NULL=61, NULLS=62, ON=63, OPTIMIZED=64, OR=65, ORDER=66,
PARSED=67, PHYSICAL=68, PLAN=69, RIGHT=70, RLIKE=71, QUERY=72, SCHEMAS=73, OUTER=67, PARSED=68, PHYSICAL=69, PLAN=70, RIGHT=71, RLIKE=72, QUERY=73,
SECOND=74, SECONDS=75, SELECT=76, SHOW=77, SYS=78, TABLE=79, TABLES=80, SCHEMAS=74, SECOND=75, SECONDS=76, SELECT=77, SHOW=78, SYS=79, TABLE=80,
TEXT=81, TRUE=82, TO=83, TYPE=84, TYPES=85, USING=86, VERIFY=87, WHERE=88, TABLES=81, TEXT=82, TRUE=83, TO=84, TYPE=85, TYPES=86, USING=87, VERIFY=88,
WITH=89, YEAR=90, YEARS=91, ESCAPE_ESC=92, FUNCTION_ESC=93, LIMIT_ESC=94, WHERE=89, WITH=90, YEAR=91, YEARS=92, ESCAPE_ESC=93, FUNCTION_ESC=94,
DATE_ESC=95, TIME_ESC=96, TIMESTAMP_ESC=97, GUID_ESC=98, ESC_END=99, EQ=100, LIMIT_ESC=95, DATE_ESC=96, TIME_ESC=97, TIMESTAMP_ESC=98, GUID_ESC=99,
NULLEQ=101, NEQ=102, LT=103, LTE=104, GT=105, GTE=106, PLUS=107, MINUS=108, ESC_END=100, EQ=101, NULLEQ=102, NEQ=103, LT=104, LTE=105, GT=106, GTE=107,
ASTERISK=109, SLASH=110, PERCENT=111, CAST_OP=112, CONCAT=113, DOT=114, PLUS=108, MINUS=109, ASTERISK=110, SLASH=111, PERCENT=112, CAST_OP=113,
PARAM=115, STRING=116, INTEGER_VALUE=117, DECIMAL_VALUE=118, IDENTIFIER=119, CONCAT=114, DOT=115, PARAM=116, STRING=117, INTEGER_VALUE=118, DECIMAL_VALUE=119,
DIGIT_IDENTIFIER=120, TABLE_IDENTIFIER=121, QUOTED_IDENTIFIER=122, BACKQUOTED_IDENTIFIER=123, IDENTIFIER=120, DIGIT_IDENTIFIER=121, TABLE_IDENTIFIER=122, QUOTED_IDENTIFIER=123,
SIMPLE_COMMENT=124, BRACKETED_COMMENT=125, WS=126, UNRECOGNIZED=127; BACKQUOTED_IDENTIFIER=124, SIMPLE_COMMENT=125, BRACKETED_COMMENT=126,
WS=127, UNRECOGNIZED=128;
public static String[] modeNames = { public static String[] modeNames = {
"DEFAULT_MODE" "DEFAULT_MODE"
}; };
@ -43,62 +44,62 @@ class SqlBaseLexer extends Lexer {
public static final String[] ruleNames = { public static final String[] ruleNames = {
"T__0", "T__1", "T__2", "T__3", "ALL", "ANALYZE", "ANALYZED", "AND", "ANY", "T__0", "T__1", "T__2", "T__3", "ALL", "ANALYZE", "ANALYZED", "AND", "ANY",
"AS", "ASC", "BETWEEN", "BY", "CAST", "CATALOG", "CATALOGS", "COLUMNS", "AS", "ASC", "BETWEEN", "BY", "CAST", "CATALOG", "CATALOGS", "COLUMNS",
"CONVERT", "CURRENT_DATE", "CURRENT_TIMESTAMP", "DAY", "DAYS", "DEBUG", "CONVERT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "DAY",
"DESC", "DESCRIBE", "DISTINCT", "ESCAPE", "EXECUTABLE", "EXISTS", "EXPLAIN", "DAYS", "DEBUG", "DESC", "DESCRIBE", "DISTINCT", "ESCAPE", "EXECUTABLE",
"EXTRACT", "FALSE", "FIRST", "FORMAT", "FROM", "FULL", "FUNCTIONS", "GRAPHVIZ", "EXISTS", "EXPLAIN", "EXTRACT", "FALSE", "FIRST", "FORMAT", "FROM", "FULL",
"GROUP", "HAVING", "HOUR", "HOURS", "IN", "INNER", "INTERVAL", "IS", "JOIN", "FUNCTIONS", "GRAPHVIZ", "GROUP", "HAVING", "HOUR", "HOURS", "IN", "INNER",
"LAST", "LEFT", "LIKE", "LIMIT", "MAPPED", "MATCH", "MINUTE", "MINUTES", "INTERVAL", "IS", "JOIN", "LAST", "LEFT", "LIKE", "LIMIT", "MAPPED", "MATCH",
"MONTH", "MONTHS", "NATURAL", "NOT", "NULL", "NULLS", "ON", "OPTIMIZED", "MINUTE", "MINUTES", "MONTH", "MONTHS", "NATURAL", "NOT", "NULL", "NULLS",
"OR", "ORDER", "OUTER", "PARSED", "PHYSICAL", "PLAN", "RIGHT", "RLIKE", "ON", "OPTIMIZED", "OR", "ORDER", "OUTER", "PARSED", "PHYSICAL", "PLAN",
"QUERY", "SCHEMAS", "SECOND", "SECONDS", "SELECT", "SHOW", "SYS", "TABLE", "RIGHT", "RLIKE", "QUERY", "SCHEMAS", "SECOND", "SECONDS", "SELECT", "SHOW",
"TABLES", "TEXT", "TRUE", "TO", "TYPE", "TYPES", "USING", "VERIFY", "WHERE", "SYS", "TABLE", "TABLES", "TEXT", "TRUE", "TO", "TYPE", "TYPES", "USING",
"WITH", "YEAR", "YEARS", "ESCAPE_ESC", "FUNCTION_ESC", "LIMIT_ESC", "DATE_ESC", "VERIFY", "WHERE", "WITH", "YEAR", "YEARS", "ESCAPE_ESC", "FUNCTION_ESC",
"TIME_ESC", "TIMESTAMP_ESC", "GUID_ESC", "ESC_END", "EQ", "NULLEQ", "NEQ", "LIMIT_ESC", "DATE_ESC", "TIME_ESC", "TIMESTAMP_ESC", "GUID_ESC", "ESC_END",
"LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "EQ", "NULLEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK",
"CAST_OP", "CONCAT", "DOT", "PARAM", "STRING", "INTEGER_VALUE", "DECIMAL_VALUE", "SLASH", "PERCENT", "CAST_OP", "CONCAT", "DOT", "PARAM", "STRING", "INTEGER_VALUE",
"IDENTIFIER", "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", "QUOTED_IDENTIFIER", "DECIMAL_VALUE", "IDENTIFIER", "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER",
"BACKQUOTED_IDENTIFIER", "EXPONENT", "DIGIT", "LETTER", "SIMPLE_COMMENT", "QUOTED_IDENTIFIER", "BACKQUOTED_IDENTIFIER", "EXPONENT", "DIGIT", "LETTER",
"BRACKETED_COMMENT", "WS", "UNRECOGNIZED" "SIMPLE_COMMENT", "BRACKETED_COMMENT", "WS", "UNRECOGNIZED"
}; };
private static final String[] _LITERAL_NAMES = { private static final String[] _LITERAL_NAMES = {
null, "'('", "')'", "','", "':'", "'ALL'", "'ANALYZE'", "'ANALYZED'", null, "'('", "')'", "','", "':'", "'ALL'", "'ANALYZE'", "'ANALYZED'",
"'AND'", "'ANY'", "'AS'", "'ASC'", "'BETWEEN'", "'BY'", "'CAST'", "'CATALOG'", "'AND'", "'ANY'", "'AS'", "'ASC'", "'BETWEEN'", "'BY'", "'CAST'", "'CATALOG'",
"'CATALOGS'", "'COLUMNS'", "'CONVERT'", "'CURRENT_DATE'", "'CURRENT_TIMESTAMP'", "'CATALOGS'", "'COLUMNS'", "'CONVERT'", "'CURRENT_DATE'", "'CURRENT_TIME'",
"'DAY'", "'DAYS'", "'DEBUG'", "'DESC'", "'DESCRIBE'", "'DISTINCT'", "'ESCAPE'", "'CURRENT_TIMESTAMP'", "'DAY'", "'DAYS'", "'DEBUG'", "'DESC'", "'DESCRIBE'",
"'EXECUTABLE'", "'EXISTS'", "'EXPLAIN'", "'EXTRACT'", "'FALSE'", "'FIRST'", "'DISTINCT'", "'ESCAPE'", "'EXECUTABLE'", "'EXISTS'", "'EXPLAIN'", "'EXTRACT'",
"'FORMAT'", "'FROM'", "'FULL'", "'FUNCTIONS'", "'GRAPHVIZ'", "'GROUP'", "'FALSE'", "'FIRST'", "'FORMAT'", "'FROM'", "'FULL'", "'FUNCTIONS'", "'GRAPHVIZ'",
"'HAVING'", "'HOUR'", "'HOURS'", "'IN'", "'INNER'", "'INTERVAL'", "'IS'", "'GROUP'", "'HAVING'", "'HOUR'", "'HOURS'", "'IN'", "'INNER'", "'INTERVAL'",
"'JOIN'", "'LAST'", "'LEFT'", "'LIKE'", "'LIMIT'", "'MAPPED'", "'MATCH'", "'IS'", "'JOIN'", "'LAST'", "'LEFT'", "'LIKE'", "'LIMIT'", "'MAPPED'",
"'MINUTE'", "'MINUTES'", "'MONTH'", "'MONTHS'", "'NATURAL'", "'NOT'", "'MATCH'", "'MINUTE'", "'MINUTES'", "'MONTH'", "'MONTHS'", "'NATURAL'",
"'NULL'", "'NULLS'", "'ON'", "'OPTIMIZED'", "'OR'", "'ORDER'", "'OUTER'", "'NOT'", "'NULL'", "'NULLS'", "'ON'", "'OPTIMIZED'", "'OR'", "'ORDER'",
"'PARSED'", "'PHYSICAL'", "'PLAN'", "'RIGHT'", "'RLIKE'", "'QUERY'", "'SCHEMAS'", "'OUTER'", "'PARSED'", "'PHYSICAL'", "'PLAN'", "'RIGHT'", "'RLIKE'", "'QUERY'",
"'SECOND'", "'SECONDS'", "'SELECT'", "'SHOW'", "'SYS'", "'TABLE'", "'TABLES'", "'SCHEMAS'", "'SECOND'", "'SECONDS'", "'SELECT'", "'SHOW'", "'SYS'", "'TABLE'",
"'TEXT'", "'TRUE'", "'TO'", "'TYPE'", "'TYPES'", "'USING'", "'VERIFY'", "'TABLES'", "'TEXT'", "'TRUE'", "'TO'", "'TYPE'", "'TYPES'", "'USING'",
"'WHERE'", "'WITH'", "'YEAR'", "'YEARS'", "'{ESCAPE'", "'{FN'", "'{LIMIT'", "'VERIFY'", "'WHERE'", "'WITH'", "'YEAR'", "'YEARS'", "'{ESCAPE'", "'{FN'",
"'{D'", "'{T'", "'{TS'", "'{GUID'", "'}'", "'='", "'<=>'", null, "'<'", "'{LIMIT'", "'{D'", "'{T'", "'{TS'", "'{GUID'", "'}'", "'='", "'<=>'",
"'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", "'::'", "'||'", null, "'<'", "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'",
"'.'", "'?'" "'::'", "'||'", "'.'", "'?'"
}; };
private static final String[] _SYMBOLIC_NAMES = { private static final String[] _SYMBOLIC_NAMES = {
null, null, null, null, null, "ALL", "ANALYZE", "ANALYZED", "AND", "ANY", null, null, null, null, null, "ALL", "ANALYZE", "ANALYZED", "AND", "ANY",
"AS", "ASC", "BETWEEN", "BY", "CAST", "CATALOG", "CATALOGS", "COLUMNS", "AS", "ASC", "BETWEEN", "BY", "CAST", "CATALOG", "CATALOGS", "COLUMNS",
"CONVERT", "CURRENT_DATE", "CURRENT_TIMESTAMP", "DAY", "DAYS", "DEBUG", "CONVERT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "DAY",
"DESC", "DESCRIBE", "DISTINCT", "ESCAPE", "EXECUTABLE", "EXISTS", "EXPLAIN", "DAYS", "DEBUG", "DESC", "DESCRIBE", "DISTINCT", "ESCAPE", "EXECUTABLE",
"EXTRACT", "FALSE", "FIRST", "FORMAT", "FROM", "FULL", "FUNCTIONS", "GRAPHVIZ", "EXISTS", "EXPLAIN", "EXTRACT", "FALSE", "FIRST", "FORMAT", "FROM", "FULL",
"GROUP", "HAVING", "HOUR", "HOURS", "IN", "INNER", "INTERVAL", "IS", "JOIN", "FUNCTIONS", "GRAPHVIZ", "GROUP", "HAVING", "HOUR", "HOURS", "IN", "INNER",
"LAST", "LEFT", "LIKE", "LIMIT", "MAPPED", "MATCH", "MINUTE", "MINUTES", "INTERVAL", "IS", "JOIN", "LAST", "LEFT", "LIKE", "LIMIT", "MAPPED", "MATCH",
"MONTH", "MONTHS", "NATURAL", "NOT", "NULL", "NULLS", "ON", "OPTIMIZED", "MINUTE", "MINUTES", "MONTH", "MONTHS", "NATURAL", "NOT", "NULL", "NULLS",
"OR", "ORDER", "OUTER", "PARSED", "PHYSICAL", "PLAN", "RIGHT", "RLIKE", "ON", "OPTIMIZED", "OR", "ORDER", "OUTER", "PARSED", "PHYSICAL", "PLAN",
"QUERY", "SCHEMAS", "SECOND", "SECONDS", "SELECT", "SHOW", "SYS", "TABLE", "RIGHT", "RLIKE", "QUERY", "SCHEMAS", "SECOND", "SECONDS", "SELECT", "SHOW",
"TABLES", "TEXT", "TRUE", "TO", "TYPE", "TYPES", "USING", "VERIFY", "WHERE", "SYS", "TABLE", "TABLES", "TEXT", "TRUE", "TO", "TYPE", "TYPES", "USING",
"WITH", "YEAR", "YEARS", "ESCAPE_ESC", "FUNCTION_ESC", "LIMIT_ESC", "DATE_ESC", "VERIFY", "WHERE", "WITH", "YEAR", "YEARS", "ESCAPE_ESC", "FUNCTION_ESC",
"TIME_ESC", "TIMESTAMP_ESC", "GUID_ESC", "ESC_END", "EQ", "NULLEQ", "NEQ", "LIMIT_ESC", "DATE_ESC", "TIME_ESC", "TIMESTAMP_ESC", "GUID_ESC", "ESC_END",
"LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "EQ", "NULLEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK",
"CAST_OP", "CONCAT", "DOT", "PARAM", "STRING", "INTEGER_VALUE", "DECIMAL_VALUE", "SLASH", "PERCENT", "CAST_OP", "CONCAT", "DOT", "PARAM", "STRING", "INTEGER_VALUE",
"IDENTIFIER", "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", "QUOTED_IDENTIFIER", "DECIMAL_VALUE", "IDENTIFIER", "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER",
"BACKQUOTED_IDENTIFIER", "SIMPLE_COMMENT", "BRACKETED_COMMENT", "WS", "QUOTED_IDENTIFIER", "BACKQUOTED_IDENTIFIER", "SIMPLE_COMMENT", "BRACKETED_COMMENT",
"UNRECOGNIZED" "WS", "UNRECOGNIZED"
}; };
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
@ -155,7 +156,7 @@ class SqlBaseLexer extends Lexer {
public ATN getATN() { return _ATN; } public ATN getATN() { return _ATN; }
public static final String _serializedATN = public static final String _serializedATN =
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\u0081\u042d\b\1\4"+ "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\u0082\u043c\b\1\4"+
"\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n"+ "\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n"+
"\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+ "\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22"+
"\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+ "\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31"+
@ -169,356 +170,361 @@ class SqlBaseLexer extends Lexer {
"\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k"+ "\4`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k"+
"\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv"+ "\tk\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv"+
"\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080\t"+ "\4w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080\t"+
"\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\3\2\3\2\3\3\3\3"+ "\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084"+
"\3\4\3\4\3\5\3\5\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3"+ "\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3"+
"\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\13\3"+ "\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\n\3\n"+
"\13\3\13\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16"+ "\3\n\3\n\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3"+
"\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\20\3\21"+ "\r\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3"+
"\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22"+ "\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3"+
"\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24"+ "\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3"+
"\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25"+ "\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3"+
"\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\26"+ "\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3"+
"\3\26\3\26\3\26\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30"+ "\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3"+
"\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32"+ "\26\3\26\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3"+
"\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3\34"+ "\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3"+
"\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3\36"+ "\33\3\33\3\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3"+
"\3\36\3\36\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37"+ "\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3"+
"\3 \3 \3 \3 \3 \3 \3 \3 \3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3\"\3\"\3#"+ "\36\3\36\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \3 \3 \3 \3"+
"\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3&\3&"+ "!\3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3#\3#\3$\3"+
"\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3(\3(\3)\3)"+ "$\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3\'"+
"\3)\3)\3)\3)\3)\3*\3*\3*\3*\3*\3+\3+\3+\3+\3+\3+\3,\3,\3,\3-\3-\3-\3-"+ "\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3(\3(\3(\3(\3(\3)\3)\3)\3)\3)\3)\3*\3*\3"+
"\3-\3-\3.\3.\3.\3.\3.\3.\3.\3.\3.\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\3"+ "*\3*\3*\3*\3*\3+\3+\3+\3+\3+\3,\3,\3,\3,\3,\3,\3-\3-\3-\3.\3.\3.\3.\3"+
"\61\3\61\3\61\3\61\3\61\3\62\3\62\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3"+ ".\3.\3/\3/\3/\3/\3/\3/\3/\3/\3/\3\60\3\60\3\60\3\61\3\61\3\61\3\61\3\61"+
"\63\3\64\3\64\3\64\3\64\3\64\3\64\3\65\3\65\3\65\3\65\3\65\3\65\3\65\3"+ "\3\62\3\62\3\62\3\62\3\62\3\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64"+
"\66\3\66\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\3\67\3\67\3\67\38\38"+ "\3\64\3\65\3\65\3\65\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\66\3\66\3\66"+
"\38\38\38\38\38\38\39\39\39\39\39\39\3:\3:\3:\3:\3:\3:\3:\3;\3;\3;\3;"+ "\3\67\3\67\3\67\3\67\3\67\3\67\38\38\38\38\38\38\38\39\39\39\39\39\39"+
"\3;\3;\3;\3;\3<\3<\3<\3<\3=\3=\3=\3=\3=\3>\3>\3>\3>\3>\3>\3?\3?\3?\3@"+ "\39\39\3:\3:\3:\3:\3:\3:\3;\3;\3;\3;\3;\3;\3;\3<\3<\3<\3<\3<\3<\3<\3<"+
"\3@\3@\3@\3@\3@\3@\3@\3@\3@\3A\3A\3A\3B\3B\3B\3B\3B\3B\3C\3C\3C\3C\3C"+ "\3=\3=\3=\3=\3>\3>\3>\3>\3>\3?\3?\3?\3?\3?\3?\3@\3@\3@\3A\3A\3A\3A\3A"+
"\3C\3D\3D\3D\3D\3D\3D\3D\3E\3E\3E\3E\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3G"+ "\3A\3A\3A\3A\3A\3B\3B\3B\3C\3C\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3E\3E\3E"+
"\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3I\3J\3J\3J\3J\3J\3J"+ "\3E\3E\3E\3E\3F\3F\3F\3F\3F\3F\3F\3F\3F\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H"+
"\3J\3J\3K\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3L\3L\3M\3M\3M\3M\3M\3M"+ "\3H\3I\3I\3I\3I\3I\3I\3J\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3K\3K\3L\3L"+
"\3M\3N\3N\3N\3N\3N\3O\3O\3O\3O\3P\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q"+ "\3L\3L\3L\3L\3L\3M\3M\3M\3M\3M\3M\3M\3M\3N\3N\3N\3N\3N\3N\3N\3O\3O\3O"+
"\3R\3R\3R\3R\3R\3S\3S\3S\3S\3S\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3V\3V\3V"+ "\3O\3O\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3S\3S\3S\3S"+
"\3V\3W\3W\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3Z"+ "\3S\3T\3T\3T\3T\3T\3U\3U\3U\3V\3V\3V\3V\3V\3W\3W\3W\3W\3W\3W\3X\3X\3X"+
"\3Z\3Z\3[\3[\3[\3[\3[\3\\\3\\\3\\\3\\\3\\\3\\\3]\3]\3]\3]\3]\3]\3]\3]"+ "\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3[\3\\\3"+
"\3^\3^\3^\3^\3_\3_\3_\3_\3_\3_\3_\3`\3`\3`\3a\3a\3a\3b\3b\3b\3b\3c\3c"+ "\\\3\\\3\\\3\\\3]\3]\3]\3]\3]\3]\3^\3^\3^\3^\3^\3^\3^\3^\3_\3_\3_\3_\3"+
"\3c\3c\3c\3c\3d\3d\3e\3e\3f\3f\3f\3f\3g\3g\3g\3g\5g\u036b\ng\3h\3h\3i"+ "`\3`\3`\3`\3`\3`\3`\3a\3a\3a\3b\3b\3b\3c\3c\3c\3c\3d\3d\3d\3d\3d\3d\3"+
"\3i\3i\3j\3j\3k\3k\3k\3l\3l\3m\3m\3n\3n\3o\3o\3p\3p\3q\3q\3q\3r\3r\3r"+ "e\3e\3f\3f\3g\3g\3g\3g\3h\3h\3h\3h\5h\u037a\nh\3i\3i\3j\3j\3j\3k\3k\3"+
"\3s\3s\3t\3t\3u\3u\3u\3u\7u\u038f\nu\fu\16u\u0392\13u\3u\3u\3v\6v\u0397"+ "l\3l\3l\3m\3m\3n\3n\3o\3o\3p\3p\3q\3q\3r\3r\3r\3s\3s\3s\3t\3t\3u\3u\3"+
"\nv\rv\16v\u0398\3w\6w\u039c\nw\rw\16w\u039d\3w\3w\7w\u03a2\nw\fw\16w"+ "v\3v\3v\3v\7v\u039e\nv\fv\16v\u03a1\13v\3v\3v\3w\6w\u03a6\nw\rw\16w\u03a7"+
"\u03a5\13w\3w\3w\6w\u03a9\nw\rw\16w\u03aa\3w\6w\u03ae\nw\rw\16w\u03af"+ "\3x\6x\u03ab\nx\rx\16x\u03ac\3x\3x\7x\u03b1\nx\fx\16x\u03b4\13x\3x\3x"+
"\3w\3w\7w\u03b4\nw\fw\16w\u03b7\13w\5w\u03b9\nw\3w\3w\3w\3w\6w\u03bf\n"+ "\6x\u03b8\nx\rx\16x\u03b9\3x\6x\u03bd\nx\rx\16x\u03be\3x\3x\7x\u03c3\n"+
"w\rw\16w\u03c0\3w\3w\5w\u03c5\nw\3x\3x\5x\u03c9\nx\3x\3x\3x\7x\u03ce\n"+ "x\fx\16x\u03c6\13x\5x\u03c8\nx\3x\3x\3x\3x\6x\u03ce\nx\rx\16x\u03cf\3"+
"x\fx\16x\u03d1\13x\3y\3y\3y\3y\6y\u03d7\ny\ry\16y\u03d8\3z\3z\3z\6z\u03de"+ "x\3x\5x\u03d4\nx\3y\3y\5y\u03d8\ny\3y\3y\3y\7y\u03dd\ny\fy\16y\u03e0\13"+
"\nz\rz\16z\u03df\3{\3{\3{\3{\7{\u03e6\n{\f{\16{\u03e9\13{\3{\3{\3|\3|"+ "y\3z\3z\3z\3z\6z\u03e6\nz\rz\16z\u03e7\3{\3{\3{\6{\u03ed\n{\r{\16{\u03ee"+
"\3|\3|\7|\u03f1\n|\f|\16|\u03f4\13|\3|\3|\3}\3}\5}\u03fa\n}\3}\6}\u03fd"+ "\3|\3|\3|\3|\7|\u03f5\n|\f|\16|\u03f8\13|\3|\3|\3}\3}\3}\3}\7}\u0400\n"+
"\n}\r}\16}\u03fe\3~\3~\3\177\3\177\3\u0080\3\u0080\3\u0080\3\u0080\7\u0080"+ "}\f}\16}\u0403\13}\3}\3}\3~\3~\5~\u0409\n~\3~\6~\u040c\n~\r~\16~\u040d"+
"\u0409\n\u0080\f\u0080\16\u0080\u040c\13\u0080\3\u0080\5\u0080\u040f\n"+ "\3\177\3\177\3\u0080\3\u0080\3\u0081\3\u0081\3\u0081\3\u0081\7\u0081\u0418"+
"\u0080\3\u0080\5\u0080\u0412\n\u0080\3\u0080\3\u0080\3\u0081\3\u0081\3"+ "\n\u0081\f\u0081\16\u0081\u041b\13\u0081\3\u0081\5\u0081\u041e\n\u0081"+
"\u0081\3\u0081\3\u0081\7\u0081\u041b\n\u0081\f\u0081\16\u0081\u041e\13"+ "\3\u0081\5\u0081\u0421\n\u0081\3\u0081\3\u0081\3\u0082\3\u0082\3\u0082"+
"\u0081\3\u0081\3\u0081\3\u0081\3\u0081\3\u0081\3\u0082\6\u0082\u0426\n"+ "\3\u0082\3\u0082\7\u0082\u042a\n\u0082\f\u0082\16\u0082\u042d\13\u0082"+
"\u0082\r\u0082\16\u0082\u0427\3\u0082\3\u0082\3\u0083\3\u0083\3\u041c"+ "\3\u0082\3\u0082\3\u0082\3\u0082\3\u0082\3\u0083\6\u0083\u0435\n\u0083"+
"\2\u0084\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17"+ "\r\u0083\16\u0083\u0436\3\u0083\3\u0083\3\u0084\3\u0084\3\u042b\2\u0085"+
"\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\35"+ "\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20"+
"9\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66"+ "\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37"+
"k\67m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG"+ "= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o"+
"\u008dH\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009f"+ "9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH"+
"Q\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3"+ "\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1"+
"[\u00b5\\\u00b7]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7"+ "R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5"+
"e\u00c9f\u00cbg\u00cdh\u00cfi\u00d1j\u00d3k\u00d5l\u00d7m\u00d9n\u00db"+ "\\\u00b7]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9"+
"o\u00ddp\u00dfq\u00e1r\u00e3s\u00e5t\u00e7u\u00e9v\u00ebw\u00edx\u00ef"+ "f\u00cbg\u00cdh\u00cfi\u00d1j\u00d3k\u00d5l\u00d7m\u00d9n\u00dbo\u00dd"+
"y\u00f1z\u00f3{\u00f5|\u00f7}\u00f9\2\u00fb\2\u00fd\2\u00ff~\u0101\177"+ "p\u00dfq\u00e1r\u00e3s\u00e5t\u00e7u\u00e9v\u00ebw\u00edx\u00efy\u00f1"+
"\u0103\u0080\u0105\u0081\3\2\13\3\2))\4\2BBaa\3\2$$\3\2bb\4\2--//\3\2"+ "z\u00f3{\u00f5|\u00f7}\u00f9~\u00fb\2\u00fd\2\u00ff\2\u0101\177\u0103"+
"\62;\3\2C\\\4\2\f\f\17\17\5\2\13\f\17\17\"\"\u044d\2\3\3\2\2\2\2\5\3\2"+ "\u0080\u0105\u0081\u0107\u0082\3\2\13\3\2))\4\2BBaa\3\2$$\3\2bb\4\2--"+
"\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21"+ "//\3\2\62;\3\2C\\\4\2\f\f\17\17\5\2\13\f\17\17\"\"\u045c\2\3\3\2\2\2\2"+
"\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2"+ "\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2"+
"\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3"+ "\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2"+
"\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3"+ "\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2"+
"\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3"+ "\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2"+
"\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2"+ "\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2"+
"\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2"+ "\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2"+
"Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3"+ "K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3"+
"\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2"+ "\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2"+
"\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2"+ "\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2"+
"\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3"+ "q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3"+
"\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2"+ "\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2"+
"\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099"+ "\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f"+
"\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2"+ "\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2"+
"\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab"+ "\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1"+
"\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2"+ "\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2"+
"\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd"+ "\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3"+
"\3\2\2\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2"+ "\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2"+
"\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf"+ "\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5"+
"\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00d7\3\2\2"+ "\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2"+
"\2\2\u00d9\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df\3\2\2\2\2\u00e1"+ "\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00d7"+
"\3\2\2\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9\3\2\2"+ "\3\2\2\2\2\u00d9\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df\3\2\2"+
"\2\2\u00eb\3\2\2\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1\3\2\2\2\2\u00f3"+ "\2\2\u00e1\3\2\2\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7\3\2\2\2\2\u00e9"+
"\3\2\2\2\2\u00f5\3\2\2\2\2\u00f7\3\2\2\2\2\u00ff\3\2\2\2\2\u0101\3\2\2"+ "\3\2\2\2\2\u00eb\3\2\2\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1\3\2\2"+
"\2\2\u0103\3\2\2\2\2\u0105\3\2\2\2\3\u0107\3\2\2\2\5\u0109\3\2\2\2\7\u010b"+ "\2\2\u00f3\3\2\2\2\2\u00f5\3\2\2\2\2\u00f7\3\2\2\2\2\u00f9\3\2\2\2\2\u0101"+
"\3\2\2\2\t\u010d\3\2\2\2\13\u010f\3\2\2\2\r\u0113\3\2\2\2\17\u011b\3\2"+ "\3\2\2\2\2\u0103\3\2\2\2\2\u0105\3\2\2\2\2\u0107\3\2\2\2\3\u0109\3\2\2"+
"\2\2\21\u0124\3\2\2\2\23\u0128\3\2\2\2\25\u012c\3\2\2\2\27\u012f\3\2\2"+ "\2\5\u010b\3\2\2\2\7\u010d\3\2\2\2\t\u010f\3\2\2\2\13\u0111\3\2\2\2\r"+
"\2\31\u0133\3\2\2\2\33\u013b\3\2\2\2\35\u013e\3\2\2\2\37\u0143\3\2\2\2"+ "\u0115\3\2\2\2\17\u011d\3\2\2\2\21\u0126\3\2\2\2\23\u012a\3\2\2\2\25\u012e"+
"!\u014b\3\2\2\2#\u0154\3\2\2\2%\u015c\3\2\2\2\'\u0164\3\2\2\2)\u0171\3"+ "\3\2\2\2\27\u0131\3\2\2\2\31\u0135\3\2\2\2\33\u013d\3\2\2\2\35\u0140\3"+
"\2\2\2+\u0183\3\2\2\2-\u0187\3\2\2\2/\u018c\3\2\2\2\61\u0192\3\2\2\2\63"+ "\2\2\2\37\u0145\3\2\2\2!\u014d\3\2\2\2#\u0156\3\2\2\2%\u015e\3\2\2\2\'"+
"\u0197\3\2\2\2\65\u01a0\3\2\2\2\67\u01a9\3\2\2\29\u01b0\3\2\2\2;\u01bb"+ "\u0166\3\2\2\2)\u0173\3\2\2\2+\u0180\3\2\2\2-\u0192\3\2\2\2/\u0196\3\2"+
"\3\2\2\2=\u01c2\3\2\2\2?\u01ca\3\2\2\2A\u01d2\3\2\2\2C\u01d8\3\2\2\2E"+ "\2\2\61\u019b\3\2\2\2\63\u01a1\3\2\2\2\65\u01a6\3\2\2\2\67\u01af\3\2\2"+
"\u01de\3\2\2\2G\u01e5\3\2\2\2I\u01ea\3\2\2\2K\u01ef\3\2\2\2M\u01f9\3\2"+ "\29\u01b8\3\2\2\2;\u01bf\3\2\2\2=\u01ca\3\2\2\2?\u01d1\3\2\2\2A\u01d9"+
"\2\2O\u0202\3\2\2\2Q\u0208\3\2\2\2S\u020f\3\2\2\2U\u0214\3\2\2\2W\u021a"+ "\3\2\2\2C\u01e1\3\2\2\2E\u01e7\3\2\2\2G\u01ed\3\2\2\2I\u01f4\3\2\2\2K"+
"\3\2\2\2Y\u021d\3\2\2\2[\u0223\3\2\2\2]\u022c\3\2\2\2_\u022f\3\2\2\2a"+ "\u01f9\3\2\2\2M\u01fe\3\2\2\2O\u0208\3\2\2\2Q\u0211\3\2\2\2S\u0217\3\2"+
"\u0234\3\2\2\2c\u0239\3\2\2\2e\u023e\3\2\2\2g\u0243\3\2\2\2i\u0249\3\2"+ "\2\2U\u021e\3\2\2\2W\u0223\3\2\2\2Y\u0229\3\2\2\2[\u022c\3\2\2\2]\u0232"+
"\2\2k\u0250\3\2\2\2m\u0256\3\2\2\2o\u025d\3\2\2\2q\u0265\3\2\2\2s\u026b"+ "\3\2\2\2_\u023b\3\2\2\2a\u023e\3\2\2\2c\u0243\3\2\2\2e\u0248\3\2\2\2g"+
"\3\2\2\2u\u0272\3\2\2\2w\u027a\3\2\2\2y\u027e\3\2\2\2{\u0283\3\2\2\2}"+ "\u024d\3\2\2\2i\u0252\3\2\2\2k\u0258\3\2\2\2m\u025f\3\2\2\2o\u0265\3\2"+
"\u0289\3\2\2\2\177\u028c\3\2\2\2\u0081\u0296\3\2\2\2\u0083\u0299\3\2\2"+ "\2\2q\u026c\3\2\2\2s\u0274\3\2\2\2u\u027a\3\2\2\2w\u0281\3\2\2\2y\u0289"+
"\2\u0085\u029f\3\2\2\2\u0087\u02a5\3\2\2\2\u0089\u02ac\3\2\2\2\u008b\u02b5"+ "\3\2\2\2{\u028d\3\2\2\2}\u0292\3\2\2\2\177\u0298\3\2\2\2\u0081\u029b\3"+
"\3\2\2\2\u008d\u02ba\3\2\2\2\u008f\u02c0\3\2\2\2\u0091\u02c6\3\2\2\2\u0093"+ "\2\2\2\u0083\u02a5\3\2\2\2\u0085\u02a8\3\2\2\2\u0087\u02ae\3\2\2\2\u0089"+
"\u02cc\3\2\2\2\u0095\u02d4\3\2\2\2\u0097\u02db\3\2\2\2\u0099\u02e3\3\2"+ "\u02b4\3\2\2\2\u008b\u02bb\3\2\2\2\u008d\u02c4\3\2\2\2\u008f\u02c9\3\2"+
"\2\2\u009b\u02ea\3\2\2\2\u009d\u02ef\3\2\2\2\u009f\u02f3\3\2\2\2\u00a1"+ "\2\2\u0091\u02cf\3\2\2\2\u0093\u02d5\3\2\2\2\u0095\u02db\3\2\2\2\u0097"+
"\u02f9\3\2\2\2\u00a3\u0300\3\2\2\2\u00a5\u0305\3\2\2\2\u00a7\u030a\3\2"+ "\u02e3\3\2\2\2\u0099\u02ea\3\2\2\2\u009b\u02f2\3\2\2\2\u009d\u02f9\3\2"+
"\2\2\u00a9\u030d\3\2\2\2\u00ab\u0312\3\2\2\2\u00ad\u0318\3\2\2\2\u00af"+ "\2\2\u009f\u02fe\3\2\2\2\u00a1\u0302\3\2\2\2\u00a3\u0308\3\2\2\2\u00a5"+
"\u031e\3\2\2\2\u00b1\u0325\3\2\2\2\u00b3\u032b\3\2\2\2\u00b5\u0330\3\2"+ "\u030f\3\2\2\2\u00a7\u0314\3\2\2\2\u00a9\u0319\3\2\2\2\u00ab\u031c\3\2"+
"\2\2\u00b7\u0335\3\2\2\2\u00b9\u033b\3\2\2\2\u00bb\u0343\3\2\2\2\u00bd"+ "\2\2\u00ad\u0321\3\2\2\2\u00af\u0327\3\2\2\2\u00b1\u032d\3\2\2\2\u00b3"+
"\u0347\3\2\2\2\u00bf\u034e\3\2\2\2\u00c1\u0351\3\2\2\2\u00c3\u0354\3\2"+ "\u0334\3\2\2\2\u00b5\u033a\3\2\2\2\u00b7\u033f\3\2\2\2\u00b9\u0344\3\2"+
"\2\2\u00c5\u0358\3\2\2\2\u00c7\u035e\3\2\2\2\u00c9\u0360\3\2\2\2\u00cb"+ "\2\2\u00bb\u034a\3\2\2\2\u00bd\u0352\3\2\2\2\u00bf\u0356\3\2\2\2\u00c1"+
"\u0362\3\2\2\2\u00cd\u036a\3\2\2\2\u00cf\u036c\3\2\2\2\u00d1\u036e\3\2"+ "\u035d\3\2\2\2\u00c3\u0360\3\2\2\2\u00c5\u0363\3\2\2\2\u00c7\u0367\3\2"+
"\2\2\u00d3\u0371\3\2\2\2\u00d5\u0373\3\2\2\2\u00d7\u0376\3\2\2\2\u00d9"+ "\2\2\u00c9\u036d\3\2\2\2\u00cb\u036f\3\2\2\2\u00cd\u0371\3\2\2\2\u00cf"+
"\u0378\3\2\2\2\u00db\u037a\3\2\2\2\u00dd\u037c\3\2\2\2\u00df\u037e\3\2"+ "\u0379\3\2\2\2\u00d1\u037b\3\2\2\2\u00d3\u037d\3\2\2\2\u00d5\u0380\3\2"+
"\2\2\u00e1\u0380\3\2\2\2\u00e3\u0383\3\2\2\2\u00e5\u0386\3\2\2\2\u00e7"+ "\2\2\u00d7\u0382\3\2\2\2\u00d9\u0385\3\2\2\2\u00db\u0387\3\2\2\2\u00dd"+
"\u0388\3\2\2\2\u00e9\u038a\3\2\2\2\u00eb\u0396\3\2\2\2\u00ed\u03c4\3\2"+ "\u0389\3\2\2\2\u00df\u038b\3\2\2\2\u00e1\u038d\3\2\2\2\u00e3\u038f\3\2"+
"\2\2\u00ef\u03c8\3\2\2\2\u00f1\u03d2\3\2\2\2\u00f3\u03dd\3\2\2\2\u00f5"+ "\2\2\u00e5\u0392\3\2\2\2\u00e7\u0395\3\2\2\2\u00e9\u0397\3\2\2\2\u00eb"+
"\u03e1\3\2\2\2\u00f7\u03ec\3\2\2\2\u00f9\u03f7\3\2\2\2\u00fb\u0400\3\2"+ "\u0399\3\2\2\2\u00ed\u03a5\3\2\2\2\u00ef\u03d3\3\2\2\2\u00f1\u03d7\3\2"+
"\2\2\u00fd\u0402\3\2\2\2\u00ff\u0404\3\2\2\2\u0101\u0415\3\2\2\2\u0103"+ "\2\2\u00f3\u03e1\3\2\2\2\u00f5\u03ec\3\2\2\2\u00f7\u03f0\3\2\2\2\u00f9"+
"\u0425\3\2\2\2\u0105\u042b\3\2\2\2\u0107\u0108\7*\2\2\u0108\4\3\2\2\2"+ "\u03fb\3\2\2\2\u00fb\u0406\3\2\2\2\u00fd\u040f\3\2\2\2\u00ff\u0411\3\2"+
"\u0109\u010a\7+\2\2\u010a\6\3\2\2\2\u010b\u010c\7.\2\2\u010c\b\3\2\2\2"+ "\2\2\u0101\u0413\3\2\2\2\u0103\u0424\3\2\2\2\u0105\u0434\3\2\2\2\u0107"+
"\u010d\u010e\7<\2\2\u010e\n\3\2\2\2\u010f\u0110\7C\2\2\u0110\u0111\7N"+ "\u043a\3\2\2\2\u0109\u010a\7*\2\2\u010a\4\3\2\2\2\u010b\u010c\7+\2\2\u010c"+
"\2\2\u0111\u0112\7N\2\2\u0112\f\3\2\2\2\u0113\u0114\7C\2\2\u0114\u0115"+ "\6\3\2\2\2\u010d\u010e\7.\2\2\u010e\b\3\2\2\2\u010f\u0110\7<\2\2\u0110"+
"\7P\2\2\u0115\u0116\7C\2\2\u0116\u0117\7N\2\2\u0117\u0118\7[\2\2\u0118"+ "\n\3\2\2\2\u0111\u0112\7C\2\2\u0112\u0113\7N\2\2\u0113\u0114\7N\2\2\u0114"+
"\u0119\7\\\2\2\u0119\u011a\7G\2\2\u011a\16\3\2\2\2\u011b\u011c\7C\2\2"+ "\f\3\2\2\2\u0115\u0116\7C\2\2\u0116\u0117\7P\2\2\u0117\u0118\7C\2\2\u0118"+
"\u011c\u011d\7P\2\2\u011d\u011e\7C\2\2\u011e\u011f\7N\2\2\u011f\u0120"+ "\u0119\7N\2\2\u0119\u011a\7[\2\2\u011a\u011b\7\\\2\2\u011b\u011c\7G\2"+
"\7[\2\2\u0120\u0121\7\\\2\2\u0121\u0122\7G\2\2\u0122\u0123\7F\2\2\u0123"+ "\2\u011c\16\3\2\2\2\u011d\u011e\7C\2\2\u011e\u011f\7P\2\2\u011f\u0120"+
"\20\3\2\2\2\u0124\u0125\7C\2\2\u0125\u0126\7P\2\2\u0126\u0127\7F\2\2\u0127"+ "\7C\2\2\u0120\u0121\7N\2\2\u0121\u0122\7[\2\2\u0122\u0123\7\\\2\2\u0123"+
"\22\3\2\2\2\u0128\u0129\7C\2\2\u0129\u012a\7P\2\2\u012a\u012b\7[\2\2\u012b"+ "\u0124\7G\2\2\u0124\u0125\7F\2\2\u0125\20\3\2\2\2\u0126\u0127\7C\2\2\u0127"+
"\24\3\2\2\2\u012c\u012d\7C\2\2\u012d\u012e\7U\2\2\u012e\26\3\2\2\2\u012f"+ "\u0128\7P\2\2\u0128\u0129\7F\2\2\u0129\22\3\2\2\2\u012a\u012b\7C\2\2\u012b"+
"\u0130\7C\2\2\u0130\u0131\7U\2\2\u0131\u0132\7E\2\2\u0132\30\3\2\2\2\u0133"+ "\u012c\7P\2\2\u012c\u012d\7[\2\2\u012d\24\3\2\2\2\u012e\u012f\7C\2\2\u012f"+
"\u0134\7D\2\2\u0134\u0135\7G\2\2\u0135\u0136\7V\2\2\u0136\u0137\7Y\2\2"+ "\u0130\7U\2\2\u0130\26\3\2\2\2\u0131\u0132\7C\2\2\u0132\u0133\7U\2\2\u0133"+
"\u0137\u0138\7G\2\2\u0138\u0139\7G\2\2\u0139\u013a\7P\2\2\u013a\32\3\2"+ "\u0134\7E\2\2\u0134\30\3\2\2\2\u0135\u0136\7D\2\2\u0136\u0137\7G\2\2\u0137"+
"\2\2\u013b\u013c\7D\2\2\u013c\u013d\7[\2\2\u013d\34\3\2\2\2\u013e\u013f"+ "\u0138\7V\2\2\u0138\u0139\7Y\2\2\u0139\u013a\7G\2\2\u013a\u013b\7G\2\2"+
"\7E\2\2\u013f\u0140\7C\2\2\u0140\u0141\7U\2\2\u0141\u0142\7V\2\2\u0142"+ "\u013b\u013c\7P\2\2\u013c\32\3\2\2\2\u013d\u013e\7D\2\2\u013e\u013f\7"+
"\36\3\2\2\2\u0143\u0144\7E\2\2\u0144\u0145\7C\2\2\u0145\u0146\7V\2\2\u0146"+ "[\2\2\u013f\34\3\2\2\2\u0140\u0141\7E\2\2\u0141\u0142\7C\2\2\u0142\u0143"+
"\u0147\7C\2\2\u0147\u0148\7N\2\2\u0148\u0149\7Q\2\2\u0149\u014a\7I\2\2"+ "\7U\2\2\u0143\u0144\7V\2\2\u0144\36\3\2\2\2\u0145\u0146\7E\2\2\u0146\u0147"+
"\u014a \3\2\2\2\u014b\u014c\7E\2\2\u014c\u014d\7C\2\2\u014d\u014e\7V\2"+ "\7C\2\2\u0147\u0148\7V\2\2\u0148\u0149\7C\2\2\u0149\u014a\7N\2\2\u014a"+
"\2\u014e\u014f\7C\2\2\u014f\u0150\7N\2\2\u0150\u0151\7Q\2\2\u0151\u0152"+ "\u014b\7Q\2\2\u014b\u014c\7I\2\2\u014c \3\2\2\2\u014d\u014e\7E\2\2\u014e"+
"\7I\2\2\u0152\u0153\7U\2\2\u0153\"\3\2\2\2\u0154\u0155\7E\2\2\u0155\u0156"+ "\u014f\7C\2\2\u014f\u0150\7V\2\2\u0150\u0151\7C\2\2\u0151\u0152\7N\2\2"+
"\7Q\2\2\u0156\u0157\7N\2\2\u0157\u0158\7W\2\2\u0158\u0159\7O\2\2\u0159"+ "\u0152\u0153\7Q\2\2\u0153\u0154\7I\2\2\u0154\u0155\7U\2\2\u0155\"\3\2"+
"\u015a\7P\2\2\u015a\u015b\7U\2\2\u015b$\3\2\2\2\u015c\u015d\7E\2\2\u015d"+ "\2\2\u0156\u0157\7E\2\2\u0157\u0158\7Q\2\2\u0158\u0159\7N\2\2\u0159\u015a"+
"\u015e\7Q\2\2\u015e\u015f\7P\2\2\u015f\u0160\7X\2\2\u0160\u0161\7G\2\2"+ "\7W\2\2\u015a\u015b\7O\2\2\u015b\u015c\7P\2\2\u015c\u015d\7U\2\2\u015d"+
"\u0161\u0162\7T\2\2\u0162\u0163\7V\2\2\u0163&\3\2\2\2\u0164\u0165\7E\2"+ "$\3\2\2\2\u015e\u015f\7E\2\2\u015f\u0160\7Q\2\2\u0160\u0161\7P\2\2\u0161"+
"\2\u0165\u0166\7W\2\2\u0166\u0167\7T\2\2\u0167\u0168\7T\2\2\u0168\u0169"+ "\u0162\7X\2\2\u0162\u0163\7G\2\2\u0163\u0164\7T\2\2\u0164\u0165\7V\2\2"+
"\7G\2\2\u0169\u016a\7P\2\2\u016a\u016b\7V\2\2\u016b\u016c\7a\2\2\u016c"+ "\u0165&\3\2\2\2\u0166\u0167\7E\2\2\u0167\u0168\7W\2\2\u0168\u0169\7T\2"+
"\u016d\7F\2\2\u016d\u016e\7C\2\2\u016e\u016f\7V\2\2\u016f\u0170\7G\2\2"+ "\2\u0169\u016a\7T\2\2\u016a\u016b\7G\2\2\u016b\u016c\7P\2\2\u016c\u016d"+
"\u0170(\3\2\2\2\u0171\u0172\7E\2\2\u0172\u0173\7W\2\2\u0173\u0174\7T\2"+ "\7V\2\2\u016d\u016e\7a\2\2\u016e\u016f\7F\2\2\u016f\u0170\7C\2\2\u0170"+
"\2\u0174\u0175\7T\2\2\u0175\u0176\7G\2\2\u0176\u0177\7P\2\2\u0177\u0178"+ "\u0171\7V\2\2\u0171\u0172\7G\2\2\u0172(\3\2\2\2\u0173\u0174\7E\2\2\u0174"+
"\7V\2\2\u0178\u0179\7a\2\2\u0179\u017a\7V\2\2\u017a\u017b\7K\2\2\u017b"+ "\u0175\7W\2\2\u0175\u0176\7T\2\2\u0176\u0177\7T\2\2\u0177\u0178\7G\2\2"+
"\u017c\7O\2\2\u017c\u017d\7G\2\2\u017d\u017e\7U\2\2\u017e\u017f\7V\2\2"+ "\u0178\u0179\7P\2\2\u0179\u017a\7V\2\2\u017a\u017b\7a\2\2\u017b\u017c"+
"\u017f\u0180\7C\2\2\u0180\u0181\7O\2\2\u0181\u0182\7R\2\2\u0182*\3\2\2"+ "\7V\2\2\u017c\u017d\7K\2\2\u017d\u017e\7O\2\2\u017e\u017f\7G\2\2\u017f"+
"\2\u0183\u0184\7F\2\2\u0184\u0185\7C\2\2\u0185\u0186\7[\2\2\u0186,\3\2"+ "*\3\2\2\2\u0180\u0181\7E\2\2\u0181\u0182\7W\2\2\u0182\u0183\7T\2\2\u0183"+
"\2\2\u0187\u0188\7F\2\2\u0188\u0189\7C\2\2\u0189\u018a\7[\2\2\u018a\u018b"+ "\u0184\7T\2\2\u0184\u0185\7G\2\2\u0185\u0186\7P\2\2\u0186\u0187\7V\2\2"+
"\7U\2\2\u018b.\3\2\2\2\u018c\u018d\7F\2\2\u018d\u018e\7G\2\2\u018e\u018f"+ "\u0187\u0188\7a\2\2\u0188\u0189\7V\2\2\u0189\u018a\7K\2\2\u018a\u018b"+
"\7D\2\2\u018f\u0190\7W\2\2\u0190\u0191\7I\2\2\u0191\60\3\2\2\2\u0192\u0193"+ "\7O\2\2\u018b\u018c\7G\2\2\u018c\u018d\7U\2\2\u018d\u018e\7V\2\2\u018e"+
"\7F\2\2\u0193\u0194\7G\2\2\u0194\u0195\7U\2\2\u0195\u0196\7E\2\2\u0196"+ "\u018f\7C\2\2\u018f\u0190\7O\2\2\u0190\u0191\7R\2\2\u0191,\3\2\2\2\u0192"+
"\62\3\2\2\2\u0197\u0198\7F\2\2\u0198\u0199\7G\2\2\u0199\u019a\7U\2\2\u019a"+ "\u0193\7F\2\2\u0193\u0194\7C\2\2\u0194\u0195\7[\2\2\u0195.\3\2\2\2\u0196"+
"\u019b\7E\2\2\u019b\u019c\7T\2\2\u019c\u019d\7K\2\2\u019d\u019e\7D\2\2"+ "\u0197\7F\2\2\u0197\u0198\7C\2\2\u0198\u0199\7[\2\2\u0199\u019a\7U\2\2"+
"\u019e\u019f\7G\2\2\u019f\64\3\2\2\2\u01a0\u01a1\7F\2\2\u01a1\u01a2\7"+ "\u019a\60\3\2\2\2\u019b\u019c\7F\2\2\u019c\u019d\7G\2\2\u019d\u019e\7"+
"K\2\2\u01a2\u01a3\7U\2\2\u01a3\u01a4\7V\2\2\u01a4\u01a5\7K\2\2\u01a5\u01a6"+ "D\2\2\u019e\u019f\7W\2\2\u019f\u01a0\7I\2\2\u01a0\62\3\2\2\2\u01a1\u01a2"+
"\7P\2\2\u01a6\u01a7\7E\2\2\u01a7\u01a8\7V\2\2\u01a8\66\3\2\2\2\u01a9\u01aa"+ "\7F\2\2\u01a2\u01a3\7G\2\2\u01a3\u01a4\7U\2\2\u01a4\u01a5\7E\2\2\u01a5"+
"\7G\2\2\u01aa\u01ab\7U\2\2\u01ab\u01ac\7E\2\2\u01ac\u01ad\7C\2\2\u01ad"+ "\64\3\2\2\2\u01a6\u01a7\7F\2\2\u01a7\u01a8\7G\2\2\u01a8\u01a9\7U\2\2\u01a9"+
"\u01ae\7R\2\2\u01ae\u01af\7G\2\2\u01af8\3\2\2\2\u01b0\u01b1\7G\2\2\u01b1"+ "\u01aa\7E\2\2\u01aa\u01ab\7T\2\2\u01ab\u01ac\7K\2\2\u01ac\u01ad\7D\2\2"+
"\u01b2\7Z\2\2\u01b2\u01b3\7G\2\2\u01b3\u01b4\7E\2\2\u01b4\u01b5\7W\2\2"+ "\u01ad\u01ae\7G\2\2\u01ae\66\3\2\2\2\u01af\u01b0\7F\2\2\u01b0\u01b1\7"+
"\u01b5\u01b6\7V\2\2\u01b6\u01b7\7C\2\2\u01b7\u01b8\7D\2\2\u01b8\u01b9"+ "K\2\2\u01b1\u01b2\7U\2\2\u01b2\u01b3\7V\2\2\u01b3\u01b4\7K\2\2\u01b4\u01b5"+
"\7N\2\2\u01b9\u01ba\7G\2\2\u01ba:\3\2\2\2\u01bb\u01bc\7G\2\2\u01bc\u01bd"+ "\7P\2\2\u01b5\u01b6\7E\2\2\u01b6\u01b7\7V\2\2\u01b78\3\2\2\2\u01b8\u01b9"+
"\7Z\2\2\u01bd\u01be\7K\2\2\u01be\u01bf\7U\2\2\u01bf\u01c0\7V\2\2\u01c0"+ "\7G\2\2\u01b9\u01ba\7U\2\2\u01ba\u01bb\7E\2\2\u01bb\u01bc\7C\2\2\u01bc"+
"\u01c1\7U\2\2\u01c1<\3\2\2\2\u01c2\u01c3\7G\2\2\u01c3\u01c4\7Z\2\2\u01c4"+ "\u01bd\7R\2\2\u01bd\u01be\7G\2\2\u01be:\3\2\2\2\u01bf\u01c0\7G\2\2\u01c0"+
"\u01c5\7R\2\2\u01c5\u01c6\7N\2\2\u01c6\u01c7\7C\2\2\u01c7\u01c8\7K\2\2"+ "\u01c1\7Z\2\2\u01c1\u01c2\7G\2\2\u01c2\u01c3\7E\2\2\u01c3\u01c4\7W\2\2"+
"\u01c8\u01c9\7P\2\2\u01c9>\3\2\2\2\u01ca\u01cb\7G\2\2\u01cb\u01cc\7Z\2"+ "\u01c4\u01c5\7V\2\2\u01c5\u01c6\7C\2\2\u01c6\u01c7\7D\2\2\u01c7\u01c8"+
"\2\u01cc\u01cd\7V\2\2\u01cd\u01ce\7T\2\2\u01ce\u01cf\7C\2\2\u01cf\u01d0"+ "\7N\2\2\u01c8\u01c9\7G\2\2\u01c9<\3\2\2\2\u01ca\u01cb\7G\2\2\u01cb\u01cc"+
"\7E\2\2\u01d0\u01d1\7V\2\2\u01d1@\3\2\2\2\u01d2\u01d3\7H\2\2\u01d3\u01d4"+ "\7Z\2\2\u01cc\u01cd\7K\2\2\u01cd\u01ce\7U\2\2\u01ce\u01cf\7V\2\2\u01cf"+
"\7C\2\2\u01d4\u01d5\7N\2\2\u01d5\u01d6\7U\2\2\u01d6\u01d7\7G\2\2\u01d7"+ "\u01d0\7U\2\2\u01d0>\3\2\2\2\u01d1\u01d2\7G\2\2\u01d2\u01d3\7Z\2\2\u01d3"+
"B\3\2\2\2\u01d8\u01d9\7H\2\2\u01d9\u01da\7K\2\2\u01da\u01db\7T\2\2\u01db"+ "\u01d4\7R\2\2\u01d4\u01d5\7N\2\2\u01d5\u01d6\7C\2\2\u01d6\u01d7\7K\2\2"+
"\u01dc\7U\2\2\u01dc\u01dd\7V\2\2\u01ddD\3\2\2\2\u01de\u01df\7H\2\2\u01df"+ "\u01d7\u01d8\7P\2\2\u01d8@\3\2\2\2\u01d9\u01da\7G\2\2\u01da\u01db\7Z\2"+
"\u01e0\7Q\2\2\u01e0\u01e1\7T\2\2\u01e1\u01e2\7O\2\2\u01e2\u01e3\7C\2\2"+ "\2\u01db\u01dc\7V\2\2\u01dc\u01dd\7T\2\2\u01dd\u01de\7C\2\2\u01de\u01df"+
"\u01e3\u01e4\7V\2\2\u01e4F\3\2\2\2\u01e5\u01e6\7H\2\2\u01e6\u01e7\7T\2"+ "\7E\2\2\u01df\u01e0\7V\2\2\u01e0B\3\2\2\2\u01e1\u01e2\7H\2\2\u01e2\u01e3"+
"\2\u01e7\u01e8\7Q\2\2\u01e8\u01e9\7O\2\2\u01e9H\3\2\2\2\u01ea\u01eb\7"+ "\7C\2\2\u01e3\u01e4\7N\2\2\u01e4\u01e5\7U\2\2\u01e5\u01e6\7G\2\2\u01e6"+
"H\2\2\u01eb\u01ec\7W\2\2\u01ec\u01ed\7N\2\2\u01ed\u01ee\7N\2\2\u01eeJ"+ "D\3\2\2\2\u01e7\u01e8\7H\2\2\u01e8\u01e9\7K\2\2\u01e9\u01ea\7T\2\2\u01ea"+
"\3\2\2\2\u01ef\u01f0\7H\2\2\u01f0\u01f1\7W\2\2\u01f1\u01f2\7P\2\2\u01f2"+ "\u01eb\7U\2\2\u01eb\u01ec\7V\2\2\u01ecF\3\2\2\2\u01ed\u01ee\7H\2\2\u01ee"+
"\u01f3\7E\2\2\u01f3\u01f4\7V\2\2\u01f4\u01f5\7K\2\2\u01f5\u01f6\7Q\2\2"+ "\u01ef\7Q\2\2\u01ef\u01f0\7T\2\2\u01f0\u01f1\7O\2\2\u01f1\u01f2\7C\2\2"+
"\u01f6\u01f7\7P\2\2\u01f7\u01f8\7U\2\2\u01f8L\3\2\2\2\u01f9\u01fa\7I\2"+ "\u01f2\u01f3\7V\2\2\u01f3H\3\2\2\2\u01f4\u01f5\7H\2\2\u01f5\u01f6\7T\2"+
"\2\u01fa\u01fb\7T\2\2\u01fb\u01fc\7C\2\2\u01fc\u01fd\7R\2\2\u01fd\u01fe"+ "\2\u01f6\u01f7\7Q\2\2\u01f7\u01f8\7O\2\2\u01f8J\3\2\2\2\u01f9\u01fa\7"+
"\7J\2\2\u01fe\u01ff\7X\2\2\u01ff\u0200\7K\2\2\u0200\u0201\7\\\2\2\u0201"+ "H\2\2\u01fa\u01fb\7W\2\2\u01fb\u01fc\7N\2\2\u01fc\u01fd\7N\2\2\u01fdL"+
"N\3\2\2\2\u0202\u0203\7I\2\2\u0203\u0204\7T\2\2\u0204\u0205\7Q\2\2\u0205"+ "\3\2\2\2\u01fe\u01ff\7H\2\2\u01ff\u0200\7W\2\2\u0200\u0201\7P\2\2\u0201"+
"\u0206\7W\2\2\u0206\u0207\7R\2\2\u0207P\3\2\2\2\u0208\u0209\7J\2\2\u0209"+ "\u0202\7E\2\2\u0202\u0203\7V\2\2\u0203\u0204\7K\2\2\u0204\u0205\7Q\2\2"+
"\u020a\7C\2\2\u020a\u020b\7X\2\2\u020b\u020c\7K\2\2\u020c\u020d\7P\2\2"+ "\u0205\u0206\7P\2\2\u0206\u0207\7U\2\2\u0207N\3\2\2\2\u0208\u0209\7I\2"+
"\u020d\u020e\7I\2\2\u020eR\3\2\2\2\u020f\u0210\7J\2\2\u0210\u0211\7Q\2"+ "\2\u0209\u020a\7T\2\2\u020a\u020b\7C\2\2\u020b\u020c\7R\2\2\u020c\u020d"+
"\2\u0211\u0212\7W\2\2\u0212\u0213\7T\2\2\u0213T\3\2\2\2\u0214\u0215\7"+ "\7J\2\2\u020d\u020e\7X\2\2\u020e\u020f\7K\2\2\u020f\u0210\7\\\2\2\u0210"+
"J\2\2\u0215\u0216\7Q\2\2\u0216\u0217\7W\2\2\u0217\u0218\7T\2\2\u0218\u0219"+ "P\3\2\2\2\u0211\u0212\7I\2\2\u0212\u0213\7T\2\2\u0213\u0214\7Q\2\2\u0214"+
"\7U\2\2\u0219V\3\2\2\2\u021a\u021b\7K\2\2\u021b\u021c\7P\2\2\u021cX\3"+ "\u0215\7W\2\2\u0215\u0216\7R\2\2\u0216R\3\2\2\2\u0217\u0218\7J\2\2\u0218"+
"\2\2\2\u021d\u021e\7K\2\2\u021e\u021f\7P\2\2\u021f\u0220\7P\2\2\u0220"+ "\u0219\7C\2\2\u0219\u021a\7X\2\2\u021a\u021b\7K\2\2\u021b\u021c\7P\2\2"+
"\u0221\7G\2\2\u0221\u0222\7T\2\2\u0222Z\3\2\2\2\u0223\u0224\7K\2\2\u0224"+ "\u021c\u021d\7I\2\2\u021dT\3\2\2\2\u021e\u021f\7J\2\2\u021f\u0220\7Q\2"+
"\u0225\7P\2\2\u0225\u0226\7V\2\2\u0226\u0227\7G\2\2\u0227\u0228\7T\2\2"+ "\2\u0220\u0221\7W\2\2\u0221\u0222\7T\2\2\u0222V\3\2\2\2\u0223\u0224\7"+
"\u0228\u0229\7X\2\2\u0229\u022a\7C\2\2\u022a\u022b\7N\2\2\u022b\\\3\2"+ "J\2\2\u0224\u0225\7Q\2\2\u0225\u0226\7W\2\2\u0226\u0227\7T\2\2\u0227\u0228"+
"\2\2\u022c\u022d\7K\2\2\u022d\u022e\7U\2\2\u022e^\3\2\2\2\u022f\u0230"+ "\7U\2\2\u0228X\3\2\2\2\u0229\u022a\7K\2\2\u022a\u022b\7P\2\2\u022bZ\3"+
"\7L\2\2\u0230\u0231\7Q\2\2\u0231\u0232\7K\2\2\u0232\u0233\7P\2\2\u0233"+ "\2\2\2\u022c\u022d\7K\2\2\u022d\u022e\7P\2\2\u022e\u022f\7P\2\2\u022f"+
"`\3\2\2\2\u0234\u0235\7N\2\2\u0235\u0236\7C\2\2\u0236\u0237\7U\2\2\u0237"+ "\u0230\7G\2\2\u0230\u0231\7T\2\2\u0231\\\3\2\2\2\u0232\u0233\7K\2\2\u0233"+
"\u0238\7V\2\2\u0238b\3\2\2\2\u0239\u023a\7N\2\2\u023a\u023b\7G\2\2\u023b"+ "\u0234\7P\2\2\u0234\u0235\7V\2\2\u0235\u0236\7G\2\2\u0236\u0237\7T\2\2"+
"\u023c\7H\2\2\u023c\u023d\7V\2\2\u023dd\3\2\2\2\u023e\u023f\7N\2\2\u023f"+ "\u0237\u0238\7X\2\2\u0238\u0239\7C\2\2\u0239\u023a\7N\2\2\u023a^\3\2\2"+
"\u0240\7K\2\2\u0240\u0241\7M\2\2\u0241\u0242\7G\2\2\u0242f\3\2\2\2\u0243"+ "\2\u023b\u023c\7K\2\2\u023c\u023d\7U\2\2\u023d`\3\2\2\2\u023e\u023f\7"+
"\u0244\7N\2\2\u0244\u0245\7K\2\2\u0245\u0246\7O\2\2\u0246\u0247\7K\2\2"+ "L\2\2\u023f\u0240\7Q\2\2\u0240\u0241\7K\2\2\u0241\u0242\7P\2\2\u0242b"+
"\u0247\u0248\7V\2\2\u0248h\3\2\2\2\u0249\u024a\7O\2\2\u024a\u024b\7C\2"+ "\3\2\2\2\u0243\u0244\7N\2\2\u0244\u0245\7C\2\2\u0245\u0246\7U\2\2\u0246"+
"\2\u024b\u024c\7R\2\2\u024c\u024d\7R\2\2\u024d\u024e\7G\2\2\u024e\u024f"+ "\u0247\7V\2\2\u0247d\3\2\2\2\u0248\u0249\7N\2\2\u0249\u024a\7G\2\2\u024a"+
"\7F\2\2\u024fj\3\2\2\2\u0250\u0251\7O\2\2\u0251\u0252\7C\2\2\u0252\u0253"+ "\u024b\7H\2\2\u024b\u024c\7V\2\2\u024cf\3\2\2\2\u024d\u024e\7N\2\2\u024e"+
"\7V\2\2\u0253\u0254\7E\2\2\u0254\u0255\7J\2\2\u0255l\3\2\2\2\u0256\u0257"+ "\u024f\7K\2\2\u024f\u0250\7M\2\2\u0250\u0251\7G\2\2\u0251h\3\2\2\2\u0252"+
"\7O\2\2\u0257\u0258\7K\2\2\u0258\u0259\7P\2\2\u0259\u025a\7W\2\2\u025a"+ "\u0253\7N\2\2\u0253\u0254\7K\2\2\u0254\u0255\7O\2\2\u0255\u0256\7K\2\2"+
"\u025b\7V\2\2\u025b\u025c\7G\2\2\u025cn\3\2\2\2\u025d\u025e\7O\2\2\u025e"+ "\u0256\u0257\7V\2\2\u0257j\3\2\2\2\u0258\u0259\7O\2\2\u0259\u025a\7C\2"+
"\u025f\7K\2\2\u025f\u0260\7P\2\2\u0260\u0261\7W\2\2\u0261\u0262\7V\2\2"+ "\2\u025a\u025b\7R\2\2\u025b\u025c\7R\2\2\u025c\u025d\7G\2\2\u025d\u025e"+
"\u0262\u0263\7G\2\2\u0263\u0264\7U\2\2\u0264p\3\2\2\2\u0265\u0266\7O\2"+ "\7F\2\2\u025el\3\2\2\2\u025f\u0260\7O\2\2\u0260\u0261\7C\2\2\u0261\u0262"+
"\2\u0266\u0267\7Q\2\2\u0267\u0268\7P\2\2\u0268\u0269\7V\2\2\u0269\u026a"+ "\7V\2\2\u0262\u0263\7E\2\2\u0263\u0264\7J\2\2\u0264n\3\2\2\2\u0265\u0266"+
"\7J\2\2\u026ar\3\2\2\2\u026b\u026c\7O\2\2\u026c\u026d\7Q\2\2\u026d\u026e"+ "\7O\2\2\u0266\u0267\7K\2\2\u0267\u0268\7P\2\2\u0268\u0269\7W\2\2\u0269"+
"\7P\2\2\u026e\u026f\7V\2\2\u026f\u0270\7J\2\2\u0270\u0271\7U\2\2\u0271"+ "\u026a\7V\2\2\u026a\u026b\7G\2\2\u026bp\3\2\2\2\u026c\u026d\7O\2\2\u026d"+
"t\3\2\2\2\u0272\u0273\7P\2\2\u0273\u0274\7C\2\2\u0274\u0275\7V\2\2\u0275"+ "\u026e\7K\2\2\u026e\u026f\7P\2\2\u026f\u0270\7W\2\2\u0270\u0271\7V\2\2"+
"\u0276\7W\2\2\u0276\u0277\7T\2\2\u0277\u0278\7C\2\2\u0278\u0279\7N\2\2"+ "\u0271\u0272\7G\2\2\u0272\u0273\7U\2\2\u0273r\3\2\2\2\u0274\u0275\7O\2"+
"\u0279v\3\2\2\2\u027a\u027b\7P\2\2\u027b\u027c\7Q\2\2\u027c\u027d\7V\2"+ "\2\u0275\u0276\7Q\2\2\u0276\u0277\7P\2\2\u0277\u0278\7V\2\2\u0278\u0279"+
"\2\u027dx\3\2\2\2\u027e\u027f\7P\2\2\u027f\u0280\7W\2\2\u0280\u0281\7"+ "\7J\2\2\u0279t\3\2\2\2\u027a\u027b\7O\2\2\u027b\u027c\7Q\2\2\u027c\u027d"+
"N\2\2\u0281\u0282\7N\2\2\u0282z\3\2\2\2\u0283\u0284\7P\2\2\u0284\u0285"+ "\7P\2\2\u027d\u027e\7V\2\2\u027e\u027f\7J\2\2\u027f\u0280\7U\2\2\u0280"+
"\7W\2\2\u0285\u0286\7N\2\2\u0286\u0287\7N\2\2\u0287\u0288\7U\2\2\u0288"+ "v\3\2\2\2\u0281\u0282\7P\2\2\u0282\u0283\7C\2\2\u0283\u0284\7V\2\2\u0284"+
"|\3\2\2\2\u0289\u028a\7Q\2\2\u028a\u028b\7P\2\2\u028b~\3\2\2\2\u028c\u028d"+ "\u0285\7W\2\2\u0285\u0286\7T\2\2\u0286\u0287\7C\2\2\u0287\u0288\7N\2\2"+
"\7Q\2\2\u028d\u028e\7R\2\2\u028e\u028f\7V\2\2\u028f\u0290\7K\2\2\u0290"+ "\u0288x\3\2\2\2\u0289\u028a\7P\2\2\u028a\u028b\7Q\2\2\u028b\u028c\7V\2"+
"\u0291\7O\2\2\u0291\u0292\7K\2\2\u0292\u0293\7\\\2\2\u0293\u0294\7G\2"+ "\2\u028cz\3\2\2\2\u028d\u028e\7P\2\2\u028e\u028f\7W\2\2\u028f\u0290\7"+
"\2\u0294\u0295\7F\2\2\u0295\u0080\3\2\2\2\u0296\u0297\7Q\2\2\u0297\u0298"+ "N\2\2\u0290\u0291\7N\2\2\u0291|\3\2\2\2\u0292\u0293\7P\2\2\u0293\u0294"+
"\7T\2\2\u0298\u0082\3\2\2\2\u0299\u029a\7Q\2\2\u029a\u029b\7T\2\2\u029b"+ "\7W\2\2\u0294\u0295\7N\2\2\u0295\u0296\7N\2\2\u0296\u0297\7U\2\2\u0297"+
"\u029c\7F\2\2\u029c\u029d\7G\2\2\u029d\u029e\7T\2\2\u029e\u0084\3\2\2"+ "~\3\2\2\2\u0298\u0299\7Q\2\2\u0299\u029a\7P\2\2\u029a\u0080\3\2\2\2\u029b"+
"\2\u029f\u02a0\7Q\2\2\u02a0\u02a1\7W\2\2\u02a1\u02a2\7V\2\2\u02a2\u02a3"+ "\u029c\7Q\2\2\u029c\u029d\7R\2\2\u029d\u029e\7V\2\2\u029e\u029f\7K\2\2"+
"\7G\2\2\u02a3\u02a4\7T\2\2\u02a4\u0086\3\2\2\2\u02a5\u02a6\7R\2\2\u02a6"+ "\u029f\u02a0\7O\2\2\u02a0\u02a1\7K\2\2\u02a1\u02a2\7\\\2\2\u02a2\u02a3"+
"\u02a7\7C\2\2\u02a7\u02a8\7T\2\2\u02a8\u02a9\7U\2\2\u02a9\u02aa\7G\2\2"+ "\7G\2\2\u02a3\u02a4\7F\2\2\u02a4\u0082\3\2\2\2\u02a5\u02a6\7Q\2\2\u02a6"+
"\u02aa\u02ab\7F\2\2\u02ab\u0088\3\2\2\2\u02ac\u02ad\7R\2\2\u02ad\u02ae"+ "\u02a7\7T\2\2\u02a7\u0084\3\2\2\2\u02a8\u02a9\7Q\2\2\u02a9\u02aa\7T\2"+
"\7J\2\2\u02ae\u02af\7[\2\2\u02af\u02b0\7U\2\2\u02b0\u02b1\7K\2\2\u02b1"+ "\2\u02aa\u02ab\7F\2\2\u02ab\u02ac\7G\2\2\u02ac\u02ad\7T\2\2\u02ad\u0086"+
"\u02b2\7E\2\2\u02b2\u02b3\7C\2\2\u02b3\u02b4\7N\2\2\u02b4\u008a\3\2\2"+ "\3\2\2\2\u02ae\u02af\7Q\2\2\u02af\u02b0\7W\2\2\u02b0\u02b1\7V\2\2\u02b1"+
"\2\u02b5\u02b6\7R\2\2\u02b6\u02b7\7N\2\2\u02b7\u02b8\7C\2\2\u02b8\u02b9"+ "\u02b2\7G\2\2\u02b2\u02b3\7T\2\2\u02b3\u0088\3\2\2\2\u02b4\u02b5\7R\2"+
"\7P\2\2\u02b9\u008c\3\2\2\2\u02ba\u02bb\7T\2\2\u02bb\u02bc\7K\2\2\u02bc"+ "\2\u02b5\u02b6\7C\2\2\u02b6\u02b7\7T\2\2\u02b7\u02b8\7U\2\2\u02b8\u02b9"+
"\u02bd\7I\2\2\u02bd\u02be\7J\2\2\u02be\u02bf\7V\2\2\u02bf\u008e\3\2\2"+ "\7G\2\2\u02b9\u02ba\7F\2\2\u02ba\u008a\3\2\2\2\u02bb\u02bc\7R\2\2\u02bc"+
"\2\u02c0\u02c1\7T\2\2\u02c1\u02c2\7N\2\2\u02c2\u02c3\7K\2\2\u02c3\u02c4"+ "\u02bd\7J\2\2\u02bd\u02be\7[\2\2\u02be\u02bf\7U\2\2\u02bf\u02c0\7K\2\2"+
"\7M\2\2\u02c4\u02c5\7G\2\2\u02c5\u0090\3\2\2\2\u02c6\u02c7\7S\2\2\u02c7"+ "\u02c0\u02c1\7E\2\2\u02c1\u02c2\7C\2\2\u02c2\u02c3\7N\2\2\u02c3\u008c"+
"\u02c8\7W\2\2\u02c8\u02c9\7G\2\2\u02c9\u02ca\7T\2\2\u02ca\u02cb\7[\2\2"+ "\3\2\2\2\u02c4\u02c5\7R\2\2\u02c5\u02c6\7N\2\2\u02c6\u02c7\7C\2\2\u02c7"+
"\u02cb\u0092\3\2\2\2\u02cc\u02cd\7U\2\2\u02cd\u02ce\7E\2\2\u02ce\u02cf"+ "\u02c8\7P\2\2\u02c8\u008e\3\2\2\2\u02c9\u02ca\7T\2\2\u02ca\u02cb\7K\2"+
"\7J\2\2\u02cf\u02d0\7G\2\2\u02d0\u02d1\7O\2\2\u02d1\u02d2\7C\2\2\u02d2"+ "\2\u02cb\u02cc\7I\2\2\u02cc\u02cd\7J\2\2\u02cd\u02ce\7V\2\2\u02ce\u0090"+
"\u02d3\7U\2\2\u02d3\u0094\3\2\2\2\u02d4\u02d5\7U\2\2\u02d5\u02d6\7G\2"+ "\3\2\2\2\u02cf\u02d0\7T\2\2\u02d0\u02d1\7N\2\2\u02d1\u02d2\7K\2\2\u02d2"+
"\2\u02d6\u02d7\7E\2\2\u02d7\u02d8\7Q\2\2\u02d8\u02d9\7P\2\2\u02d9\u02da"+ "\u02d3\7M\2\2\u02d3\u02d4\7G\2\2\u02d4\u0092\3\2\2\2\u02d5\u02d6\7S\2"+
"\7F\2\2\u02da\u0096\3\2\2\2\u02db\u02dc\7U\2\2\u02dc\u02dd\7G\2\2\u02dd"+ "\2\u02d6\u02d7\7W\2\2\u02d7\u02d8\7G\2\2\u02d8\u02d9\7T\2\2\u02d9\u02da"+
"\u02de\7E\2\2\u02de\u02df\7Q\2\2\u02df\u02e0\7P\2\2\u02e0\u02e1\7F\2\2"+ "\7[\2\2\u02da\u0094\3\2\2\2\u02db\u02dc\7U\2\2\u02dc\u02dd\7E\2\2\u02dd"+
"\u02e1\u02e2\7U\2\2\u02e2\u0098\3\2\2\2\u02e3\u02e4\7U\2\2\u02e4\u02e5"+ "\u02de\7J\2\2\u02de\u02df\7G\2\2\u02df\u02e0\7O\2\2\u02e0\u02e1\7C\2\2"+
"\7G\2\2\u02e5\u02e6\7N\2\2\u02e6\u02e7\7G\2\2\u02e7\u02e8\7E\2\2\u02e8"+ "\u02e1\u02e2\7U\2\2\u02e2\u0096\3\2\2\2\u02e3\u02e4\7U\2\2\u02e4\u02e5"+
"\u02e9\7V\2\2\u02e9\u009a\3\2\2\2\u02ea\u02eb\7U\2\2\u02eb\u02ec\7J\2"+ "\7G\2\2\u02e5\u02e6\7E\2\2\u02e6\u02e7\7Q\2\2\u02e7\u02e8\7P\2\2\u02e8"+
"\2\u02ec\u02ed\7Q\2\2\u02ed\u02ee\7Y\2\2\u02ee\u009c\3\2\2\2\u02ef\u02f0"+ "\u02e9\7F\2\2\u02e9\u0098\3\2\2\2\u02ea\u02eb\7U\2\2\u02eb\u02ec\7G\2"+
"\7U\2\2\u02f0\u02f1\7[\2\2\u02f1\u02f2\7U\2\2\u02f2\u009e\3\2\2\2\u02f3"+ "\2\u02ec\u02ed\7E\2\2\u02ed\u02ee\7Q\2\2\u02ee\u02ef\7P\2\2\u02ef\u02f0"+
"\u02f4\7V\2\2\u02f4\u02f5\7C\2\2\u02f5\u02f6\7D\2\2\u02f6\u02f7\7N\2\2"+ "\7F\2\2\u02f0\u02f1\7U\2\2\u02f1\u009a\3\2\2\2\u02f2\u02f3\7U\2\2\u02f3"+
"\u02f7\u02f8\7G\2\2\u02f8\u00a0\3\2\2\2\u02f9\u02fa\7V\2\2\u02fa\u02fb"+ "\u02f4\7G\2\2\u02f4\u02f5\7N\2\2\u02f5\u02f6\7G\2\2\u02f6\u02f7\7E\2\2"+
"\7C\2\2\u02fb\u02fc\7D\2\2\u02fc\u02fd\7N\2\2\u02fd\u02fe\7G\2\2\u02fe"+ "\u02f7\u02f8\7V\2\2\u02f8\u009c\3\2\2\2\u02f9\u02fa\7U\2\2\u02fa\u02fb"+
"\u02ff\7U\2\2\u02ff\u00a2\3\2\2\2\u0300\u0301\7V\2\2\u0301\u0302\7G\2"+ "\7J\2\2\u02fb\u02fc\7Q\2\2\u02fc\u02fd\7Y\2\2\u02fd\u009e\3\2\2\2\u02fe"+
"\2\u0302\u0303\7Z\2\2\u0303\u0304\7V\2\2\u0304\u00a4\3\2\2\2\u0305\u0306"+ "\u02ff\7U\2\2\u02ff\u0300\7[\2\2\u0300\u0301\7U\2\2\u0301\u00a0\3\2\2"+
"\7V\2\2\u0306\u0307\7T\2\2\u0307\u0308\7W\2\2\u0308\u0309\7G\2\2\u0309"+ "\2\u0302\u0303\7V\2\2\u0303\u0304\7C\2\2\u0304\u0305\7D\2\2\u0305\u0306"+
"\u00a6\3\2\2\2\u030a\u030b\7V\2\2\u030b\u030c\7Q\2\2\u030c\u00a8\3\2\2"+ "\7N\2\2\u0306\u0307\7G\2\2\u0307\u00a2\3\2\2\2\u0308\u0309\7V\2\2\u0309"+
"\2\u030d\u030e\7V\2\2\u030e\u030f\7[\2\2\u030f\u0310\7R\2\2\u0310\u0311"+ "\u030a\7C\2\2\u030a\u030b\7D\2\2\u030b\u030c\7N\2\2\u030c\u030d\7G\2\2"+
"\7G\2\2\u0311\u00aa\3\2\2\2\u0312\u0313\7V\2\2\u0313\u0314\7[\2\2\u0314"+ "\u030d\u030e\7U\2\2\u030e\u00a4\3\2\2\2\u030f\u0310\7V\2\2\u0310\u0311"+
"\u0315\7R\2\2\u0315\u0316\7G\2\2\u0316\u0317\7U\2\2\u0317\u00ac\3\2\2"+ "\7G\2\2\u0311\u0312\7Z\2\2\u0312\u0313\7V\2\2\u0313\u00a6\3\2\2\2\u0314"+
"\2\u0318\u0319\7W\2\2\u0319\u031a\7U\2\2\u031a\u031b\7K\2\2\u031b\u031c"+ "\u0315\7V\2\2\u0315\u0316\7T\2\2\u0316\u0317\7W\2\2\u0317\u0318\7G\2\2"+
"\7P\2\2\u031c\u031d\7I\2\2\u031d\u00ae\3\2\2\2\u031e\u031f\7X\2\2\u031f"+ "\u0318\u00a8\3\2\2\2\u0319\u031a\7V\2\2\u031a\u031b\7Q\2\2\u031b\u00aa"+
"\u0320\7G\2\2\u0320\u0321\7T\2\2\u0321\u0322\7K\2\2\u0322\u0323\7H\2\2"+ "\3\2\2\2\u031c\u031d\7V\2\2\u031d\u031e\7[\2\2\u031e\u031f\7R\2\2\u031f"+
"\u0323\u0324\7[\2\2\u0324\u00b0\3\2\2\2\u0325\u0326\7Y\2\2\u0326\u0327"+ "\u0320\7G\2\2\u0320\u00ac\3\2\2\2\u0321\u0322\7V\2\2\u0322\u0323\7[\2"+
"\7J\2\2\u0327\u0328\7G\2\2\u0328\u0329\7T\2\2\u0329\u032a\7G\2\2\u032a"+ "\2\u0323\u0324\7R\2\2\u0324\u0325\7G\2\2\u0325\u0326\7U\2\2\u0326\u00ae"+
"\u00b2\3\2\2\2\u032b\u032c\7Y\2\2\u032c\u032d\7K\2\2\u032d\u032e\7V\2"+ "\3\2\2\2\u0327\u0328\7W\2\2\u0328\u0329\7U\2\2\u0329\u032a\7K\2\2\u032a"+
"\2\u032e\u032f\7J\2\2\u032f\u00b4\3\2\2\2\u0330\u0331\7[\2\2\u0331\u0332"+ "\u032b\7P\2\2\u032b\u032c\7I\2\2\u032c\u00b0\3\2\2\2\u032d\u032e\7X\2"+
"\7G\2\2\u0332\u0333\7C\2\2\u0333\u0334\7T\2\2\u0334\u00b6\3\2\2\2\u0335"+ "\2\u032e\u032f\7G\2\2\u032f\u0330\7T\2\2\u0330\u0331\7K\2\2\u0331\u0332"+
"\u0336\7[\2\2\u0336\u0337\7G\2\2\u0337\u0338\7C\2\2\u0338\u0339\7T\2\2"+ "\7H\2\2\u0332\u0333\7[\2\2\u0333\u00b2\3\2\2\2\u0334\u0335\7Y\2\2\u0335"+
"\u0339\u033a\7U\2\2\u033a\u00b8\3\2\2\2\u033b\u033c\7}\2\2\u033c\u033d"+ "\u0336\7J\2\2\u0336\u0337\7G\2\2\u0337\u0338\7T\2\2\u0338\u0339\7G\2\2"+
"\7G\2\2\u033d\u033e\7U\2\2\u033e\u033f\7E\2\2\u033f\u0340\7C\2\2\u0340"+ "\u0339\u00b4\3\2\2\2\u033a\u033b\7Y\2\2\u033b\u033c\7K\2\2\u033c\u033d"+
"\u0341\7R\2\2\u0341\u0342\7G\2\2\u0342\u00ba\3\2\2\2\u0343\u0344\7}\2"+ "\7V\2\2\u033d\u033e\7J\2\2\u033e\u00b6\3\2\2\2\u033f\u0340\7[\2\2\u0340"+
"\2\u0344\u0345\7H\2\2\u0345\u0346\7P\2\2\u0346\u00bc\3\2\2\2\u0347\u0348"+ "\u0341\7G\2\2\u0341\u0342\7C\2\2\u0342\u0343\7T\2\2\u0343\u00b8\3\2\2"+
"\7}\2\2\u0348\u0349\7N\2\2\u0349\u034a\7K\2\2\u034a\u034b\7O\2\2\u034b"+ "\2\u0344\u0345\7[\2\2\u0345\u0346\7G\2\2\u0346\u0347\7C\2\2\u0347\u0348"+
"\u034c\7K\2\2\u034c\u034d\7V\2\2\u034d\u00be\3\2\2\2\u034e\u034f\7}\2"+ "\7T\2\2\u0348\u0349\7U\2\2\u0349\u00ba\3\2\2\2\u034a\u034b\7}\2\2\u034b"+
"\2\u034f\u0350\7F\2\2\u0350\u00c0\3\2\2\2\u0351\u0352\7}\2\2\u0352\u0353"+ "\u034c\7G\2\2\u034c\u034d\7U\2\2\u034d\u034e\7E\2\2\u034e\u034f\7C\2\2"+
"\7V\2\2\u0353\u00c2\3\2\2\2\u0354\u0355\7}\2\2\u0355\u0356\7V\2\2\u0356"+ "\u034f\u0350\7R\2\2\u0350\u0351\7G\2\2\u0351\u00bc\3\2\2\2\u0352\u0353"+
"\u0357\7U\2\2\u0357\u00c4\3\2\2\2\u0358\u0359\7}\2\2\u0359\u035a\7I\2"+ "\7}\2\2\u0353\u0354\7H\2\2\u0354\u0355\7P\2\2\u0355\u00be\3\2\2\2\u0356"+
"\2\u035a\u035b\7W\2\2\u035b\u035c\7K\2\2\u035c\u035d\7F\2\2\u035d\u00c6"+ "\u0357\7}\2\2\u0357\u0358\7N\2\2\u0358\u0359\7K\2\2\u0359\u035a\7O\2\2"+
"\3\2\2\2\u035e\u035f\7\177\2\2\u035f\u00c8\3\2\2\2\u0360\u0361\7?\2\2"+ "\u035a\u035b\7K\2\2\u035b\u035c\7V\2\2\u035c\u00c0\3\2\2\2\u035d\u035e"+
"\u0361\u00ca\3\2\2\2\u0362\u0363\7>\2\2\u0363\u0364\7?\2\2\u0364\u0365"+ "\7}\2\2\u035e\u035f\7F\2\2\u035f\u00c2\3\2\2\2\u0360\u0361\7}\2\2\u0361"+
"\7@\2\2\u0365\u00cc\3\2\2\2\u0366\u0367\7>\2\2\u0367\u036b\7@\2\2\u0368"+ "\u0362\7V\2\2\u0362\u00c4\3\2\2\2\u0363\u0364\7}\2\2\u0364\u0365\7V\2"+
"\u0369\7#\2\2\u0369\u036b\7?\2\2\u036a\u0366\3\2\2\2\u036a\u0368\3\2\2"+ "\2\u0365\u0366\7U\2\2\u0366\u00c6\3\2\2\2\u0367\u0368\7}\2\2\u0368\u0369"+
"\2\u036b\u00ce\3\2\2\2\u036c\u036d\7>\2\2\u036d\u00d0\3\2\2\2\u036e\u036f"+ "\7I\2\2\u0369\u036a\7W\2\2\u036a\u036b\7K\2\2\u036b\u036c\7F\2\2\u036c"+
"\7>\2\2\u036f\u0370\7?\2\2\u0370\u00d2\3\2\2\2\u0371\u0372\7@\2\2\u0372"+ "\u00c8\3\2\2\2\u036d\u036e\7\177\2\2\u036e\u00ca\3\2\2\2\u036f\u0370\7"+
"\u00d4\3\2\2\2\u0373\u0374\7@\2\2\u0374\u0375\7?\2\2\u0375\u00d6\3\2\2"+ "?\2\2\u0370\u00cc\3\2\2\2\u0371\u0372\7>\2\2\u0372\u0373\7?\2\2\u0373"+
"\2\u0376\u0377\7-\2\2\u0377\u00d8\3\2\2\2\u0378\u0379\7/\2\2\u0379\u00da"+ "\u0374\7@\2\2\u0374\u00ce\3\2\2\2\u0375\u0376\7>\2\2\u0376\u037a\7@\2"+
"\3\2\2\2\u037a\u037b\7,\2\2\u037b\u00dc\3\2\2\2\u037c\u037d\7\61\2\2\u037d"+ "\2\u0377\u0378\7#\2\2\u0378\u037a\7?\2\2\u0379\u0375\3\2\2\2\u0379\u0377"+
"\u00de\3\2\2\2\u037e\u037f\7\'\2\2\u037f\u00e0\3\2\2\2\u0380\u0381\7<"+ "\3\2\2\2\u037a\u00d0\3\2\2\2\u037b\u037c\7>\2\2\u037c\u00d2\3\2\2\2\u037d"+
"\2\2\u0381\u0382\7<\2\2\u0382\u00e2\3\2\2\2\u0383\u0384\7~\2\2\u0384\u0385"+ "\u037e\7>\2\2\u037e\u037f\7?\2\2\u037f\u00d4\3\2\2\2\u0380\u0381\7@\2"+
"\7~\2\2\u0385\u00e4\3\2\2\2\u0386\u0387\7\60\2\2\u0387\u00e6\3\2\2\2\u0388"+ "\2\u0381\u00d6\3\2\2\2\u0382\u0383\7@\2\2\u0383\u0384\7?\2\2\u0384\u00d8"+
"\u0389\7A\2\2\u0389\u00e8\3\2\2\2\u038a\u0390\7)\2\2\u038b\u038f\n\2\2"+ "\3\2\2\2\u0385\u0386\7-\2\2\u0386\u00da\3\2\2\2\u0387\u0388\7/\2\2\u0388"+
"\2\u038c\u038d\7)\2\2\u038d\u038f\7)\2\2\u038e\u038b\3\2\2\2\u038e\u038c"+ "\u00dc\3\2\2\2\u0389\u038a\7,\2\2\u038a\u00de\3\2\2\2\u038b\u038c\7\61"+
"\3\2\2\2\u038f\u0392\3\2\2\2\u0390\u038e\3\2\2\2\u0390\u0391\3\2\2\2\u0391"+ "\2\2\u038c\u00e0\3\2\2\2\u038d\u038e\7\'\2\2\u038e\u00e2\3\2\2\2\u038f"+
"\u0393\3\2\2\2\u0392\u0390\3\2\2\2\u0393\u0394\7)\2\2\u0394\u00ea\3\2"+ "\u0390\7<\2\2\u0390\u0391\7<\2\2\u0391\u00e4\3\2\2\2\u0392\u0393\7~\2"+
"\2\2\u0395\u0397\5\u00fb~\2\u0396\u0395\3\2\2\2\u0397\u0398\3\2\2\2\u0398"+ "\2\u0393\u0394\7~\2\2\u0394\u00e6\3\2\2\2\u0395\u0396\7\60\2\2\u0396\u00e8"+
"\u0396\3\2\2\2\u0398\u0399\3\2\2\2\u0399\u00ec\3\2\2\2\u039a\u039c\5\u00fb"+ "\3\2\2\2\u0397\u0398\7A\2\2\u0398\u00ea\3\2\2\2\u0399\u039f\7)\2\2\u039a"+
"~\2\u039b\u039a\3\2\2\2\u039c\u039d\3\2\2\2\u039d\u039b\3\2\2\2\u039d"+ "\u039e\n\2\2\2\u039b\u039c\7)\2\2\u039c\u039e\7)\2\2\u039d\u039a\3\2\2"+
"\u039e\3\2\2\2\u039e\u039f\3\2\2\2\u039f\u03a3\5\u00e5s\2\u03a0\u03a2"+ "\2\u039d\u039b\3\2\2\2\u039e\u03a1\3\2\2\2\u039f\u039d\3\2\2\2\u039f\u03a0"+
"\5\u00fb~\2\u03a1\u03a0\3\2\2\2\u03a2\u03a5\3\2\2\2\u03a3\u03a1\3\2\2"+ "\3\2\2\2\u03a0\u03a2\3\2\2\2\u03a1\u039f\3\2\2\2\u03a2\u03a3\7)\2\2\u03a3"+
"\2\u03a3\u03a4\3\2\2\2\u03a4\u03c5\3\2\2\2\u03a5\u03a3\3\2\2\2\u03a6\u03a8"+ "\u00ec\3\2\2\2\u03a4\u03a6\5\u00fd\177\2\u03a5\u03a4\3\2\2\2\u03a6\u03a7"+
"\5\u00e5s\2\u03a7\u03a9\5\u00fb~\2\u03a8\u03a7\3\2\2\2\u03a9\u03aa\3\2"+ "\3\2\2\2\u03a7\u03a5\3\2\2\2\u03a7\u03a8\3\2\2\2\u03a8\u00ee\3\2\2\2\u03a9"+
"\2\2\u03aa\u03a8\3\2\2\2\u03aa\u03ab\3\2\2\2\u03ab\u03c5\3\2\2\2\u03ac"+ "\u03ab\5\u00fd\177\2\u03aa\u03a9\3\2\2\2\u03ab\u03ac\3\2\2\2\u03ac\u03aa"+
"\u03ae\5\u00fb~\2\u03ad\u03ac\3\2\2\2\u03ae\u03af\3\2\2\2\u03af\u03ad"+ "\3\2\2\2\u03ac\u03ad\3\2\2\2\u03ad\u03ae\3\2\2\2\u03ae\u03b2\5\u00e7t"+
"\3\2\2\2\u03af\u03b0\3\2\2\2\u03b0\u03b8\3\2\2\2\u03b1\u03b5\5\u00e5s"+ "\2\u03af\u03b1\5\u00fd\177\2\u03b0\u03af\3\2\2\2\u03b1\u03b4\3\2\2\2\u03b2"+
"\2\u03b2\u03b4\5\u00fb~\2\u03b3\u03b2\3\2\2\2\u03b4\u03b7\3\2\2\2\u03b5"+ "\u03b0\3\2\2\2\u03b2\u03b3\3\2\2\2\u03b3\u03d4\3\2\2\2\u03b4\u03b2\3\2"+
"\u03b3\3\2\2\2\u03b5\u03b6\3\2\2\2\u03b6\u03b9\3\2\2\2\u03b7\u03b5\3\2"+ "\2\2\u03b5\u03b7\5\u00e7t\2\u03b6\u03b8\5\u00fd\177\2\u03b7\u03b6\3\2"+
"\2\2\u03b8\u03b1\3\2\2\2\u03b8\u03b9\3\2\2\2\u03b9\u03ba\3\2\2\2\u03ba"+ "\2\2\u03b8\u03b9\3\2\2\2\u03b9\u03b7\3\2\2\2\u03b9\u03ba\3\2\2\2\u03ba"+
"\u03bb\5\u00f9}\2\u03bb\u03c5\3\2\2\2\u03bc\u03be\5\u00e5s\2\u03bd\u03bf"+ "\u03d4\3\2\2\2\u03bb\u03bd\5\u00fd\177\2\u03bc\u03bb\3\2\2\2\u03bd\u03be"+
"\5\u00fb~\2\u03be\u03bd\3\2\2\2\u03bf\u03c0\3\2\2\2\u03c0\u03be\3\2\2"+ "\3\2\2\2\u03be\u03bc\3\2\2\2\u03be\u03bf\3\2\2\2\u03bf\u03c7\3\2\2\2\u03c0"+
"\2\u03c0\u03c1\3\2\2\2\u03c1\u03c2\3\2\2\2\u03c2\u03c3\5\u00f9}\2\u03c3"+ "\u03c4\5\u00e7t\2\u03c1\u03c3\5\u00fd\177\2\u03c2\u03c1\3\2\2\2\u03c3"+
"\u03c5\3\2\2\2\u03c4\u039b\3\2\2\2\u03c4\u03a6\3\2\2\2\u03c4\u03ad\3\2"+ "\u03c6\3\2\2\2\u03c4\u03c2\3\2\2\2\u03c4\u03c5\3\2\2\2\u03c5\u03c8\3\2"+
"\2\2\u03c4\u03bc\3\2\2\2\u03c5\u00ee\3\2\2\2\u03c6\u03c9\5\u00fd\177\2"+ "\2\2\u03c6\u03c4\3\2\2\2\u03c7\u03c0\3\2\2\2\u03c7\u03c8\3\2\2\2\u03c8"+
"\u03c7\u03c9\7a\2\2\u03c8\u03c6\3\2\2\2\u03c8\u03c7\3\2\2\2\u03c9\u03cf"+ "\u03c9\3\2\2\2\u03c9\u03ca\5\u00fb~\2\u03ca\u03d4\3\2\2\2\u03cb\u03cd"+
"\3\2\2\2\u03ca\u03ce\5\u00fd\177\2\u03cb\u03ce\5\u00fb~\2\u03cc\u03ce"+ "\5\u00e7t\2\u03cc\u03ce\5\u00fd\177\2\u03cd\u03cc\3\2\2\2\u03ce\u03cf"+
"\t\3\2\2\u03cd\u03ca\3\2\2\2\u03cd\u03cb\3\2\2\2\u03cd\u03cc\3\2\2\2\u03ce"+ "\3\2\2\2\u03cf\u03cd\3\2\2\2\u03cf\u03d0\3\2\2\2\u03d0\u03d1\3\2\2\2\u03d1"+
"\u03d1\3\2\2\2\u03cf\u03cd\3\2\2\2\u03cf\u03d0\3\2\2\2\u03d0\u00f0\3\2"+ "\u03d2\5\u00fb~\2\u03d2\u03d4\3\2\2\2\u03d3\u03aa\3\2\2\2\u03d3\u03b5"+
"\2\2\u03d1\u03cf\3\2\2\2\u03d2\u03d6\5\u00fb~\2\u03d3\u03d7\5\u00fd\177"+ "\3\2\2\2\u03d3\u03bc\3\2\2\2\u03d3\u03cb\3\2\2\2\u03d4\u00f0\3\2\2\2\u03d5"+
"\2\u03d4\u03d7\5\u00fb~\2\u03d5\u03d7\t\3\2\2\u03d6\u03d3\3\2\2\2\u03d6"+ "\u03d8\5\u00ff\u0080\2\u03d6\u03d8\7a\2\2\u03d7\u03d5\3\2\2\2\u03d7\u03d6"+
"\u03d4\3\2\2\2\u03d6\u03d5\3\2\2\2\u03d7\u03d8\3\2\2\2\u03d8\u03d6\3\2"+ "\3\2\2\2\u03d8\u03de\3\2\2\2\u03d9\u03dd\5\u00ff\u0080\2\u03da\u03dd\5"+
"\2\2\u03d8\u03d9\3\2\2\2\u03d9\u00f2\3\2\2\2\u03da\u03de\5\u00fd\177\2"+ "\u00fd\177\2\u03db\u03dd\t\3\2\2\u03dc\u03d9\3\2\2\2\u03dc\u03da\3\2\2"+
"\u03db\u03de\5\u00fb~\2\u03dc\u03de\7a\2\2\u03dd\u03da\3\2\2\2\u03dd\u03db"+ "\2\u03dc\u03db\3\2\2\2\u03dd\u03e0\3\2\2\2\u03de\u03dc\3\2\2\2\u03de\u03df"+
"\3\2\2\2\u03dd\u03dc\3\2\2\2\u03de\u03df\3\2\2\2\u03df\u03dd\3\2\2\2\u03df"+ "\3\2\2\2\u03df\u00f2\3\2\2\2\u03e0\u03de\3\2\2\2\u03e1\u03e5\5\u00fd\177"+
"\u03e0\3\2\2\2\u03e0\u00f4\3\2\2\2\u03e1\u03e7\7$\2\2\u03e2\u03e6\n\4"+ "\2\u03e2\u03e6\5\u00ff\u0080\2\u03e3\u03e6\5\u00fd\177\2\u03e4\u03e6\t"+
"\2\2\u03e3\u03e4\7$\2\2\u03e4\u03e6\7$\2\2\u03e5\u03e2\3\2\2\2\u03e5\u03e3"+ "\3\2\2\u03e5\u03e2\3\2\2\2\u03e5\u03e3\3\2\2\2\u03e5\u03e4\3\2\2\2\u03e6"+
"\3\2\2\2\u03e6\u03e9\3\2\2\2\u03e7\u03e5\3\2\2\2\u03e7\u03e8\3\2\2\2\u03e8"+ "\u03e7\3\2\2\2\u03e7\u03e5\3\2\2\2\u03e7\u03e8\3\2\2\2\u03e8\u00f4\3\2"+
"\u03ea\3\2\2\2\u03e9\u03e7\3\2\2\2\u03ea\u03eb\7$\2\2\u03eb\u00f6\3\2"+ "\2\2\u03e9\u03ed\5\u00ff\u0080\2\u03ea\u03ed\5\u00fd\177\2\u03eb\u03ed"+
"\2\2\u03ec\u03f2\7b\2\2\u03ed\u03f1\n\5\2\2\u03ee\u03ef\7b\2\2\u03ef\u03f1"+ "\7a\2\2\u03ec\u03e9\3\2\2\2\u03ec\u03ea\3\2\2\2\u03ec\u03eb\3\2\2\2\u03ed"+
"\7b\2\2\u03f0\u03ed\3\2\2\2\u03f0\u03ee\3\2\2\2\u03f1\u03f4\3\2\2\2\u03f2"+ "\u03ee\3\2\2\2\u03ee\u03ec\3\2\2\2\u03ee\u03ef\3\2\2\2\u03ef\u00f6\3\2"+
"\u03f0\3\2\2\2\u03f2\u03f3\3\2\2\2\u03f3\u03f5\3\2\2\2\u03f4\u03f2\3\2"+ "\2\2\u03f0\u03f6\7$\2\2\u03f1\u03f5\n\4\2\2\u03f2\u03f3\7$\2\2\u03f3\u03f5"+
"\2\2\u03f5\u03f6\7b\2\2\u03f6\u00f8\3\2\2\2\u03f7\u03f9\7G\2\2\u03f8\u03fa"+ "\7$\2\2\u03f4\u03f1\3\2\2\2\u03f4\u03f2\3\2\2\2\u03f5\u03f8\3\2\2\2\u03f6"+
"\t\6\2\2\u03f9\u03f8\3\2\2\2\u03f9\u03fa\3\2\2\2\u03fa\u03fc\3\2\2\2\u03fb"+ "\u03f4\3\2\2\2\u03f6\u03f7\3\2\2\2\u03f7\u03f9\3\2\2\2\u03f8\u03f6\3\2"+
"\u03fd\5\u00fb~\2\u03fc\u03fb\3\2\2\2\u03fd\u03fe\3\2\2\2\u03fe\u03fc"+ "\2\2\u03f9\u03fa\7$\2\2\u03fa\u00f8\3\2\2\2\u03fb\u0401\7b\2\2\u03fc\u0400"+
"\3\2\2\2\u03fe\u03ff\3\2\2\2\u03ff\u00fa\3\2\2\2\u0400\u0401\t\7\2\2\u0401"+ "\n\5\2\2\u03fd\u03fe\7b\2\2\u03fe\u0400\7b\2\2\u03ff\u03fc\3\2\2\2\u03ff"+
"\u00fc\3\2\2\2\u0402\u0403\t\b\2\2\u0403\u00fe\3\2\2\2\u0404\u0405\7/"+ "\u03fd\3\2\2\2\u0400\u0403\3\2\2\2\u0401\u03ff\3\2\2\2\u0401\u0402\3\2"+
"\2\2\u0405\u0406\7/\2\2\u0406\u040a\3\2\2\2\u0407\u0409\n\t\2\2\u0408"+ "\2\2\u0402\u0404\3\2\2\2\u0403\u0401\3\2\2\2\u0404\u0405\7b\2\2\u0405"+
"\u0407\3\2\2\2\u0409\u040c\3\2\2\2\u040a\u0408\3\2\2\2\u040a\u040b\3\2"+ "\u00fa\3\2\2\2\u0406\u0408\7G\2\2\u0407\u0409\t\6\2\2\u0408\u0407\3\2"+
"\2\2\u040b\u040e\3\2\2\2\u040c\u040a\3\2\2\2\u040d\u040f\7\17\2\2\u040e"+ "\2\2\u0408\u0409\3\2\2\2\u0409\u040b\3\2\2\2\u040a\u040c\5\u00fd\177\2"+
"\u040d\3\2\2\2\u040e\u040f\3\2\2\2\u040f\u0411\3\2\2\2\u0410\u0412\7\f"+ "\u040b\u040a\3\2\2\2\u040c\u040d\3\2\2\2\u040d\u040b\3\2\2\2\u040d\u040e"+
"\2\2\u0411\u0410\3\2\2\2\u0411\u0412\3\2\2\2\u0412\u0413\3\2\2\2\u0413"+ "\3\2\2\2\u040e\u00fc\3\2\2\2\u040f\u0410\t\7\2\2\u0410\u00fe\3\2\2\2\u0411"+
"\u0414\b\u0080\2\2\u0414\u0100\3\2\2\2\u0415\u0416\7\61\2\2\u0416\u0417"+ "\u0412\t\b\2\2\u0412\u0100\3\2\2\2\u0413\u0414\7/\2\2\u0414\u0415\7/\2"+
"\7,\2\2\u0417\u041c\3\2\2\2\u0418\u041b\5\u0101\u0081\2\u0419\u041b\13"+ "\2\u0415\u0419\3\2\2\2\u0416\u0418\n\t\2\2\u0417\u0416\3\2\2\2\u0418\u041b"+
"\2\2\2\u041a\u0418\3\2\2\2\u041a\u0419\3\2\2\2\u041b\u041e\3\2\2\2\u041c"+ "\3\2\2\2\u0419\u0417\3\2\2\2\u0419\u041a\3\2\2\2\u041a\u041d\3\2\2\2\u041b"+
"\u041d\3\2\2\2\u041c\u041a\3\2\2\2\u041d\u041f\3\2\2\2\u041e\u041c\3\2"+ "\u0419\3\2\2\2\u041c\u041e\7\17\2\2\u041d\u041c\3\2\2\2\u041d\u041e\3"+
"\2\2\u041f\u0420\7,\2\2\u0420\u0421\7\61\2\2\u0421\u0422\3\2\2\2\u0422"+ "\2\2\2\u041e\u0420\3\2\2\2\u041f\u0421\7\f\2\2\u0420\u041f\3\2\2\2\u0420"+
"\u0423\b\u0081\2\2\u0423\u0102\3\2\2\2\u0424\u0426\t\n\2\2\u0425\u0424"+ "\u0421\3\2\2\2\u0421\u0422\3\2\2\2\u0422\u0423\b\u0081\2\2\u0423\u0102"+
"\3\2\2\2\u0426\u0427\3\2\2\2\u0427\u0425\3\2\2\2\u0427\u0428\3\2\2\2\u0428"+ "\3\2\2\2\u0424\u0425\7\61\2\2\u0425\u0426\7,\2\2\u0426\u042b\3\2\2\2\u0427"+
"\u0429\3\2\2\2\u0429\u042a\b\u0082\2\2\u042a\u0104\3\2\2\2\u042b\u042c"+ "\u042a\5\u0103\u0082\2\u0428\u042a\13\2\2\2\u0429\u0427\3\2\2\2\u0429"+
"\13\2\2\2\u042c\u0106\3\2\2\2\"\2\u036a\u038e\u0390\u0398\u039d\u03a3"+ "\u0428\3\2\2\2\u042a\u042d\3\2\2\2\u042b\u042c\3\2\2\2\u042b\u0429\3\2"+
"\u03aa\u03af\u03b5\u03b8\u03c0\u03c4\u03c8\u03cd\u03cf\u03d6\u03d8\u03dd"+ "\2\2\u042c\u042e\3\2\2\2\u042d\u042b\3\2\2\2\u042e\u042f\7,\2\2\u042f"+
"\u03df\u03e5\u03e7\u03f0\u03f2\u03f9\u03fe\u040a\u040e\u0411\u041a\u041c"+ "\u0430\7\61\2\2\u0430\u0431\3\2\2\2\u0431\u0432\b\u0082\2\2\u0432\u0104"+
"\u0427\3\2\3\2"; "\3\2\2\2\u0433\u0435\t\n\2\2\u0434\u0433\3\2\2\2\u0435\u0436\3\2\2\2\u0436"+
"\u0434\3\2\2\2\u0436\u0437\3\2\2\2\u0437\u0438\3\2\2\2\u0438\u0439\b\u0083"+
"\2\2\u0439\u0106\3\2\2\2\u043a\u043b\13\2\2\2\u043b\u0108\3\2\2\2\"\2"+
"\u0379\u039d\u039f\u03a7\u03ac\u03b2\u03b9\u03be\u03c4\u03c7\u03cf\u03d3"+
"\u03d7\u03dc\u03de\u03e5\u03e7\u03ec\u03ee\u03f4\u03f6\u03ff\u0401\u0408"+
"\u040d\u0419\u041d\u0420\u0429\u042b\u0436\3\2\3\2";
public static final ATN _ATN = public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray()); new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static { static {

View File

@ -114,7 +114,7 @@ public final class DateUtils {
} }
public static String toTimeString(OffsetTime time) { public static String toTimeString(OffsetTime time) {
return time.format(ISO_LOCAL_TIME); return StringUtils.toString(time);
} }
public static long minDayInterval(long l) { public static long minDayInterval(long l) {

View File

@ -0,0 +1,79 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.expression.function.scalar.datetime;
import org.elasticsearch.xpack.sql.TestUtils;
import org.elasticsearch.xpack.sql.expression.Expression;
import org.elasticsearch.xpack.sql.expression.Literal;
import org.elasticsearch.xpack.sql.session.Configuration;
import org.elasticsearch.xpack.sql.tree.AbstractNodeTestCase;
import java.time.OffsetTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.util.Objects;
import static org.elasticsearch.xpack.sql.tree.Source.EMPTY;
public class CurrentTimeTests extends AbstractNodeTestCase<CurrentTime, Expression> {
public static CurrentTime randomCurrentTime() {
return new CurrentTime(EMPTY, Literal.of(EMPTY, randomInt(10)), TestUtils.randomConfiguration());
}
@Override
protected CurrentTime randomInstance() {
return randomCurrentTime();
}
@Override
protected CurrentTime copy(CurrentTime instance) {
return new CurrentTime(instance.source(), instance.precision(), instance.configuration());
}
@Override
protected CurrentTime mutate(CurrentTime instance) {
ZonedDateTime now = instance.configuration().now();
ZoneId mutatedZoneId = randomValueOtherThanMany(o -> Objects.equals(now.getOffset(), o.getRules().getOffset(now.toInstant())),
() -> randomZone());
return new CurrentTime(instance.source(), Literal.of(EMPTY, randomInt(10)), TestUtils.randomConfiguration(mutatedZoneId));
}
@Override
public void testTransform() {
}
@Override
public void testReplaceChildren() {
}
public void testNanoPrecision() {
OffsetTime ot = OffsetTime.parse("12:34:45.123456789Z");
assertEquals(000_000_000, CurrentTime.nanoPrecision(ot, Literal.of(EMPTY, 0)).getNano());
assertEquals(100_000_000, CurrentTime.nanoPrecision(ot, Literal.of(EMPTY, 1)).getNano());
assertEquals(120_000_000, CurrentTime.nanoPrecision(ot, Literal.of(EMPTY, 2)).getNano());
assertEquals(123_000_000, CurrentTime.nanoPrecision(ot, Literal.of(EMPTY, 3)).getNano());
assertEquals(123_400_000, CurrentTime.nanoPrecision(ot, Literal.of(EMPTY, 4)).getNano());
assertEquals(123_450_000, CurrentTime.nanoPrecision(ot, Literal.of(EMPTY, 5)).getNano());
assertEquals(123_456_000, CurrentTime.nanoPrecision(ot, Literal.of(EMPTY, 6)).getNano());
assertEquals(123_456_700, CurrentTime.nanoPrecision(ot, Literal.of(EMPTY, 7)).getNano());
assertEquals(123_456_780, CurrentTime.nanoPrecision(ot, Literal.of(EMPTY, 8)).getNano());
assertEquals(123_456_789, CurrentTime.nanoPrecision(ot, Literal.of(EMPTY, 9)).getNano());
}
public void testDefaultPrecision() {
Configuration configuration = TestUtils.randomConfiguration();
// null precision means default precision
CurrentTime ct = new CurrentTime(EMPTY, null, configuration);
ZonedDateTime now = configuration.now();
assertEquals(now.get(ChronoField.MILLI_OF_SECOND), ((OffsetTime) ct.fold()).get(ChronoField.MILLI_OF_SECOND));
OffsetTime ot = OffsetTime.parse("12:34:56.123456789Z");
assertEquals(123_000_000, CurrentTime.nanoPrecision(ot, null).getNano());
}
}

View File

@ -382,22 +382,6 @@ public class ExpressionTests extends ESTestCase {
assertEquals("line 1:13: Does not recognize type [INVALID]", ex.getMessage()); assertEquals("line 1:13: Does not recognize type [INVALID]", ex.getMessage());
} }
public void testCurrentDate() {
Expression expr = parser.createExpression("CURRENT_DATE");
assertEquals(UnresolvedFunction.class, expr.getClass());
UnresolvedFunction ur = (UnresolvedFunction) expr;
assertEquals("CURRENT_DATE", ur.sourceText());
assertEquals(0, ur.children().size());
}
public void testCurrentDateWithParentheses() {
Expression expr = parser.createExpression("CURRENT_DATE( )");
assertEquals(UnresolvedFunction.class, expr.getClass());
UnresolvedFunction ur = (UnresolvedFunction) expr;
assertEquals("CURRENT_DATE( )", ur.sourceText());
assertEquals(0, ur.children().size());
}
public void testCurrentTimestamp() { public void testCurrentTimestamp() {
Expression expr = parser.createExpression("CURRENT_TIMESTAMP"); Expression expr = parser.createExpression("CURRENT_TIMESTAMP");
assertEquals(UnresolvedFunction.class, expr.getClass()); assertEquals(UnresolvedFunction.class, expr.getClass());
@ -422,6 +406,46 @@ public class ExpressionTests extends ESTestCase {
assertEquals("line 1:20: Precision needs to be between [0-9], received [100]", ex.getMessage()); assertEquals("line 1:20: Precision needs to be between [0-9], received [100]", ex.getMessage());
} }
public void testCurrentDate() {
Expression expr = parser.createExpression("CURRENT_DATE");
assertEquals(UnresolvedFunction.class, expr.getClass());
UnresolvedFunction ur = (UnresolvedFunction) expr;
assertEquals("CURRENT_DATE", ur.sourceText());
assertEquals(0, ur.children().size());
}
public void testCurrentDateWithParentheses() {
Expression expr = parser.createExpression("CURRENT_DATE( )");
assertEquals(UnresolvedFunction.class, expr.getClass());
UnresolvedFunction ur = (UnresolvedFunction) expr;
assertEquals("CURRENT_DATE( )", ur.sourceText());
assertEquals(0, ur.children().size());
}
public void testCurrentTime() {
Expression expr = parser.createExpression("CURRENT_TIME");
assertEquals(UnresolvedFunction.class, expr.getClass());
UnresolvedFunction ur = (UnresolvedFunction) expr;
assertEquals("CURRENT_TIME", ur.sourceText());
assertEquals(0, ur.children().size());
}
public void testCurrentTimePrecision() {
Expression expr = parser.createExpression("CURRENT_TIME(7)");
assertEquals(UnresolvedFunction.class, expr.getClass());
UnresolvedFunction ur = (UnresolvedFunction) expr;
assertEquals("CURRENT_TIME(7)", ur.sourceText());
assertEquals(1, ur.children().size());
Expression child = ur.children().get(0);
assertEquals(Literal.class, child.getClass());
assertEquals(Short.valueOf((short) 7), child.fold());
}
public void testCurrentTimeInvalidPrecision() {
ParsingException ex = expectThrows(ParsingException.class, () -> parser.createExpression("CURRENT_TIME(100)"));
assertEquals("line 1:15: Precision needs to be between [0-9], received [100]", ex.getMessage());
}
public void testSourceKeyword() { public void testSourceKeyword() {
String s = "CUrrENT_timestamP"; String s = "CUrrENT_timestamP";
Expression expr = parser.createExpression(s); Expression expr = parser.createExpression(s);

View File

@ -70,10 +70,10 @@ public class DataTypeConversionTests extends ESTestCase {
{ {
Conversion conversion = conversionFor(TIME, to); Conversion conversion = conversionFor(TIME, to);
assertNull(conversion.convert(null)); assertNull(conversion.convert(null));
assertEquals("00:02:03.456", conversion.convert(asTimeOnly(123456L))); assertEquals("00:02:03.456Z", conversion.convert(asTimeOnly(123456L)));
assertEquals("21:33:09.101", conversion.convert(asTimeOnly(123456789101L))); assertEquals("21:33:09.101Z", conversion.convert(asTimeOnly(123456789101L)));
assertEquals("23:57:56.544", conversion.convert(asTimeOnly(-123456L))); assertEquals("23:57:56.544Z", conversion.convert(asTimeOnly(-123456L)));
assertEquals("02:26:50.899", conversion.convert(asTimeOnly(-123456789101L))); assertEquals("02:26:50.899Z", conversion.convert(asTimeOnly(-123456789101L)));
} }
{ {
Conversion conversion = conversionFor(DATETIME, to); Conversion conversion = conversionFor(DATETIME, to);