diff --git a/docs/reference/sql/functions/conditional.asciidoc b/docs/reference/sql/functions/conditional.asciidoc index 135381a1c93..cf15504bbe3 100644 --- a/docs/reference/sql/functions/conditional.asciidoc +++ b/docs/reference/sql/functions/conditional.asciidoc @@ -1,10 +1,103 @@ [role="xpack"] [testenv="basic"] [[sql-functions-conditional]] -=== Conditional Functions +=== Conditional Functions And Expressions Functions that return one of their arguments by evaluating in an if-else manner. +[[sql-functions-conditional-case]] +==== `CASE` + +.Synopsis: +[source, sql] +---- +CASE WHEN condition THEN result + [WHEN ...] + [ELSE default_result] +END +---- + +*Input*: + +One or multiple _WHEN *condition* THEN *result_* clauses are used and the expression can optionally have +an _ELSE *default_result_* clause. Every *condition* should be a boolean expression. + +*Output*: one of the *result* expressions if the corresponding _WHEN *condition_* evaluates to `true` or +the *default_result* if all _WHEN *condition_* clauses evaluate to `false`. If the optional _ELSE *default_result_* +clause is missing and all _WHEN *condition_* clauses evaluate to `false` then `null` is returned. + +.Description + +The CASE expression is a generic conditional expression which simulates if/else statements of other programming languages +If the condition’s result is true, the value of the result expression that follows the condition will be the returned +the subsequent when clauses will be skipped and not processed. + + +["source","sql",subs="attributes,callouts,macros"] +---- +include-tagged::{sql-specs}/docs/docs.csv-spec[case] +---- + +["source","sql",subs="attributes,callouts,macros"] +---- +include-tagged::{sql-specs}/docs/docs.csv-spec[caseReturnNull] +---- + +["source","sql",subs="attributes,callouts,macros"] +---- +include-tagged::{sql-specs}/docs/docs.csv-spec[caseWithElse] +---- + + +As a variant, a case expression can be expressed with a syntax similar to *switch-case* of other programming languages: +[source, sql] +---- +CASE expression + WHEN value1 THEN result1 + [WHEN value2 THEN result2] + [WHEN ...] + [ELSE default_result] +END +---- + +In this case it's transformed internally to: +[source, sql] +---- +CASE WHEN expression = value1 THEN result1 + [WHEN expression = value2 THEN result2] + [WHEN ...] + [ELSE default_result] +END +---- + +["source","sql",subs="attributes,callouts,macros"] +---- +include-tagged::{sql-specs}/docs/docs.csv-spec[caseWithOperand] +---- + +["source","sql",subs="attributes,callouts,macros"] +---- +include-tagged::{sql-specs}/docs/docs.csv-spec[caseWithOperandAndElse] +---- + +[NOTE] +=============================== +All result expressions must be of compatible data types. More specifically all result +expressions should have a compatible data type with the 1st _non-null_ result expression. +E.g.: + +for the following query: + +[source, sql] +CASE WHEN a = 1 THEN null + WHEN a > 2 THEN 10 + WHEN a > 5 THEN 'foo' +END + +an error message would be returned, mentioning that *'foo'* is of data type *keyword*, +which does not match the expected data type *integer* (based on result *10*). +=============================== + [[sql-functions-conditional-coalesce]] ==== `COALESCE` diff --git a/docs/reference/sql/functions/index.asciidoc b/docs/reference/sql/functions/index.asciidoc index 1fa2778ee05..831a9d0a4e7 100644 --- a/docs/reference/sql/functions/index.asciidoc +++ b/docs/reference/sql/functions/index.asciidoc @@ -127,6 +127,7 @@ ** <> ** <> * <> +** <> ** <> ** <> ** <> diff --git a/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec index ea7cfb2c6a2..73ef70a96a4 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/command.csv-spec @@ -25,6 +25,7 @@ STDDEV_POP |AGGREGATE SUM_OF_SQUARES |AGGREGATE VAR_POP |AGGREGATE HISTOGRAM |GROUPING +CASE |CONDITIONAL COALESCE |CONDITIONAL GREATEST |CONDITIONAL IFNULL |CONDITIONAL diff --git a/x-pack/plugin/sql/qa/src/main/resources/conditionals.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/conditionals.csv-spec new file mode 100644 index 00000000000..2a4eaa501a1 --- /dev/null +++ b/x-pack/plugin/sql/qa/src/main/resources/conditionals.csv-spec @@ -0,0 +1,181 @@ +caseField +SELECT emp_no, CASE WHEN emp_no - 10000 < 10 THEN 'First 10' ELSE 'Second 10' END as "case" FROM test_emp WHERE emp_no >= 10005 +ORDER BY emp_no LIMIT 10; + + emp_no | case +--------+----------- +10005 | First 10 +10006 | First 10 +10007 | First 10 +10008 | First 10 +10009 | First 10 +10010 | Second 10 +10011 | Second 10 +10012 | Second 10 +10013 | Second 10 +10014 | Second 10 +; + +caseFieldWithoutAlias +SELECT emp_no, CASE WHEN emp_no - 10000 < 10 THEN emp_no ELSE emp_no % 10 END FROM test_emp WHERE emp_no >= 10005 +ORDER BY emp_no LIMIT 10; + + emp_no | CASE WHEN emp_no - 10000 < 10 THEN emp_no ELSE emp_no % 10 END +--------+---------------------------------------------------------------- +10005 | 10005 +10006 | 10006 +10007 | 10007 +10008 | 10008 +10009 | 10009 +10010 | 0 +10011 | 1 +10012 | 2 +10013 | 3 +10014 | 4 +; + +caseFieldNoElse +SELECT emp_no, CASE WHEN emp_no - 10000 < 10 THEN 'First 10' END as "case" FROM test_emp WHERE emp_no >= 10005 +ORDER BY emp_no LIMIT 10; + + emp_no | case +--------+---------- +10005 | First 10 +10006 | First 10 +10007 | First 10 +10008 | First 10 +10009 | First 10 +10010 | null +10011 | null +10012 | null +10013 | null +10014 | null +; + +caseWhere +SELECT last_name FROM test_emp WHERE CASE WHEN LENGTH(last_name) < 7 THEN 'ShortName' ELSE 'LongName' END = 'LongName' +ORDER BY emp_no LIMIT 10; + + last_name +----------- +Facello +Bamford +Koblick +Maliniak +Preusig +Zielinski +Kalloufi +Piveteau +Bridgland +Nooteboom +; + +caseWhereNoElse +SELECT last_name FROM test_emp WHERE CASE WHEN LENGTH(last_name) < 7 THEN 'ShortName' END IS NOT NULL +ORDER BY emp_no LIMIT 10; + + last_name +----------- +Simmel +Peac +Sluis +Terkki +Genin +Peha +Erde +Famili +Pettey +Heyers +; + +caseOrderBy +schema::last_name:s|languages:byte|emp_no:i +SELECT last_name, languages, emp_no FROM test_emp WHERE emp_no BETWEEN 10005 AND 10015 +ORDER BY CASE WHEN languages >= 3 THEN 'first' ELSE 'second' END, emp_no LIMIT 10; + + last_name | languages | emp_no +-----------+-----------+-------- + Preusig | 3 | 10006 + Zielinski | 4 | 10007 + Piveteau | 4 | 10010 + Sluis | 5 | 10011 + Bridgland | 5 | 10012 + Genin | 5 | 10014 + Nooteboom | 5 | 10015 + Maliniak | 1 | 10005 + Kalloufi | 2 | 10008 + Peac | 1 | 10009 +; + +caseOrderByNoElse +schema::last_name:s|languages:byte|emp_no:i +SELECT last_name, languages, emp_no FROM test_emp WHERE emp_no BETWEEN 10005 AND 10015 +ORDER BY CASE WHEN languages >= 3 THEN 'first' END NULLS FIRST, emp_no LIMIT 10; + + last_name | languages | emp_no +-----------+-----------+-------- +Maliniak | 1 | 10005 +Kalloufi | 2 | 10008 +Peac | 1 | 10009 +Terkki | 1 | 10013 +Preusig | 3 | 10006 +Zielinski | 4 | 10007 +Piveteau | 4 | 10010 +Sluis | 5 | 10011 +Bridgland | 5 | 10012 +Genin | 5 | 10014 +; + +caseGroupBy +schema::count:l|lang_skills:s +SELECT count(*) AS count, CASE WHEN NVL(languages, 0) <= 1 THEN 'zero-to-one' ELSE 'multilingual' END as lang_skills +FROM test_emp GROUP BY lang_skills ORDER BY lang_skills; + + count | lang_skills +-------+-------------- +75 | multilingual +25 | zero-to-one +; + +caseGroupByNoElse +schema::count:l|lang_skills:s +SELECT count(*) AS count, CASE WHEN NVL(languages, 0) <= 1 THEN 'zero-to-one' END as lang_skills +FROM test_emp GROUP BY lang_skills ORDER BY lang_skills; + + count | lang_skills +-------+------------- +75 | null +25 | zero-to-one +; + +caseGroupByComplexNested +schema::count:l|lang_skills:s +SELECT count(*) AS count, +CASE WHEN NVL(languages, 0) = 0 THEN 'zero' + WHEN languages = 1 THEN 'one' + WHEN languages = 2 THEN 'bilingual' + WHEN languages = 3 THEN 'trilingual' + ELSE 'multilingual' +END as lang_skills FROM test_emp GROUP BY lang_skills ORDER BY 2; + + count | lang_skills +-------+-------------- +19 | bilingual +39 | multilingual +15 | one +17 | trilingual +10 | zero +; + +caseGroupByAndHaving +schema::count:l|gender:s|languages:byte +SELECT count(*) AS count, gender, languages FROM test_emp +GROUP BY 2, 3 HAVING CASE WHEN count(*) > 10 THEN 'many' ELSE 'a few' END = 'many' +ORDER BY 2, 3; + +count | gender | languages +----------+-------------+--------------- +11 | M | 2 +11 | M | 3 +11 | M | 4 +; diff --git a/x-pack/plugin/sql/qa/src/main/resources/docs/docs.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/docs/docs.csv-spec index d7a60200a5e..bc7180de4d6 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/docs/docs.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/docs/docs.csv-spec @@ -202,6 +202,7 @@ STDDEV_POP |AGGREGATE SUM_OF_SQUARES |AGGREGATE VAR_POP |AGGREGATE HISTOGRAM |GROUPING +CASE |CONDITIONAL COALESCE |CONDITIONAL GREATEST |CONDITIONAL IFNULL |CONDITIONAL @@ -1987,10 +1988,81 @@ SELECT TRUNCATE(-345.153, 1) AS trimmed; /////////////////////////////// // -// Null handling +// Conditional // /////////////////////////////// +case +schema::case:s +// tag::case +SELECT CASE WHEN 1 > 2 THEN 'elastic' + WHEN 2 <= 3 THEN 'search' + END AS "case"; + + case +--------------- +search +// end::case +; + +caseReturnNull +schema::case:s +// tag::caseReturnNull +SELECT CASE WHEN 1 > 2 THEN 'elastic' + WHEN 2 > 10 THEN 'search' + END AS "case"; + + case +--------------- +null +// end::caseReturnNull +; + +caseWithElse +schema::case:s +// tag::caseWithElse +SELECT CASE WHEN 1 > 2 THEN 'elastic' + WHEN 2 > 10 THEN 'search' + ELSE 'default' + END AS "case"; + + case +--------------- +default +// end::caseWithElse +; + +caseWithOperand +schema::case:s +// tag::caseWithOperand +SELECT CASE 5 + WHEN 1 THEN 'elastic' + WHEN 2 THEN 'search' + WHEN 5 THEN 'elasticsearch' + END AS "case"; + + case +--------------- +elasticsearch +// end::caseWithOperand +; + +caseWithOperandAndElse +schema::case:s +// tag::caseWithOperandAndElse +SELECT CASE 5 + WHEN 1 THEN 'elastic' + WHEN 2 THEN 'search' + WHEN 3 THEN 'elasticsearch' + ELSE 'default' + END AS "case"; + + case +--------------- +default +// end::caseWithOperandAndElse +; + coalesceReturnNonNull // tag::coalesceReturnNonNull SELECT COALESCE(null, 'elastic', 'search') AS "coalesce"; diff --git a/x-pack/plugin/sql/qa/src/main/resources/null.csv-spec b/x-pack/plugin/sql/qa/src/main/resources/null.csv-spec index 610217b2333..df76250694e 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/null.csv-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/null.csv-spec @@ -38,45 +38,9 @@ c null ; -coalesceFirstNotNull -SELECT COALESCE(123) AS c; - -c -123 -; - - -coalesceWithFirstNullOfString -SELECT COALESCE(null, 'first') AS c; - -c:s -first -; - -coalesceWithFirstNullOfNumber -SELECT COALESCE(null, 123) AS c; - -c:i -123 -; - coalesceMixed SELECT COALESCE(null, 123, null, 321); COALESCE(null, 123, null, 321):i 123 ; - -coalesceMixedWithAlias -SELECT COALESCE(null, 123, null, 321) AS c; - -c:i -123 -; - -coalesceScalar -SELECT COALESCE(null, ABS(123) + 1) AS c; - -c:i -124 -; diff --git a/x-pack/plugin/sql/qa/src/main/resources/null.sql-spec b/x-pack/plugin/sql/qa/src/main/resources/null.sql-spec index d5a21262ca5..fce74d7569e 100644 --- a/x-pack/plugin/sql/qa/src/main/resources/null.sql-spec +++ b/x-pack/plugin/sql/qa/src/main/resources/null.sql-spec @@ -1,7 +1,22 @@ // -// Null expressions +// Null conditionals // +coalesceFirstNotNull +SELECT COALESCE(123) AS c; + +coalesceWithFirstNullOfString +SELECT COALESCE(null, 'first') AS c; + +coalesceWithFirstNullOfNumber +SELECT COALESCE(null, 123) AS c; + +coalesceMixedWithAlias +SELECT COALESCE(null, 123, null, 321) AS c; + +coalesceScalar +SELECT COALESCE(null, ABS(123) + 1) AS c; + coalesceField SELECT COALESCE(null, ABS(emp_no) + 1) AS c FROM test_emp ORDER BY emp_no LIMIT 5; diff --git a/x-pack/plugin/sql/src/main/antlr/SqlBase.g4 b/x-pack/plugin/sql/src/main/antlr/SqlBase.g4 index d814e9e60f2..f60610fc751 100644 --- a/x-pack/plugin/sql/src/main/antlr/SqlBase.g4 +++ b/x-pack/plugin/sql/src/main/antlr/SqlBase.g4 @@ -213,16 +213,17 @@ valueExpression ; primaryExpression - : castExpression #cast - | primaryExpression CAST_OP dataType #castOperatorExpression - | extractExpression #extract - | builtinDateTimeFunction #currentDateTimeFunction - | constant #constantDefault - | (qualifiedName DOT)? ASTERISK #star - | functionExpression #function - | '(' query ')' #subqueryExpression - | qualifiedName #dereference - | '(' expression ')' #parenthesizedExpression + : castExpression #cast + | primaryExpression CAST_OP dataType #castOperatorExpression + | extractExpression #extract + | builtinDateTimeFunction #currentDateTimeFunction + | constant #constantDefault + | (qualifiedName DOT)? ASTERISK #star + | functionExpression #function + | '(' query ')' #subqueryExpression + | qualifiedName #dereference + | '(' expression ')' #parenthesizedExpression + | CASE (operand=booleanExpression)? whenClause+ (ELSE elseClause=booleanExpression)? END #case ; builtinDateTimeFunction @@ -337,6 +338,10 @@ string | STRING ; +whenClause + : WHEN condition=expression THEN result=expression + ; + // http://developer.mimer.se/validator/sql-reserved-words.tml nonReserved : ANALYZE | ANALYZED @@ -368,6 +373,7 @@ AS: 'AS'; ASC: 'ASC'; BETWEEN: 'BETWEEN'; BY: 'BY'; +CASE: 'CASE'; CAST: 'CAST'; CATALOG: 'CATALOG'; CATALOGS: 'CATALOGS'; @@ -382,6 +388,8 @@ DEBUG: 'DEBUG'; DESC: 'DESC'; DESCRIBE: 'DESCRIBE'; DISTINCT: 'DISTINCT'; +ELSE: 'ELSE'; +END: 'END'; ESCAPE: 'ESCAPE'; EXECUTABLE: 'EXECUTABLE'; EXISTS: 'EXISTS'; @@ -437,12 +445,14 @@ SYS: 'SYS'; TABLE: 'TABLE'; TABLES: 'TABLES'; TEXT: 'TEXT'; +THEN: 'THEN'; TRUE: 'TRUE'; TO: 'TO'; TYPE: 'TYPE'; TYPES: 'TYPES'; USING: 'USING'; VERIFY: 'VERIFY'; +WHEN: 'WHEN'; WHERE: 'WHERE'; WITH: 'WITH'; YEAR: 'YEAR'; diff --git a/x-pack/plugin/sql/src/main/antlr/SqlBase.tokens b/x-pack/plugin/sql/src/main/antlr/SqlBase.tokens index 71b981ebfa3..0b24423bbee 100644 --- a/x-pack/plugin/sql/src/main/antlr/SqlBase.tokens +++ b/x-pack/plugin/sql/src/main/antlr/SqlBase.tokens @@ -11,122 +11,127 @@ AS=10 ASC=11 BETWEEN=12 BY=13 -CAST=14 -CATALOG=15 -CATALOGS=16 -COLUMNS=17 -CONVERT=18 -CURRENT_DATE=19 -CURRENT_TIME=20 -CURRENT_TIMESTAMP=21 -DAY=22 -DAYS=23 -DEBUG=24 -DESC=25 -DESCRIBE=26 -DISTINCT=27 -ESCAPE=28 -EXECUTABLE=29 -EXISTS=30 -EXPLAIN=31 -EXTRACT=32 -FALSE=33 -FIRST=34 -FORMAT=35 -FROM=36 -FULL=37 -FUNCTIONS=38 -GRAPHVIZ=39 -GROUP=40 -HAVING=41 -HOUR=42 -HOURS=43 -IN=44 -INNER=45 -INTERVAL=46 -IS=47 -JOIN=48 -LAST=49 -LEFT=50 -LIKE=51 -LIMIT=52 -MAPPED=53 -MATCH=54 -MINUTE=55 -MINUTES=56 -MONTH=57 -MONTHS=58 -NATURAL=59 -NOT=60 -NULL=61 -NULLS=62 -ON=63 -OPTIMIZED=64 -OR=65 -ORDER=66 -OUTER=67 -PARSED=68 -PHYSICAL=69 -PLAN=70 -RIGHT=71 -RLIKE=72 -QUERY=73 -SCHEMAS=74 -SECOND=75 -SECONDS=76 -SELECT=77 -SHOW=78 -SYS=79 -TABLE=80 -TABLES=81 -TEXT=82 -TRUE=83 -TO=84 -TYPE=85 -TYPES=86 -USING=87 -VERIFY=88 -WHERE=89 -WITH=90 -YEAR=91 -YEARS=92 -ESCAPE_ESC=93 -FUNCTION_ESC=94 -LIMIT_ESC=95 -DATE_ESC=96 -TIME_ESC=97 -TIMESTAMP_ESC=98 -GUID_ESC=99 -ESC_END=100 -EQ=101 -NULLEQ=102 -NEQ=103 -LT=104 -LTE=105 -GT=106 -GTE=107 -PLUS=108 -MINUS=109 -ASTERISK=110 -SLASH=111 -PERCENT=112 -CAST_OP=113 -CONCAT=114 -DOT=115 -PARAM=116 -STRING=117 -INTEGER_VALUE=118 -DECIMAL_VALUE=119 -IDENTIFIER=120 -DIGIT_IDENTIFIER=121 -TABLE_IDENTIFIER=122 -QUOTED_IDENTIFIER=123 -BACKQUOTED_IDENTIFIER=124 -SIMPLE_COMMENT=125 -BRACKETED_COMMENT=126 -WS=127 -UNRECOGNIZED=128 -DELIMITER=129 +CASE=14 +CAST=15 +CATALOG=16 +CATALOGS=17 +COLUMNS=18 +CONVERT=19 +CURRENT_DATE=20 +CURRENT_TIME=21 +CURRENT_TIMESTAMP=22 +DAY=23 +DAYS=24 +DEBUG=25 +DESC=26 +DESCRIBE=27 +DISTINCT=28 +ELSE=29 +END=30 +ESCAPE=31 +EXECUTABLE=32 +EXISTS=33 +EXPLAIN=34 +EXTRACT=35 +FALSE=36 +FIRST=37 +FORMAT=38 +FROM=39 +FULL=40 +FUNCTIONS=41 +GRAPHVIZ=42 +GROUP=43 +HAVING=44 +HOUR=45 +HOURS=46 +IN=47 +INNER=48 +INTERVAL=49 +IS=50 +JOIN=51 +LAST=52 +LEFT=53 +LIKE=54 +LIMIT=55 +MAPPED=56 +MATCH=57 +MINUTE=58 +MINUTES=59 +MONTH=60 +MONTHS=61 +NATURAL=62 +NOT=63 +NULL=64 +NULLS=65 +ON=66 +OPTIMIZED=67 +OR=68 +ORDER=69 +OUTER=70 +PARSED=71 +PHYSICAL=72 +PLAN=73 +RIGHT=74 +RLIKE=75 +QUERY=76 +SCHEMAS=77 +SECOND=78 +SECONDS=79 +SELECT=80 +SHOW=81 +SYS=82 +TABLE=83 +TABLES=84 +TEXT=85 +THEN=86 +TRUE=87 +TO=88 +TYPE=89 +TYPES=90 +USING=91 +VERIFY=92 +WHEN=93 +WHERE=94 +WITH=95 +YEAR=96 +YEARS=97 +ESCAPE_ESC=98 +FUNCTION_ESC=99 +LIMIT_ESC=100 +DATE_ESC=101 +TIME_ESC=102 +TIMESTAMP_ESC=103 +GUID_ESC=104 +ESC_END=105 +EQ=106 +NULLEQ=107 +NEQ=108 +LT=109 +LTE=110 +GT=111 +GTE=112 +PLUS=113 +MINUS=114 +ASTERISK=115 +SLASH=116 +PERCENT=117 +CAST_OP=118 +CONCAT=119 +DOT=120 +PARAM=121 +STRING=122 +INTEGER_VALUE=123 +DECIMAL_VALUE=124 +IDENTIFIER=125 +DIGIT_IDENTIFIER=126 +TABLE_IDENTIFIER=127 +QUOTED_IDENTIFIER=128 +BACKQUOTED_IDENTIFIER=129 +SIMPLE_COMMENT=130 +BRACKETED_COMMENT=131 +WS=132 +UNRECOGNIZED=133 +DELIMITER=134 '('=1 ')'=2 ','=3 @@ -140,105 +145,110 @@ DELIMITER=129 'ASC'=11 'BETWEEN'=12 'BY'=13 -'CAST'=14 -'CATALOG'=15 -'CATALOGS'=16 -'COLUMNS'=17 -'CONVERT'=18 -'CURRENT_DATE'=19 -'CURRENT_TIME'=20 -'CURRENT_TIMESTAMP'=21 -'DAY'=22 -'DAYS'=23 -'DEBUG'=24 -'DESC'=25 -'DESCRIBE'=26 -'DISTINCT'=27 -'ESCAPE'=28 -'EXECUTABLE'=29 -'EXISTS'=30 -'EXPLAIN'=31 -'EXTRACT'=32 -'FALSE'=33 -'FIRST'=34 -'FORMAT'=35 -'FROM'=36 -'FULL'=37 -'FUNCTIONS'=38 -'GRAPHVIZ'=39 -'GROUP'=40 -'HAVING'=41 -'HOUR'=42 -'HOURS'=43 -'IN'=44 -'INNER'=45 -'INTERVAL'=46 -'IS'=47 -'JOIN'=48 -'LAST'=49 -'LEFT'=50 -'LIKE'=51 -'LIMIT'=52 -'MAPPED'=53 -'MATCH'=54 -'MINUTE'=55 -'MINUTES'=56 -'MONTH'=57 -'MONTHS'=58 -'NATURAL'=59 -'NOT'=60 -'NULL'=61 -'NULLS'=62 -'ON'=63 -'OPTIMIZED'=64 -'OR'=65 -'ORDER'=66 -'OUTER'=67 -'PARSED'=68 -'PHYSICAL'=69 -'PLAN'=70 -'RIGHT'=71 -'RLIKE'=72 -'QUERY'=73 -'SCHEMAS'=74 -'SECOND'=75 -'SECONDS'=76 -'SELECT'=77 -'SHOW'=78 -'SYS'=79 -'TABLE'=80 -'TABLES'=81 -'TEXT'=82 -'TRUE'=83 -'TO'=84 -'TYPE'=85 -'TYPES'=86 -'USING'=87 -'VERIFY'=88 -'WHERE'=89 -'WITH'=90 -'YEAR'=91 -'YEARS'=92 -'{ESCAPE'=93 -'{FN'=94 -'{LIMIT'=95 -'{D'=96 -'{T'=97 -'{TS'=98 -'{GUID'=99 -'}'=100 -'='=101 -'<=>'=102 -'<'=104 -'<='=105 -'>'=106 -'>='=107 -'+'=108 -'-'=109 -'*'=110 -'/'=111 -'%'=112 -'::'=113 -'||'=114 -'.'=115 -'?'=116 +'CASE'=14 +'CAST'=15 +'CATALOG'=16 +'CATALOGS'=17 +'COLUMNS'=18 +'CONVERT'=19 +'CURRENT_DATE'=20 +'CURRENT_TIME'=21 +'CURRENT_TIMESTAMP'=22 +'DAY'=23 +'DAYS'=24 +'DEBUG'=25 +'DESC'=26 +'DESCRIBE'=27 +'DISTINCT'=28 +'ELSE'=29 +'END'=30 +'ESCAPE'=31 +'EXECUTABLE'=32 +'EXISTS'=33 +'EXPLAIN'=34 +'EXTRACT'=35 +'FALSE'=36 +'FIRST'=37 +'FORMAT'=38 +'FROM'=39 +'FULL'=40 +'FUNCTIONS'=41 +'GRAPHVIZ'=42 +'GROUP'=43 +'HAVING'=44 +'HOUR'=45 +'HOURS'=46 +'IN'=47 +'INNER'=48 +'INTERVAL'=49 +'IS'=50 +'JOIN'=51 +'LAST'=52 +'LEFT'=53 +'LIKE'=54 +'LIMIT'=55 +'MAPPED'=56 +'MATCH'=57 +'MINUTE'=58 +'MINUTES'=59 +'MONTH'=60 +'MONTHS'=61 +'NATURAL'=62 +'NOT'=63 +'NULL'=64 +'NULLS'=65 +'ON'=66 +'OPTIMIZED'=67 +'OR'=68 +'ORDER'=69 +'OUTER'=70 +'PARSED'=71 +'PHYSICAL'=72 +'PLAN'=73 +'RIGHT'=74 +'RLIKE'=75 +'QUERY'=76 +'SCHEMAS'=77 +'SECOND'=78 +'SECONDS'=79 +'SELECT'=80 +'SHOW'=81 +'SYS'=82 +'TABLE'=83 +'TABLES'=84 +'TEXT'=85 +'THEN'=86 +'TRUE'=87 +'TO'=88 +'TYPE'=89 +'TYPES'=90 +'USING'=91 +'VERIFY'=92 +'WHEN'=93 +'WHERE'=94 +'WITH'=95 +'YEAR'=96 +'YEARS'=97 +'{ESCAPE'=98 +'{FN'=99 +'{LIMIT'=100 +'{D'=101 +'{T'=102 +'{TS'=103 +'{GUID'=104 +'}'=105 +'='=106 +'<=>'=107 +'<'=109 +'<='=110 +'>'=111 +'>='=112 +'+'=113 +'-'=114 +'*'=115 +'/'=116 +'%'=117 +'::'=118 +'||'=119 +'.'=120 +'?'=121 diff --git a/x-pack/plugin/sql/src/main/antlr/SqlBaseLexer.tokens b/x-pack/plugin/sql/src/main/antlr/SqlBaseLexer.tokens index 44cff1d65ad..21925952a2e 100644 --- a/x-pack/plugin/sql/src/main/antlr/SqlBaseLexer.tokens +++ b/x-pack/plugin/sql/src/main/antlr/SqlBaseLexer.tokens @@ -11,121 +11,126 @@ AS=10 ASC=11 BETWEEN=12 BY=13 -CAST=14 -CATALOG=15 -CATALOGS=16 -COLUMNS=17 -CONVERT=18 -CURRENT_DATE=19 -CURRENT_TIME=20 -CURRENT_TIMESTAMP=21 -DAY=22 -DAYS=23 -DEBUG=24 -DESC=25 -DESCRIBE=26 -DISTINCT=27 -ESCAPE=28 -EXECUTABLE=29 -EXISTS=30 -EXPLAIN=31 -EXTRACT=32 -FALSE=33 -FIRST=34 -FORMAT=35 -FROM=36 -FULL=37 -FUNCTIONS=38 -GRAPHVIZ=39 -GROUP=40 -HAVING=41 -HOUR=42 -HOURS=43 -IN=44 -INNER=45 -INTERVAL=46 -IS=47 -JOIN=48 -LAST=49 -LEFT=50 -LIKE=51 -LIMIT=52 -MAPPED=53 -MATCH=54 -MINUTE=55 -MINUTES=56 -MONTH=57 -MONTHS=58 -NATURAL=59 -NOT=60 -NULL=61 -NULLS=62 -ON=63 -OPTIMIZED=64 -OR=65 -ORDER=66 -OUTER=67 -PARSED=68 -PHYSICAL=69 -PLAN=70 -RIGHT=71 -RLIKE=72 -QUERY=73 -SCHEMAS=74 -SECOND=75 -SECONDS=76 -SELECT=77 -SHOW=78 -SYS=79 -TABLE=80 -TABLES=81 -TEXT=82 -TRUE=83 -TO=84 -TYPE=85 -TYPES=86 -USING=87 -VERIFY=88 -WHERE=89 -WITH=90 -YEAR=91 -YEARS=92 -ESCAPE_ESC=93 -FUNCTION_ESC=94 -LIMIT_ESC=95 -DATE_ESC=96 -TIME_ESC=97 -TIMESTAMP_ESC=98 -GUID_ESC=99 -ESC_END=100 -EQ=101 -NULLEQ=102 -NEQ=103 -LT=104 -LTE=105 -GT=106 -GTE=107 -PLUS=108 -MINUS=109 -ASTERISK=110 -SLASH=111 -PERCENT=112 -CAST_OP=113 -CONCAT=114 -DOT=115 -PARAM=116 -STRING=117 -INTEGER_VALUE=118 -DECIMAL_VALUE=119 -IDENTIFIER=120 -DIGIT_IDENTIFIER=121 -TABLE_IDENTIFIER=122 -QUOTED_IDENTIFIER=123 -BACKQUOTED_IDENTIFIER=124 -SIMPLE_COMMENT=125 -BRACKETED_COMMENT=126 -WS=127 -UNRECOGNIZED=128 +CASE=14 +CAST=15 +CATALOG=16 +CATALOGS=17 +COLUMNS=18 +CONVERT=19 +CURRENT_DATE=20 +CURRENT_TIME=21 +CURRENT_TIMESTAMP=22 +DAY=23 +DAYS=24 +DEBUG=25 +DESC=26 +DESCRIBE=27 +DISTINCT=28 +ELSE=29 +END=30 +ESCAPE=31 +EXECUTABLE=32 +EXISTS=33 +EXPLAIN=34 +EXTRACT=35 +FALSE=36 +FIRST=37 +FORMAT=38 +FROM=39 +FULL=40 +FUNCTIONS=41 +GRAPHVIZ=42 +GROUP=43 +HAVING=44 +HOUR=45 +HOURS=46 +IN=47 +INNER=48 +INTERVAL=49 +IS=50 +JOIN=51 +LAST=52 +LEFT=53 +LIKE=54 +LIMIT=55 +MAPPED=56 +MATCH=57 +MINUTE=58 +MINUTES=59 +MONTH=60 +MONTHS=61 +NATURAL=62 +NOT=63 +NULL=64 +NULLS=65 +ON=66 +OPTIMIZED=67 +OR=68 +ORDER=69 +OUTER=70 +PARSED=71 +PHYSICAL=72 +PLAN=73 +RIGHT=74 +RLIKE=75 +QUERY=76 +SCHEMAS=77 +SECOND=78 +SECONDS=79 +SELECT=80 +SHOW=81 +SYS=82 +TABLE=83 +TABLES=84 +TEXT=85 +THEN=86 +TRUE=87 +TO=88 +TYPE=89 +TYPES=90 +USING=91 +VERIFY=92 +WHEN=93 +WHERE=94 +WITH=95 +YEAR=96 +YEARS=97 +ESCAPE_ESC=98 +FUNCTION_ESC=99 +LIMIT_ESC=100 +DATE_ESC=101 +TIME_ESC=102 +TIMESTAMP_ESC=103 +GUID_ESC=104 +ESC_END=105 +EQ=106 +NULLEQ=107 +NEQ=108 +LT=109 +LTE=110 +GT=111 +GTE=112 +PLUS=113 +MINUS=114 +ASTERISK=115 +SLASH=116 +PERCENT=117 +CAST_OP=118 +CONCAT=119 +DOT=120 +PARAM=121 +STRING=122 +INTEGER_VALUE=123 +DECIMAL_VALUE=124 +IDENTIFIER=125 +DIGIT_IDENTIFIER=126 +TABLE_IDENTIFIER=127 +QUOTED_IDENTIFIER=128 +BACKQUOTED_IDENTIFIER=129 +SIMPLE_COMMENT=130 +BRACKETED_COMMENT=131 +WS=132 +UNRECOGNIZED=133 '('=1 ')'=2 ','=3 @@ -139,105 +144,110 @@ UNRECOGNIZED=128 'ASC'=11 'BETWEEN'=12 'BY'=13 -'CAST'=14 -'CATALOG'=15 -'CATALOGS'=16 -'COLUMNS'=17 -'CONVERT'=18 -'CURRENT_DATE'=19 -'CURRENT_TIME'=20 -'CURRENT_TIMESTAMP'=21 -'DAY'=22 -'DAYS'=23 -'DEBUG'=24 -'DESC'=25 -'DESCRIBE'=26 -'DISTINCT'=27 -'ESCAPE'=28 -'EXECUTABLE'=29 -'EXISTS'=30 -'EXPLAIN'=31 -'EXTRACT'=32 -'FALSE'=33 -'FIRST'=34 -'FORMAT'=35 -'FROM'=36 -'FULL'=37 -'FUNCTIONS'=38 -'GRAPHVIZ'=39 -'GROUP'=40 -'HAVING'=41 -'HOUR'=42 -'HOURS'=43 -'IN'=44 -'INNER'=45 -'INTERVAL'=46 -'IS'=47 -'JOIN'=48 -'LAST'=49 -'LEFT'=50 -'LIKE'=51 -'LIMIT'=52 -'MAPPED'=53 -'MATCH'=54 -'MINUTE'=55 -'MINUTES'=56 -'MONTH'=57 -'MONTHS'=58 -'NATURAL'=59 -'NOT'=60 -'NULL'=61 -'NULLS'=62 -'ON'=63 -'OPTIMIZED'=64 -'OR'=65 -'ORDER'=66 -'OUTER'=67 -'PARSED'=68 -'PHYSICAL'=69 -'PLAN'=70 -'RIGHT'=71 -'RLIKE'=72 -'QUERY'=73 -'SCHEMAS'=74 -'SECOND'=75 -'SECONDS'=76 -'SELECT'=77 -'SHOW'=78 -'SYS'=79 -'TABLE'=80 -'TABLES'=81 -'TEXT'=82 -'TRUE'=83 -'TO'=84 -'TYPE'=85 -'TYPES'=86 -'USING'=87 -'VERIFY'=88 -'WHERE'=89 -'WITH'=90 -'YEAR'=91 -'YEARS'=92 -'{ESCAPE'=93 -'{FN'=94 -'{LIMIT'=95 -'{D'=96 -'{T'=97 -'{TS'=98 -'{GUID'=99 -'}'=100 -'='=101 -'<=>'=102 -'<'=104 -'<='=105 -'>'=106 -'>='=107 -'+'=108 -'-'=109 -'*'=110 -'/'=111 -'%'=112 -'::'=113 -'||'=114 -'.'=115 -'?'=116 +'CASE'=14 +'CAST'=15 +'CATALOG'=16 +'CATALOGS'=17 +'COLUMNS'=18 +'CONVERT'=19 +'CURRENT_DATE'=20 +'CURRENT_TIME'=21 +'CURRENT_TIMESTAMP'=22 +'DAY'=23 +'DAYS'=24 +'DEBUG'=25 +'DESC'=26 +'DESCRIBE'=27 +'DISTINCT'=28 +'ELSE'=29 +'END'=30 +'ESCAPE'=31 +'EXECUTABLE'=32 +'EXISTS'=33 +'EXPLAIN'=34 +'EXTRACT'=35 +'FALSE'=36 +'FIRST'=37 +'FORMAT'=38 +'FROM'=39 +'FULL'=40 +'FUNCTIONS'=41 +'GRAPHVIZ'=42 +'GROUP'=43 +'HAVING'=44 +'HOUR'=45 +'HOURS'=46 +'IN'=47 +'INNER'=48 +'INTERVAL'=49 +'IS'=50 +'JOIN'=51 +'LAST'=52 +'LEFT'=53 +'LIKE'=54 +'LIMIT'=55 +'MAPPED'=56 +'MATCH'=57 +'MINUTE'=58 +'MINUTES'=59 +'MONTH'=60 +'MONTHS'=61 +'NATURAL'=62 +'NOT'=63 +'NULL'=64 +'NULLS'=65 +'ON'=66 +'OPTIMIZED'=67 +'OR'=68 +'ORDER'=69 +'OUTER'=70 +'PARSED'=71 +'PHYSICAL'=72 +'PLAN'=73 +'RIGHT'=74 +'RLIKE'=75 +'QUERY'=76 +'SCHEMAS'=77 +'SECOND'=78 +'SECONDS'=79 +'SELECT'=80 +'SHOW'=81 +'SYS'=82 +'TABLE'=83 +'TABLES'=84 +'TEXT'=85 +'THEN'=86 +'TRUE'=87 +'TO'=88 +'TYPE'=89 +'TYPES'=90 +'USING'=91 +'VERIFY'=92 +'WHEN'=93 +'WHERE'=94 +'WITH'=95 +'YEAR'=96 +'YEARS'=97 +'{ESCAPE'=98 +'{FN'=99 +'{LIMIT'=100 +'{D'=101 +'{T'=102 +'{TS'=103 +'{GUID'=104 +'}'=105 +'='=106 +'<=>'=107 +'<'=109 +'<='=110 +'>'=111 +'>='=112 +'+'=113 +'-'=114 +'*'=115 +'/'=116 +'%'=117 +'::'=118 +'||'=119 +'.'=120 +'?'=121 diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java index a29b19e4128..883dd0e076a 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java @@ -94,6 +94,7 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.string.Right; import org.elasticsearch.xpack.sql.expression.function.scalar.string.Space; import org.elasticsearch.xpack.sql.expression.function.scalar.string.Substring; import org.elasticsearch.xpack.sql.expression.function.scalar.string.UCase; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.Case; import org.elasticsearch.xpack.sql.expression.predicate.conditional.Coalesce; import org.elasticsearch.xpack.sql.expression.predicate.conditional.Greatest; import org.elasticsearch.xpack.sql.expression.predicate.conditional.IfNull; @@ -169,7 +170,8 @@ public class FunctionRegistry { addToMap(def(Histogram.class, Histogram::new, "HISTOGRAM")); // Scalar functions // Conditional - addToMap(def(Coalesce.class, Coalesce::new, "COALESCE"), + addToMap(def(Case.class, Case::new, "CASE"), + def(Coalesce.class, Coalesce::new, "COALESCE"), def(IfNull.class, IfNull::new, "IFNULL", "ISNULL", "NVL"), def(NullIf.class, NullIf::new, "NULLIF"), def(Greatest.class, Greatest::new, "GREATEST"), diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Processors.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Processors.java index f5ceb266960..d14aeea507f 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Processors.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Processors.java @@ -28,6 +28,7 @@ import org.elasticsearch.xpack.sql.expression.gen.processor.ChainingProcessor; import org.elasticsearch.xpack.sql.expression.gen.processor.ConstantProcessor; import org.elasticsearch.xpack.sql.expression.gen.processor.HitExtractorProcessor; import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.CaseProcessor; import org.elasticsearch.xpack.sql.expression.predicate.conditional.ConditionalProcessor; import org.elasticsearch.xpack.sql.expression.predicate.conditional.NullIfProcessor; import org.elasticsearch.xpack.sql.expression.predicate.logical.BinaryLogicProcessor; @@ -62,7 +63,8 @@ public final class Processors { // logical entries.add(new Entry(Processor.class, BinaryLogicProcessor.NAME, BinaryLogicProcessor::new)); entries.add(new Entry(Processor.class, NotProcessor.NAME, NotProcessor::new)); - // null + // conditionals + entries.add(new Entry(Processor.class, CaseProcessor.NAME, CaseProcessor::new)); entries.add(new Entry(Processor.class, CheckNullProcessor.NAME, CheckNullProcessor::new)); entries.add(new Entry(Processor.class, ConditionalProcessor.NAME, ConditionalProcessor::new)); entries.add(new Entry(Processor.class, NullIfProcessor.NAME, NullIfProcessor::new)); diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java index 570154026b8..6a4ec411fe1 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/whitelist/InternalSqlScriptUtils.java @@ -26,6 +26,7 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.string.StringProce import org.elasticsearch.xpack.sql.expression.function.scalar.string.SubstringFunctionProcessor; import org.elasticsearch.xpack.sql.expression.literal.IntervalDayTime; import org.elasticsearch.xpack.sql.expression.literal.IntervalYearMonth; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.CaseProcessor; import org.elasticsearch.xpack.sql.expression.predicate.conditional.ConditionalProcessor.ConditionalOperation; import org.elasticsearch.xpack.sql.expression.predicate.conditional.NullIfProcessor; import org.elasticsearch.xpack.sql.expression.predicate.logical.BinaryLogicProcessor.BinaryLogicOperation; @@ -146,8 +147,12 @@ public final class InternalSqlScriptUtils { } // - // Null + // Conditional // + public static Object caseFunction(List expressions) { + return CaseProcessor.apply(expressions); + } + public static Object coalesce(List expressions) { return ConditionalOperation.COALESCE.apply(expressions); } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/Case.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/Case.java new file mode 100644 index 00000000000..772e75f414a --- /dev/null +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/Case.java @@ -0,0 +1,164 @@ +/* + * 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.predicate.conditional; + +import org.elasticsearch.xpack.sql.expression.Expression; +import org.elasticsearch.xpack.sql.expression.Expressions; +import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; +import org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder; +import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate; +import org.elasticsearch.xpack.sql.optimizer.Optimizer; +import org.elasticsearch.xpack.sql.tree.NodeInfo; +import org.elasticsearch.xpack.sql.tree.Source; +import org.elasticsearch.xpack.sql.type.DataType; +import org.elasticsearch.xpack.sql.type.DataTypeConversion; +import org.elasticsearch.xpack.sql.type.DataTypes; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringJoiner; + +import static org.elasticsearch.common.logging.LoggerMessageFormat.format; +import static org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder.paramsBuilder; + +/** + * Implements the CASE WHEN ... THEN ... ELSE ... END expression + */ +public class Case extends ConditionalFunction { + + private final List conditions; + private final Expression defaultElse; + + @SuppressWarnings("unchecked") + public Case(Source source, List expressions) { + super(source, expressions); + this.conditions = (List) (List) expressions.subList(0, expressions.size() - 1); + this.defaultElse = expressions.get(expressions.size() - 1); + } + + public List conditions() { + return conditions; + } + + public Expression defaultElse() { + return defaultElse; + } + + @Override + public DataType dataType() { + if (dataType == null) { + if (conditions.isEmpty()) { + dataType = defaultElse().dataType(); + } else { + dataType = DataType.NULL; + + for (IfConditional conditional : conditions) { + dataType = DataTypeConversion.commonType(dataType, conditional.dataType()); + } + } + } + return dataType; + } + + @Override + public Expression replaceChildren(List newChildren) { + return new Case(source(), newChildren); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, Case::new, children()); + } + + @Override + protected TypeResolution resolveType() { + DataType expectedResultDataType = null; + for (IfConditional ifConditional : conditions) { + if (DataTypes.isNull(ifConditional.result().dataType()) == false) { + expectedResultDataType = ifConditional.result().dataType(); + break; + } + } + if (expectedResultDataType == null) { + expectedResultDataType = defaultElse().dataType(); + } + + for (IfConditional conditional : conditions) { + if (conditional.condition().dataType() != DataType.BOOLEAN) { + return new TypeResolution(format(null, "condition of [{}] must be [boolean], found value [{}] type [{}]", + conditional.sourceText(), + Expressions.name(conditional.condition()), + conditional.condition().dataType().typeName)); + } + if (DataTypes.areTypesCompatible(expectedResultDataType, conditional.dataType()) == false) { + return new TypeResolution(format(null, "result of [{}] must be [{}], found value [{}] type [{}]", + conditional.sourceText(), + expectedResultDataType.typeName, + Expressions.name(conditional.result()), + conditional.dataType().typeName)); + } + } + + if (DataTypes.areTypesCompatible(expectedResultDataType, defaultElse.dataType()) == false) { + return new TypeResolution(format(null, "ELSE clause of [{}] must be [{}], found value [{}] type [{}]", + defaultElse.sourceText(), + expectedResultDataType.typeName, + Expressions.name(defaultElse), + defaultElse.dataType().typeName)); + } + + return TypeResolution.TYPE_RESOLVED; + } + + /** + * All foldable conditions that fold to FALSE should have + * been removed by the {@link Optimizer}. + */ + @Override + public boolean foldable() { + return (conditions.isEmpty() && defaultElse.foldable()) || + (conditions.size() == 1 && conditions.get(0).condition().foldable() && conditions.get(0).result().foldable()); + } + + @Override + public Object fold() { + if (conditions.isEmpty() == false && conditions.get(0).condition().fold() == Boolean.TRUE) { + return conditions.get(0).result().fold(); + } + return defaultElse.fold(); + } + + @Override + protected Pipe makePipe() { + List pipes = new ArrayList<>(conditions.size() + 1); + for (IfConditional ifConditional : conditions) { + pipes.add(Expressions.pipe(ifConditional.condition())); + pipes.add(Expressions.pipe(ifConditional.result())); + } + pipes.add(Expressions.pipe(defaultElse)); + return new CasePipe(source(), this, pipes); + } + + @Override + public ScriptTemplate asScript() { + List templates = new ArrayList<>(); + for (IfConditional ifConditional : conditions) { + templates.add(asScript(ifConditional.condition())); + templates.add(asScript(ifConditional.result())); + } + templates.add(asScript(defaultElse)); + + StringJoiner template = new StringJoiner(",", "{sql}.caseFunction([", "])"); + ParamsBuilder params = paramsBuilder(); + + for (ScriptTemplate scriptTemplate : templates) { + template.add(scriptTemplate.template()); + params.script(scriptTemplate.params()); + } + + return new ScriptTemplate(formatTemplate(template.toString()), params.build(), dataType()); + } +} diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/CasePipe.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/CasePipe.java new file mode 100644 index 00000000000..f3beb755c34 --- /dev/null +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/CasePipe.java @@ -0,0 +1,38 @@ +/* + * 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.predicate.conditional; + +import org.elasticsearch.xpack.sql.expression.Expression; +import org.elasticsearch.xpack.sql.expression.gen.pipeline.MultiPipe; +import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; +import org.elasticsearch.xpack.sql.tree.NodeInfo; +import org.elasticsearch.xpack.sql.tree.Source; + +import java.util.List; + +public class CasePipe extends MultiPipe { + + public CasePipe(Source source, Expression expression, List children) { + super(source, expression, children); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, CasePipe::new, expression(), children()); + } + + @Override + public Pipe replaceChildren(List newChildren) { + return new CasePipe(source(), expression(), newChildren); + } + + @Override + public Processor asProcessor(List procs) { + return new CaseProcessor(procs); + } +} diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/CaseProcessor.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/CaseProcessor.java new file mode 100644 index 00000000000..634e83401fe --- /dev/null +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/CaseProcessor.java @@ -0,0 +1,77 @@ +/* + * 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.predicate.conditional; + +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class CaseProcessor implements Processor { + + public static final String NAME = "case"; + + private final List processors; + + public CaseProcessor(List processors) { + this.processors = processors; + } + + public CaseProcessor(StreamInput in) throws IOException { + processors = in.readNamedWriteableList(Processor.class); + } + + @Override + public String getWriteableName() { + return NAME; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeNamedWriteableList(processors); + } + + @Override + public Object process(Object input) { + List objects = new ArrayList<>(processors.size()); + for (Processor processor : processors) { + objects.add(processor.process(input)); + } + return apply(objects); + } + + public static Object apply(List objects) { + for (int i = 0; i < objects.size() - 2; i += 2) { + if (objects.get(i) == Boolean.TRUE) { + return objects.get(i + 1); + } + } + // resort to default value + return objects.get(objects.size() - 1); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + CaseProcessor that = (CaseProcessor) o; + return Objects.equals(processors, that.processors); + } + + @Override + public int hashCode() { + return Objects.hash(processors); + } +} diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ConditionalFunction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ConditionalFunction.java index b3841f09e82..79c3f906b40 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ConditionalFunction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/ConditionalFunction.java @@ -15,6 +15,7 @@ import org.elasticsearch.xpack.sql.type.DataType; import org.elasticsearch.xpack.sql.type.DataTypeConversion; import java.util.List; +import java.util.Objects; import static org.elasticsearch.common.logging.LoggerMessageFormat.format; import static org.elasticsearch.xpack.sql.type.DataTypes.areTypesCompatible; @@ -75,4 +76,21 @@ public abstract class ConditionalFunction extends ScalarFunction { public Nullability nullable() { return Nullability.UNKNOWN; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConditionalFunction that = (ConditionalFunction) o; + return children().equals(that.children()); + } + + @Override + public int hashCode() { + return Objects.hash(children()); + } } diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/IfConditional.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/IfConditional.java new file mode 100644 index 00000000000..298f7d67329 --- /dev/null +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/IfConditional.java @@ -0,0 +1,92 @@ +/* + * 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.predicate.conditional; + +import org.elasticsearch.xpack.sql.expression.Expression; +import org.elasticsearch.xpack.sql.expression.Nullability; +import org.elasticsearch.xpack.sql.tree.NodeInfo; +import org.elasticsearch.xpack.sql.tree.Source; +import org.elasticsearch.xpack.sql.type.DataType; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +/** + * Helper expression (cannot be created directly from a query) to model a + * {@code WHEN ELSE } clause of {@link Case} expression + */ +public class IfConditional extends Expression { + + private final Expression condition; + private final Expression result; + + public IfConditional(Source source, Expression condition, Expression result) { + super(source, Arrays.asList(condition, result)); + this.condition = condition; + this.result = result; + } + + public Expression condition() { + return condition; + } + + public Expression result() { + return result; + } + + @Override + public Nullability nullable() { + return Nullability.UNKNOWN; + } + + @Override + public DataType dataType() { + return result.dataType(); + } + + @Override + public Expression replaceChildren(List newChildren) { + if (newChildren.size() < 2) { + throw new IllegalArgumentException("expected at least [2] children but received [" + newChildren.size() + "]"); + } + return new IfConditional(source(), newChildren.get(0), newChildren.get(1)); + } + + @Override + protected NodeInfo info() { + return NodeInfo.create(this, IfConditional::new, condition, result); + } + + @Override + protected TypeResolution resolveType() { + // Verification takes place is Case function to be + // able to generate more accurate error messages + return TypeResolution.TYPE_RESOLVED; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + + IfConditional that = (IfConditional) o; + return Objects.equals(condition, that.condition) && + Objects.equals(result, that.result); + } + + @Override + public int hashCode() { + return Objects.hash(condition, result); + } +} diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/optimizer/Optimizer.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/optimizer/Optimizer.java index eafdf21b119..78cc16470ca 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/optimizer/Optimizer.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/optimizer/Optimizer.java @@ -48,7 +48,9 @@ import org.elasticsearch.xpack.sql.expression.predicate.Negatable; import org.elasticsearch.xpack.sql.expression.predicate.Predicates; import org.elasticsearch.xpack.sql.expression.predicate.Range; import org.elasticsearch.xpack.sql.expression.predicate.conditional.ArbitraryConditionalFunction; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.Case; import org.elasticsearch.xpack.sql.expression.predicate.conditional.Coalesce; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.IfConditional; import org.elasticsearch.xpack.sql.expression.predicate.logical.And; import org.elasticsearch.xpack.sql.expression.predicate.logical.Not; import org.elasticsearch.xpack.sql.expression.predicate.logical.Or; @@ -127,6 +129,7 @@ public class Optimizer extends RuleExecutor { new FoldNull(), new ConstantFolding(), new SimplifyConditional(), + new SimplifyCase(), // boolean new BooleanSimplification(), new BooleanLiteralsOnTheRight(), @@ -1227,6 +1230,40 @@ public class Optimizer extends RuleExecutor { } } + static class SimplifyCase extends OptimizerExpressionRule { + + SimplifyCase() { + super(TransformDirection.DOWN); + } + + @Override + protected Expression rule(Expression e) { + if (e instanceof Case) { + Case c = (Case) e; + + // Remove or foldable conditions that fold to FALSE + // Stop at the 1st foldable condition that folds to TRUE + List newConditions = new ArrayList<>(); + for (IfConditional conditional : c.conditions()) { + if (conditional.condition().foldable()) { + Boolean res = (Boolean) conditional.condition().fold(); + if (res == Boolean.TRUE) { + newConditions.add(conditional); + break; + } + } else { + newConditions.add(conditional); + } + } + + if (newConditions.size() < c.children().size()) { + return c.replaceChildren(combine(newConditions, c.defaultElse())); + } + } + + return e; + } + } static class BooleanSimplification extends OptimizerExpressionRule { diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/ExpressionBuilder.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/ExpressionBuilder.java index ad2539ab99b..88b4cefd9b9 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/ExpressionBuilder.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/ExpressionBuilder.java @@ -32,6 +32,8 @@ import org.elasticsearch.xpack.sql.expression.literal.IntervalYearMonth; import org.elasticsearch.xpack.sql.expression.literal.Intervals; import org.elasticsearch.xpack.sql.expression.literal.Intervals.TimeUnit; import org.elasticsearch.xpack.sql.expression.predicate.Range; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.Case; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.IfConditional; import org.elasticsearch.xpack.sql.expression.predicate.fulltext.MatchQueryPredicate; import org.elasticsearch.xpack.sql.expression.predicate.fulltext.MultiMatchQueryPredicate; import org.elasticsearch.xpack.sql.expression.predicate.fulltext.StringQueryPredicate; @@ -116,6 +118,7 @@ import java.time.Duration; import java.time.Period; import java.time.format.DateTimeParseException; import java.time.temporal.TemporalAmount; +import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.Locale; @@ -459,6 +462,25 @@ abstract class ExpressionBuilder extends IdentifierBuilder { return new ScalarSubquery(source(ctx), plan(ctx.query())); } + @Override + public Object visitCase(SqlBaseParser.CaseContext ctx) { + List expressions = new ArrayList<>(ctx.whenClause().size()); + for (SqlBaseParser.WhenClauseContext when : ctx.whenClause()) { + if (ctx.operand != null) { + expressions.add(new IfConditional(source(when), + new Equals(source(when), expression(ctx.operand), expression(when.condition)), expression(when.result))); + } else { + expressions.add(new IfConditional(source(when), expression(when.condition), expression(when.result))); + } + } + if (ctx.elseClause != null) { + expressions.add(expression(ctx.elseClause)); + } else { + expressions.add(Literal.NULL); + } + return new Case(source(ctx), expressions); + } + @Override public Expression visitParenthesizedExpression(ParenthesizedExpressionContext ctx) { return expression(ctx.expression()); diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseBaseListener.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseBaseListener.java index bf5055ae216..9e8dd6cd6af 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseBaseListener.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseBaseListener.java @@ -743,6 +743,18 @@ class SqlBaseBaseListener implements SqlBaseListener { *

The default implementation does nothing.

*/ @Override public void exitSubqueryExpression(SqlBaseParser.SubqueryExpressionContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterCase(SqlBaseParser.CaseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitCase(SqlBaseParser.CaseContext ctx) { } /** * {@inheritDoc} * @@ -1151,6 +1163,18 @@ class SqlBaseBaseListener implements SqlBaseListener { *

The default implementation does nothing.

*/ @Override public void exitString(SqlBaseParser.StringContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterWhenClause(SqlBaseParser.WhenClauseContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitWhenClause(SqlBaseParser.WhenClauseContext ctx) { } /** * {@inheritDoc} * diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseBaseVisitor.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseBaseVisitor.java index 02d92832149..199fb407698 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseBaseVisitor.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseBaseVisitor.java @@ -438,6 +438,13 @@ class SqlBaseBaseVisitor extends AbstractParseTreeVisitor implements SqlBa * {@link #visitChildren} on {@code ctx}.

*/ @Override public T visitSubqueryExpression(SqlBaseParser.SubqueryExpressionContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitCase(SqlBaseParser.CaseContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * @@ -676,6 +683,13 @@ class SqlBaseBaseVisitor extends AbstractParseTreeVisitor implements SqlBa * {@link #visitChildren} on {@code ctx}.

*/ @Override public T visitString(SqlBaseParser.StringContext ctx) { return visitChildren(ctx); } + /** + * {@inheritDoc} + * + *

The default implementation returns the result of calling + * {@link #visitChildren} on {@code ctx}.

+ */ + @Override public T visitWhenClause(SqlBaseParser.WhenClauseContext ctx) { return visitChildren(ctx); } /** * {@inheritDoc} * diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseLexer.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseLexer.java index 132675e4178..a537f9f369e 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseLexer.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseLexer.java @@ -1,13 +1,16 @@ // ANTLR GENERATED CODE: DO NOT EDIT package org.elasticsearch.xpack.sql.parser; -import org.antlr.v4.runtime.Lexer; + import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.LexerATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.*; @SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) class SqlBaseLexer extends Lexer { @@ -18,88 +21,90 @@ class SqlBaseLexer extends Lexer { new PredictionContextCache(); 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, - AS=10, ASC=11, BETWEEN=12, BY=13, CAST=14, CATALOG=15, CATALOGS=16, COLUMNS=17, - CONVERT=18, CURRENT_DATE=19, CURRENT_TIME=20, CURRENT_TIMESTAMP=21, DAY=22, - DAYS=23, DEBUG=24, DESC=25, DESCRIBE=26, DISTINCT=27, ESCAPE=28, EXECUTABLE=29, - EXISTS=30, EXPLAIN=31, EXTRACT=32, FALSE=33, FIRST=34, FORMAT=35, FROM=36, - FULL=37, FUNCTIONS=38, GRAPHVIZ=39, GROUP=40, HAVING=41, HOUR=42, HOURS=43, - IN=44, INNER=45, INTERVAL=46, IS=47, JOIN=48, LAST=49, LEFT=50, LIKE=51, - LIMIT=52, MAPPED=53, MATCH=54, MINUTE=55, MINUTES=56, MONTH=57, MONTHS=58, - NATURAL=59, NOT=60, NULL=61, NULLS=62, ON=63, OPTIMIZED=64, OR=65, ORDER=66, - OUTER=67, PARSED=68, PHYSICAL=69, PLAN=70, RIGHT=71, RLIKE=72, QUERY=73, - SCHEMAS=74, SECOND=75, SECONDS=76, SELECT=77, SHOW=78, SYS=79, TABLE=80, - TABLES=81, TEXT=82, TRUE=83, TO=84, TYPE=85, TYPES=86, USING=87, VERIFY=88, - WHERE=89, WITH=90, YEAR=91, YEARS=92, ESCAPE_ESC=93, FUNCTION_ESC=94, - LIMIT_ESC=95, DATE_ESC=96, TIME_ESC=97, TIMESTAMP_ESC=98, GUID_ESC=99, - ESC_END=100, EQ=101, NULLEQ=102, NEQ=103, LT=104, LTE=105, GT=106, GTE=107, - PLUS=108, MINUS=109, ASTERISK=110, SLASH=111, PERCENT=112, CAST_OP=113, - CONCAT=114, DOT=115, PARAM=116, STRING=117, INTEGER_VALUE=118, DECIMAL_VALUE=119, - IDENTIFIER=120, DIGIT_IDENTIFIER=121, TABLE_IDENTIFIER=122, QUOTED_IDENTIFIER=123, - BACKQUOTED_IDENTIFIER=124, SIMPLE_COMMENT=125, BRACKETED_COMMENT=126, - WS=127, UNRECOGNIZED=128; + AS=10, ASC=11, BETWEEN=12, BY=13, CASE=14, CAST=15, CATALOG=16, CATALOGS=17, + COLUMNS=18, CONVERT=19, CURRENT_DATE=20, CURRENT_TIME=21, CURRENT_TIMESTAMP=22, + DAY=23, DAYS=24, DEBUG=25, DESC=26, DESCRIBE=27, DISTINCT=28, ELSE=29, + END=30, ESCAPE=31, EXECUTABLE=32, EXISTS=33, EXPLAIN=34, EXTRACT=35, FALSE=36, + FIRST=37, FORMAT=38, FROM=39, FULL=40, FUNCTIONS=41, GRAPHVIZ=42, GROUP=43, + HAVING=44, HOUR=45, HOURS=46, IN=47, INNER=48, INTERVAL=49, IS=50, JOIN=51, + LAST=52, LEFT=53, LIKE=54, LIMIT=55, MAPPED=56, MATCH=57, MINUTE=58, MINUTES=59, + MONTH=60, MONTHS=61, NATURAL=62, NOT=63, NULL=64, NULLS=65, ON=66, OPTIMIZED=67, + OR=68, ORDER=69, OUTER=70, PARSED=71, PHYSICAL=72, PLAN=73, RIGHT=74, + RLIKE=75, QUERY=76, SCHEMAS=77, SECOND=78, SECONDS=79, SELECT=80, SHOW=81, + SYS=82, TABLE=83, TABLES=84, TEXT=85, THEN=86, TRUE=87, TO=88, TYPE=89, + TYPES=90, USING=91, VERIFY=92, WHEN=93, WHERE=94, WITH=95, YEAR=96, YEARS=97, + ESCAPE_ESC=98, FUNCTION_ESC=99, LIMIT_ESC=100, DATE_ESC=101, TIME_ESC=102, + TIMESTAMP_ESC=103, GUID_ESC=104, ESC_END=105, EQ=106, NULLEQ=107, NEQ=108, + LT=109, LTE=110, GT=111, GTE=112, PLUS=113, MINUS=114, ASTERISK=115, SLASH=116, + PERCENT=117, CAST_OP=118, CONCAT=119, DOT=120, PARAM=121, STRING=122, + INTEGER_VALUE=123, DECIMAL_VALUE=124, IDENTIFIER=125, DIGIT_IDENTIFIER=126, + TABLE_IDENTIFIER=127, QUOTED_IDENTIFIER=128, BACKQUOTED_IDENTIFIER=129, + SIMPLE_COMMENT=130, BRACKETED_COMMENT=131, WS=132, UNRECOGNIZED=133; public static String[] modeNames = { "DEFAULT_MODE" }; public static final String[] ruleNames = { "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", "CASE", "CAST", "CATALOG", "CATALOGS", "COLUMNS", "CONVERT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "DAY", - "DAYS", "DEBUG", "DESC", "DESCRIBE", "DISTINCT", "ESCAPE", "EXECUTABLE", - "EXISTS", "EXPLAIN", "EXTRACT", "FALSE", "FIRST", "FORMAT", "FROM", "FULL", - "FUNCTIONS", "GRAPHVIZ", "GROUP", "HAVING", "HOUR", "HOURS", "IN", "INNER", - "INTERVAL", "IS", "JOIN", "LAST", "LEFT", "LIKE", "LIMIT", "MAPPED", "MATCH", - "MINUTE", "MINUTES", "MONTH", "MONTHS", "NATURAL", "NOT", "NULL", "NULLS", - "ON", "OPTIMIZED", "OR", "ORDER", "OUTER", "PARSED", "PHYSICAL", "PLAN", - "RIGHT", "RLIKE", "QUERY", "SCHEMAS", "SECOND", "SECONDS", "SELECT", "SHOW", - "SYS", "TABLE", "TABLES", "TEXT", "TRUE", "TO", "TYPE", "TYPES", "USING", - "VERIFY", "WHERE", "WITH", "YEAR", "YEARS", "ESCAPE_ESC", "FUNCTION_ESC", - "LIMIT_ESC", "DATE_ESC", "TIME_ESC", "TIMESTAMP_ESC", "GUID_ESC", "ESC_END", - "EQ", "NULLEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", - "SLASH", "PERCENT", "CAST_OP", "CONCAT", "DOT", "PARAM", "STRING", "INTEGER_VALUE", - "DECIMAL_VALUE", "IDENTIFIER", "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", - "QUOTED_IDENTIFIER", "BACKQUOTED_IDENTIFIER", "EXPONENT", "DIGIT", "LETTER", - "SIMPLE_COMMENT", "BRACKETED_COMMENT", "WS", "UNRECOGNIZED" + "DAYS", "DEBUG", "DESC", "DESCRIBE", "DISTINCT", "ELSE", "END", "ESCAPE", + "EXECUTABLE", "EXISTS", "EXPLAIN", "EXTRACT", "FALSE", "FIRST", "FORMAT", + "FROM", "FULL", "FUNCTIONS", "GRAPHVIZ", "GROUP", "HAVING", "HOUR", "HOURS", + "IN", "INNER", "INTERVAL", "IS", "JOIN", "LAST", "LEFT", "LIKE", "LIMIT", + "MAPPED", "MATCH", "MINUTE", "MINUTES", "MONTH", "MONTHS", "NATURAL", + "NOT", "NULL", "NULLS", "ON", "OPTIMIZED", "OR", "ORDER", "OUTER", "PARSED", + "PHYSICAL", "PLAN", "RIGHT", "RLIKE", "QUERY", "SCHEMAS", "SECOND", "SECONDS", + "SELECT", "SHOW", "SYS", "TABLE", "TABLES", "TEXT", "THEN", "TRUE", "TO", + "TYPE", "TYPES", "USING", "VERIFY", "WHEN", "WHERE", "WITH", "YEAR", "YEARS", + "ESCAPE_ESC", "FUNCTION_ESC", "LIMIT_ESC", "DATE_ESC", "TIME_ESC", "TIMESTAMP_ESC", + "GUID_ESC", "ESC_END", "EQ", "NULLEQ", "NEQ", "LT", "LTE", "GT", "GTE", + "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "CAST_OP", "CONCAT", + "DOT", "PARAM", "STRING", "INTEGER_VALUE", "DECIMAL_VALUE", "IDENTIFIER", + "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", "QUOTED_IDENTIFIER", "BACKQUOTED_IDENTIFIER", + "EXPONENT", "DIGIT", "LETTER", "SIMPLE_COMMENT", "BRACKETED_COMMENT", + "WS", "UNRECOGNIZED" }; private static final String[] _LITERAL_NAMES = { null, "'('", "')'", "','", "':'", "'ALL'", "'ANALYZE'", "'ANALYZED'", - "'AND'", "'ANY'", "'AS'", "'ASC'", "'BETWEEN'", "'BY'", "'CAST'", "'CATALOG'", - "'CATALOGS'", "'COLUMNS'", "'CONVERT'", "'CURRENT_DATE'", "'CURRENT_TIME'", - "'CURRENT_TIMESTAMP'", "'DAY'", "'DAYS'", "'DEBUG'", "'DESC'", "'DESCRIBE'", - "'DISTINCT'", "'ESCAPE'", "'EXECUTABLE'", "'EXISTS'", "'EXPLAIN'", "'EXTRACT'", - "'FALSE'", "'FIRST'", "'FORMAT'", "'FROM'", "'FULL'", "'FUNCTIONS'", "'GRAPHVIZ'", - "'GROUP'", "'HAVING'", "'HOUR'", "'HOURS'", "'IN'", "'INNER'", "'INTERVAL'", - "'IS'", "'JOIN'", "'LAST'", "'LEFT'", "'LIKE'", "'LIMIT'", "'MAPPED'", - "'MATCH'", "'MINUTE'", "'MINUTES'", "'MONTH'", "'MONTHS'", "'NATURAL'", - "'NOT'", "'NULL'", "'NULLS'", "'ON'", "'OPTIMIZED'", "'OR'", "'ORDER'", - "'OUTER'", "'PARSED'", "'PHYSICAL'", "'PLAN'", "'RIGHT'", "'RLIKE'", "'QUERY'", - "'SCHEMAS'", "'SECOND'", "'SECONDS'", "'SELECT'", "'SHOW'", "'SYS'", "'TABLE'", - "'TABLES'", "'TEXT'", "'TRUE'", "'TO'", "'TYPE'", "'TYPES'", "'USING'", - "'VERIFY'", "'WHERE'", "'WITH'", "'YEAR'", "'YEARS'", "'{ESCAPE'", "'{FN'", - "'{LIMIT'", "'{D'", "'{T'", "'{TS'", "'{GUID'", "'}'", "'='", "'<=>'", - null, "'<'", "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", - "'::'", "'||'", "'.'", "'?'" + "'AND'", "'ANY'", "'AS'", "'ASC'", "'BETWEEN'", "'BY'", "'CASE'", "'CAST'", + "'CATALOG'", "'CATALOGS'", "'COLUMNS'", "'CONVERT'", "'CURRENT_DATE'", + "'CURRENT_TIME'", "'CURRENT_TIMESTAMP'", "'DAY'", "'DAYS'", "'DEBUG'", + "'DESC'", "'DESCRIBE'", "'DISTINCT'", "'ELSE'", "'END'", "'ESCAPE'", "'EXECUTABLE'", + "'EXISTS'", "'EXPLAIN'", "'EXTRACT'", "'FALSE'", "'FIRST'", "'FORMAT'", + "'FROM'", "'FULL'", "'FUNCTIONS'", "'GRAPHVIZ'", "'GROUP'", "'HAVING'", + "'HOUR'", "'HOURS'", "'IN'", "'INNER'", "'INTERVAL'", "'IS'", "'JOIN'", + "'LAST'", "'LEFT'", "'LIKE'", "'LIMIT'", "'MAPPED'", "'MATCH'", "'MINUTE'", + "'MINUTES'", "'MONTH'", "'MONTHS'", "'NATURAL'", "'NOT'", "'NULL'", "'NULLS'", + "'ON'", "'OPTIMIZED'", "'OR'", "'ORDER'", "'OUTER'", "'PARSED'", "'PHYSICAL'", + "'PLAN'", "'RIGHT'", "'RLIKE'", "'QUERY'", "'SCHEMAS'", "'SECOND'", "'SECONDS'", + "'SELECT'", "'SHOW'", "'SYS'", "'TABLE'", "'TABLES'", "'TEXT'", "'THEN'", + "'TRUE'", "'TO'", "'TYPE'", "'TYPES'", "'USING'", "'VERIFY'", "'WHEN'", + "'WHERE'", "'WITH'", "'YEAR'", "'YEARS'", "'{ESCAPE'", "'{FN'", "'{LIMIT'", + "'{D'", "'{T'", "'{TS'", "'{GUID'", "'}'", "'='", "'<=>'", null, "'<'", + "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", "'::'", "'||'", + "'.'", "'?'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, "ALL", "ANALYZE", "ANALYZED", "AND", "ANY", - "AS", "ASC", "BETWEEN", "BY", "CAST", "CATALOG", "CATALOGS", "COLUMNS", + "AS", "ASC", "BETWEEN", "BY", "CASE", "CAST", "CATALOG", "CATALOGS", "COLUMNS", "CONVERT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "DAY", - "DAYS", "DEBUG", "DESC", "DESCRIBE", "DISTINCT", "ESCAPE", "EXECUTABLE", - "EXISTS", "EXPLAIN", "EXTRACT", "FALSE", "FIRST", "FORMAT", "FROM", "FULL", - "FUNCTIONS", "GRAPHVIZ", "GROUP", "HAVING", "HOUR", "HOURS", "IN", "INNER", - "INTERVAL", "IS", "JOIN", "LAST", "LEFT", "LIKE", "LIMIT", "MAPPED", "MATCH", - "MINUTE", "MINUTES", "MONTH", "MONTHS", "NATURAL", "NOT", "NULL", "NULLS", - "ON", "OPTIMIZED", "OR", "ORDER", "OUTER", "PARSED", "PHYSICAL", "PLAN", - "RIGHT", "RLIKE", "QUERY", "SCHEMAS", "SECOND", "SECONDS", "SELECT", "SHOW", - "SYS", "TABLE", "TABLES", "TEXT", "TRUE", "TO", "TYPE", "TYPES", "USING", - "VERIFY", "WHERE", "WITH", "YEAR", "YEARS", "ESCAPE_ESC", "FUNCTION_ESC", - "LIMIT_ESC", "DATE_ESC", "TIME_ESC", "TIMESTAMP_ESC", "GUID_ESC", "ESC_END", - "EQ", "NULLEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", - "SLASH", "PERCENT", "CAST_OP", "CONCAT", "DOT", "PARAM", "STRING", "INTEGER_VALUE", - "DECIMAL_VALUE", "IDENTIFIER", "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", - "QUOTED_IDENTIFIER", "BACKQUOTED_IDENTIFIER", "SIMPLE_COMMENT", "BRACKETED_COMMENT", - "WS", "UNRECOGNIZED" + "DAYS", "DEBUG", "DESC", "DESCRIBE", "DISTINCT", "ELSE", "END", "ESCAPE", + "EXECUTABLE", "EXISTS", "EXPLAIN", "EXTRACT", "FALSE", "FIRST", "FORMAT", + "FROM", "FULL", "FUNCTIONS", "GRAPHVIZ", "GROUP", "HAVING", "HOUR", "HOURS", + "IN", "INNER", "INTERVAL", "IS", "JOIN", "LAST", "LEFT", "LIKE", "LIMIT", + "MAPPED", "MATCH", "MINUTE", "MINUTES", "MONTH", "MONTHS", "NATURAL", + "NOT", "NULL", "NULLS", "ON", "OPTIMIZED", "OR", "ORDER", "OUTER", "PARSED", + "PHYSICAL", "PLAN", "RIGHT", "RLIKE", "QUERY", "SCHEMAS", "SECOND", "SECONDS", + "SELECT", "SHOW", "SYS", "TABLE", "TABLES", "TEXT", "THEN", "TRUE", "TO", + "TYPE", "TYPES", "USING", "VERIFY", "WHEN", "WHERE", "WITH", "YEAR", "YEARS", + "ESCAPE_ESC", "FUNCTION_ESC", "LIMIT_ESC", "DATE_ESC", "TIME_ESC", "TIMESTAMP_ESC", + "GUID_ESC", "ESC_END", "EQ", "NULLEQ", "NEQ", "LT", "LTE", "GT", "GTE", + "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "CAST_OP", "CONCAT", + "DOT", "PARAM", "STRING", "INTEGER_VALUE", "DECIMAL_VALUE", "IDENTIFIER", + "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", "QUOTED_IDENTIFIER", "BACKQUOTED_IDENTIFIER", + "SIMPLE_COMMENT", "BRACKETED_COMMENT", "WS", "UNRECOGNIZED" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -156,7 +161,7 @@ class SqlBaseLexer extends Lexer { public ATN getATN() { return _ATN; } public static final String _serializedATN = - "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\u0082\u043c\b\1\4"+ + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2\u0087\u045e\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"+ "\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"+ @@ -171,55 +176,60 @@ class SqlBaseLexer extends Lexer { "\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"+ "\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084"+ - "\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"+ - "\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"+ - "\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"+ - "\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"+ - "\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"+ - "\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"+ - "\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"+ - "\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"+ - "\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"+ - "\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"+ - "\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"+ - "\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"+ - "\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"+ - "\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\60\3\60\3\60\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\63\3\64\3\64\3\64\3\64"+ - "\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"+ - "\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"+ - "\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>\3?\3?\3?\3?\3?\3?\3@\3@\3@\3A\3A\3A\3A\3A"+ - "\3A\3A\3A\3A\3A\3B\3B\3B\3C\3C\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3E\3E\3E"+ - "\3E\3E\3E\3E\3F\3F\3F\3F\3F\3F\3F\3F\3F\3G\3G\3G\3G\3G\3H\3H\3H\3H\3H"+ - "\3H\3I\3I\3I\3I\3I\3I\3J\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3K\3K\3L\3L"+ - "\3L\3L\3L\3L\3L\3M\3M\3M\3M\3M\3M\3M\3M\3N\3N\3N\3N\3N\3N\3N\3O\3O\3O"+ - "\3O\3O\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3S\3S\3S\3S"+ - "\3S\3T\3T\3T\3T\3T\3U\3U\3U\3V\3V\3V\3V\3V\3W\3W\3W\3W\3W\3W\3X\3X\3X"+ - "\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^\3^\3^\3^\3_\3_\3_\3_\3"+ - "`\3`\3`\3`\3`\3`\3`\3a\3a\3a\3b\3b\3b\3c\3c\3c\3c\3d\3d\3d\3d\3d\3d\3"+ - "e\3e\3f\3f\3g\3g\3g\3g\3h\3h\3h\3h\5h\u037a\nh\3i\3i\3j\3j\3j\3k\3k\3"+ - "l\3l\3l\3m\3m\3n\3n\3o\3o\3p\3p\3q\3q\3r\3r\3r\3s\3s\3s\3t\3t\3u\3u\3"+ - "v\3v\3v\3v\7v\u039e\nv\fv\16v\u03a1\13v\3v\3v\3w\6w\u03a6\nw\rw\16w\u03a7"+ - "\3x\6x\u03ab\nx\rx\16x\u03ac\3x\3x\7x\u03b1\nx\fx\16x\u03b4\13x\3x\3x"+ - "\6x\u03b8\nx\rx\16x\u03b9\3x\6x\u03bd\nx\rx\16x\u03be\3x\3x\7x\u03c3\n"+ - "x\fx\16x\u03c6\13x\5x\u03c8\nx\3x\3x\3x\3x\6x\u03ce\nx\rx\16x\u03cf\3"+ - "x\3x\5x\u03d4\nx\3y\3y\5y\u03d8\ny\3y\3y\3y\7y\u03dd\ny\fy\16y\u03e0\13"+ - "y\3z\3z\3z\3z\6z\u03e6\nz\rz\16z\u03e7\3{\3{\3{\6{\u03ed\n{\r{\16{\u03ee"+ - "\3|\3|\3|\3|\7|\u03f5\n|\f|\16|\u03f8\13|\3|\3|\3}\3}\3}\3}\7}\u0400\n"+ - "}\f}\16}\u0403\13}\3}\3}\3~\3~\5~\u0409\n~\3~\6~\u040c\n~\r~\16~\u040d"+ - "\3\177\3\177\3\u0080\3\u0080\3\u0081\3\u0081\3\u0081\3\u0081\7\u0081\u0418"+ - "\n\u0081\f\u0081\16\u0081\u041b\13\u0081\3\u0081\5\u0081\u041e\n\u0081"+ - "\3\u0081\5\u0081\u0421\n\u0081\3\u0081\3\u0081\3\u0082\3\u0082\3\u0082"+ - "\3\u0082\3\u0082\7\u0082\u042a\n\u0082\f\u0082\16\u0082\u042d\13\u0082"+ - "\3\u0082\3\u0082\3\u0082\3\u0082\3\u0082\3\u0083\6\u0083\u0435\n\u0083"+ - "\r\u0083\16\u0083\u0436\3\u0083\3\u0083\3\u0084\3\u0084\3\u042b\2\u0085"+ + "\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089"+ + "\t\u0089\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\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\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\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\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\3\22\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\3\24\3\24\3\24\3\24\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\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\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27"+ + "\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\31\3\31"+ + "\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\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\35\3\35\3\35"+ + "\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\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\60\3\60\3\60\3\61\3\61\3\61\3\61\3\61\3\61\3\62\3\62\3\62\3\62\3\62"+ + "\3\62\3\62\3\62\3\62\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\64\3\65\3\65"+ + "\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\66\3\67\3\67\3\67\3\67\3\67\38\3"+ + "8\38\38\38\38\39\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=\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\3A\3A\3B\3B\3B\3B\3B\3B\3"+ + "C\3C\3C\3D\3D\3D\3D\3D\3D\3D\3D\3D\3D\3E\3E\3E\3F\3F\3F\3F\3F\3F\3G\3"+ + "G\3G\3G\3G\3G\3H\3H\3H\3H\3H\3H\3H\3I\3I\3I\3I\3I\3I\3I\3I\3I\3J\3J\3"+ + "J\3J\3J\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3M\3M\3M\3M\3M\3M\3N\3N\3"+ + "N\3N\3N\3N\3N\3N\3O\3O\3O\3O\3O\3O\3O\3P\3P\3P\3P\3P\3P\3P\3P\3Q\3Q\3"+ + "Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3"+ + "U\3U\3U\3U\3V\3V\3V\3V\3V\3W\3W\3W\3W\3W\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Z\3"+ + "Z\3Z\3Z\3Z\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`\3a\3a\3a\3a\3a\3"+ + "b\3b\3b\3b\3b\3b\3c\3c\3c\3c\3c\3c\3c\3c\3d\3d\3d\3d\3e\3e\3e\3e\3e\3"+ + "e\3e\3f\3f\3f\3g\3g\3g\3h\3h\3h\3h\3i\3i\3i\3i\3i\3i\3j\3j\3k\3k\3l\3"+ + "l\3l\3l\3m\3m\3m\3m\5m\u039c\nm\3n\3n\3o\3o\3o\3p\3p\3q\3q\3q\3r\3r\3"+ + "s\3s\3t\3t\3u\3u\3v\3v\3w\3w\3w\3x\3x\3x\3y\3y\3z\3z\3{\3{\3{\3{\7{\u03c0"+ + "\n{\f{\16{\u03c3\13{\3{\3{\3|\6|\u03c8\n|\r|\16|\u03c9\3}\6}\u03cd\n}"+ + "\r}\16}\u03ce\3}\3}\7}\u03d3\n}\f}\16}\u03d6\13}\3}\3}\6}\u03da\n}\r}"+ + "\16}\u03db\3}\6}\u03df\n}\r}\16}\u03e0\3}\3}\7}\u03e5\n}\f}\16}\u03e8"+ + "\13}\5}\u03ea\n}\3}\3}\3}\3}\6}\u03f0\n}\r}\16}\u03f1\3}\3}\5}\u03f6\n"+ + "}\3~\3~\5~\u03fa\n~\3~\3~\3~\7~\u03ff\n~\f~\16~\u0402\13~\3\177\3\177"+ + "\3\177\3\177\6\177\u0408\n\177\r\177\16\177\u0409\3\u0080\3\u0080\3\u0080"+ + "\6\u0080\u040f\n\u0080\r\u0080\16\u0080\u0410\3\u0081\3\u0081\3\u0081"+ + "\3\u0081\7\u0081\u0417\n\u0081\f\u0081\16\u0081\u041a\13\u0081\3\u0081"+ + "\3\u0081\3\u0082\3\u0082\3\u0082\3\u0082\7\u0082\u0422\n\u0082\f\u0082"+ + "\16\u0082\u0425\13\u0082\3\u0082\3\u0082\3\u0083\3\u0083\5\u0083\u042b"+ + "\n\u0083\3\u0083\6\u0083\u042e\n\u0083\r\u0083\16\u0083\u042f\3\u0084"+ + "\3\u0084\3\u0085\3\u0085\3\u0086\3\u0086\3\u0086\3\u0086\7\u0086\u043a"+ + "\n\u0086\f\u0086\16\u0086\u043d\13\u0086\3\u0086\5\u0086\u0440\n\u0086"+ + "\3\u0086\5\u0086\u0443\n\u0086\3\u0086\3\u0086\3\u0087\3\u0087\3\u0087"+ + "\3\u0087\3\u0087\7\u0087\u044c\n\u0087\f\u0087\16\u0087\u044f\13\u0087"+ + "\3\u0087\3\u0087\3\u0087\3\u0087\3\u0087\3\u0088\6\u0088\u0457\n\u0088"+ + "\r\u0088\16\u0088\u0458\3\u0088\3\u0088\3\u0089\3\u0089\3\u044d\2\u008a"+ "\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"+ "\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37"+ "= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o"+ @@ -229,302 +239,313 @@ class SqlBaseLexer extends Lexer { "\\\u00b7]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9"+ "f\u00cbg\u00cdh\u00cfi\u00d1j\u00d3k\u00d5l\u00d7m\u00d9n\u00dbo\u00dd"+ "p\u00dfq\u00e1r\u00e3s\u00e5t\u00e7u\u00e9v\u00ebw\u00edx\u00efy\u00f1"+ - "z\u00f3{\u00f5|\u00f7}\u00f9~\u00fb\2\u00fd\2\u00ff\2\u0101\177\u0103"+ - "\u0080\u0105\u0081\u0107\u0082\3\2\13\3\2))\4\2BBaa\3\2$$\3\2bb\4\2--"+ - "//\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"+ - "\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\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"+ - "\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\'\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\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\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"+ - "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\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\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"+ - "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\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\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\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\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\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\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\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\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\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\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\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\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\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\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\2\u0103\3\2\2\2\2\u0105\3\2\2\2\2\u0107\3\2\2\2\3\u0109\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"+ - "\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"+ - "\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\37\u0145\3\2\2\2!\u014d\3\2\2\2#\u0156\3\2\2\2%\u015e\3\2\2\2\'"+ - "\u0166\3\2\2\2)\u0173\3\2\2\2+\u0180\3\2\2\2-\u0192\3\2\2\2/\u0196\3\2"+ - "\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"+ - "\29\u01b8\3\2\2\2;\u01bf\3\2\2\2=\u01ca\3\2\2\2?\u01d1\3\2\2\2A\u01d9"+ - "\3\2\2\2C\u01e1\3\2\2\2E\u01e7\3\2\2\2G\u01ed\3\2\2\2I\u01f4\3\2\2\2K"+ - "\u01f9\3\2\2\2M\u01fe\3\2\2\2O\u0208\3\2\2\2Q\u0211\3\2\2\2S\u0217\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"+ - "\3\2\2\2_\u023b\3\2\2\2a\u023e\3\2\2\2c\u0243\3\2\2\2e\u0248\3\2\2\2g"+ - "\u024d\3\2\2\2i\u0252\3\2\2\2k\u0258\3\2\2\2m\u025f\3\2\2\2o\u0265\3\2"+ - "\2\2q\u026c\3\2\2\2s\u0274\3\2\2\2u\u027a\3\2\2\2w\u0281\3\2\2\2y\u0289"+ - "\3\2\2\2{\u028d\3\2\2\2}\u0292\3\2\2\2\177\u0298\3\2\2\2\u0081\u029b\3"+ - "\2\2\2\u0083\u02a5\3\2\2\2\u0085\u02a8\3\2\2\2\u0087\u02ae\3\2\2\2\u0089"+ - "\u02b4\3\2\2\2\u008b\u02bb\3\2\2\2\u008d\u02c4\3\2\2\2\u008f\u02c9\3\2"+ - "\2\2\u0091\u02cf\3\2\2\2\u0093\u02d5\3\2\2\2\u0095\u02db\3\2\2\2\u0097"+ - "\u02e3\3\2\2\2\u0099\u02ea\3\2\2\2\u009b\u02f2\3\2\2\2\u009d\u02f9\3\2"+ - "\2\2\u009f\u02fe\3\2\2\2\u00a1\u0302\3\2\2\2\u00a3\u0308\3\2\2\2\u00a5"+ - "\u030f\3\2\2\2\u00a7\u0314\3\2\2\2\u00a9\u0319\3\2\2\2\u00ab\u031c\3\2"+ - "\2\2\u00ad\u0321\3\2\2\2\u00af\u0327\3\2\2\2\u00b1\u032d\3\2\2\2\u00b3"+ - "\u0334\3\2\2\2\u00b5\u033a\3\2\2\2\u00b7\u033f\3\2\2\2\u00b9\u0344\3\2"+ - "\2\2\u00bb\u034a\3\2\2\2\u00bd\u0352\3\2\2\2\u00bf\u0356\3\2\2\2\u00c1"+ - "\u035d\3\2\2\2\u00c3\u0360\3\2\2\2\u00c5\u0363\3\2\2\2\u00c7\u0367\3\2"+ - "\2\2\u00c9\u036d\3\2\2\2\u00cb\u036f\3\2\2\2\u00cd\u0371\3\2\2\2\u00cf"+ - "\u0379\3\2\2\2\u00d1\u037b\3\2\2\2\u00d3\u037d\3\2\2\2\u00d5\u0380\3\2"+ - "\2\2\u00d7\u0382\3\2\2\2\u00d9\u0385\3\2\2\2\u00db\u0387\3\2\2\2\u00dd"+ - "\u0389\3\2\2\2\u00df\u038b\3\2\2\2\u00e1\u038d\3\2\2\2\u00e3\u038f\3\2"+ - "\2\2\u00e5\u0392\3\2\2\2\u00e7\u0395\3\2\2\2\u00e9\u0397\3\2\2\2\u00eb"+ - "\u0399\3\2\2\2\u00ed\u03a5\3\2\2\2\u00ef\u03d3\3\2\2\2\u00f1\u03d7\3\2"+ - "\2\2\u00f3\u03e1\3\2\2\2\u00f5\u03ec\3\2\2\2\u00f7\u03f0\3\2\2\2\u00f9"+ - "\u03fb\3\2\2\2\u00fb\u0406\3\2\2\2\u00fd\u040f\3\2\2\2\u00ff\u0411\3\2"+ - "\2\2\u0101\u0413\3\2\2\2\u0103\u0424\3\2\2\2\u0105\u0434\3\2\2\2\u0107"+ - "\u043a\3\2\2\2\u0109\u010a\7*\2\2\u010a\4\3\2\2\2\u010b\u010c\7+\2\2\u010c"+ - "\6\3\2\2\2\u010d\u010e\7.\2\2\u010e\b\3\2\2\2\u010f\u0110\7<\2\2\u0110"+ - "\n\3\2\2\2\u0111\u0112\7C\2\2\u0112\u0113\7N\2\2\u0113\u0114\7N\2\2\u0114"+ - "\f\3\2\2\2\u0115\u0116\7C\2\2\u0116\u0117\7P\2\2\u0117\u0118\7C\2\2\u0118"+ - "\u0119\7N\2\2\u0119\u011a\7[\2\2\u011a\u011b\7\\\2\2\u011b\u011c\7G\2"+ - "\2\u011c\16\3\2\2\2\u011d\u011e\7C\2\2\u011e\u011f\7P\2\2\u011f\u0120"+ - "\7C\2\2\u0120\u0121\7N\2\2\u0121\u0122\7[\2\2\u0122\u0123\7\\\2\2\u0123"+ - "\u0124\7G\2\2\u0124\u0125\7F\2\2\u0125\20\3\2\2\2\u0126\u0127\7C\2\2\u0127"+ - "\u0128\7P\2\2\u0128\u0129\7F\2\2\u0129\22\3\2\2\2\u012a\u012b\7C\2\2\u012b"+ - "\u012c\7P\2\2\u012c\u012d\7[\2\2\u012d\24\3\2\2\2\u012e\u012f\7C\2\2\u012f"+ - "\u0130\7U\2\2\u0130\26\3\2\2\2\u0131\u0132\7C\2\2\u0132\u0133\7U\2\2\u0133"+ - "\u0134\7E\2\2\u0134\30\3\2\2\2\u0135\u0136\7D\2\2\u0136\u0137\7G\2\2\u0137"+ - "\u0138\7V\2\2\u0138\u0139\7Y\2\2\u0139\u013a\7G\2\2\u013a\u013b\7G\2\2"+ - "\u013b\u013c\7P\2\2\u013c\32\3\2\2\2\u013d\u013e\7D\2\2\u013e\u013f\7"+ - "[\2\2\u013f\34\3\2\2\2\u0140\u0141\7E\2\2\u0141\u0142\7C\2\2\u0142\u0143"+ - "\7U\2\2\u0143\u0144\7V\2\2\u0144\36\3\2\2\2\u0145\u0146\7E\2\2\u0146\u0147"+ - "\7C\2\2\u0147\u0148\7V\2\2\u0148\u0149\7C\2\2\u0149\u014a\7N\2\2\u014a"+ - "\u014b\7Q\2\2\u014b\u014c\7I\2\2\u014c \3\2\2\2\u014d\u014e\7E\2\2\u014e"+ - "\u014f\7C\2\2\u014f\u0150\7V\2\2\u0150\u0151\7C\2\2\u0151\u0152\7N\2\2"+ - "\u0152\u0153\7Q\2\2\u0153\u0154\7I\2\2\u0154\u0155\7U\2\2\u0155\"\3\2"+ - "\2\2\u0156\u0157\7E\2\2\u0157\u0158\7Q\2\2\u0158\u0159\7N\2\2\u0159\u015a"+ - "\7W\2\2\u015a\u015b\7O\2\2\u015b\u015c\7P\2\2\u015c\u015d\7U\2\2\u015d"+ - "$\3\2\2\2\u015e\u015f\7E\2\2\u015f\u0160\7Q\2\2\u0160\u0161\7P\2\2\u0161"+ - "\u0162\7X\2\2\u0162\u0163\7G\2\2\u0163\u0164\7T\2\2\u0164\u0165\7V\2\2"+ - "\u0165&\3\2\2\2\u0166\u0167\7E\2\2\u0167\u0168\7W\2\2\u0168\u0169\7T\2"+ - "\2\u0169\u016a\7T\2\2\u016a\u016b\7G\2\2\u016b\u016c\7P\2\2\u016c\u016d"+ - "\7V\2\2\u016d\u016e\7a\2\2\u016e\u016f\7F\2\2\u016f\u0170\7C\2\2\u0170"+ - "\u0171\7V\2\2\u0171\u0172\7G\2\2\u0172(\3\2\2\2\u0173\u0174\7E\2\2\u0174"+ - "\u0175\7W\2\2\u0175\u0176\7T\2\2\u0176\u0177\7T\2\2\u0177\u0178\7G\2\2"+ - "\u0178\u0179\7P\2\2\u0179\u017a\7V\2\2\u017a\u017b\7a\2\2\u017b\u017c"+ - "\7V\2\2\u017c\u017d\7K\2\2\u017d\u017e\7O\2\2\u017e\u017f\7G\2\2\u017f"+ - "*\3\2\2\2\u0180\u0181\7E\2\2\u0181\u0182\7W\2\2\u0182\u0183\7T\2\2\u0183"+ - "\u0184\7T\2\2\u0184\u0185\7G\2\2\u0185\u0186\7P\2\2\u0186\u0187\7V\2\2"+ - "\u0187\u0188\7a\2\2\u0188\u0189\7V\2\2\u0189\u018a\7K\2\2\u018a\u018b"+ - "\7O\2\2\u018b\u018c\7G\2\2\u018c\u018d\7U\2\2\u018d\u018e\7V\2\2\u018e"+ - "\u018f\7C\2\2\u018f\u0190\7O\2\2\u0190\u0191\7R\2\2\u0191,\3\2\2\2\u0192"+ - "\u0193\7F\2\2\u0193\u0194\7C\2\2\u0194\u0195\7[\2\2\u0195.\3\2\2\2\u0196"+ - "\u0197\7F\2\2\u0197\u0198\7C\2\2\u0198\u0199\7[\2\2\u0199\u019a\7U\2\2"+ - "\u019a\60\3\2\2\2\u019b\u019c\7F\2\2\u019c\u019d\7G\2\2\u019d\u019e\7"+ - "D\2\2\u019e\u019f\7W\2\2\u019f\u01a0\7I\2\2\u01a0\62\3\2\2\2\u01a1\u01a2"+ - "\7F\2\2\u01a2\u01a3\7G\2\2\u01a3\u01a4\7U\2\2\u01a4\u01a5\7E\2\2\u01a5"+ - "\64\3\2\2\2\u01a6\u01a7\7F\2\2\u01a7\u01a8\7G\2\2\u01a8\u01a9\7U\2\2\u01a9"+ - "\u01aa\7E\2\2\u01aa\u01ab\7T\2\2\u01ab\u01ac\7K\2\2\u01ac\u01ad\7D\2\2"+ - "\u01ad\u01ae\7G\2\2\u01ae\66\3\2\2\2\u01af\u01b0\7F\2\2\u01b0\u01b1\7"+ - "K\2\2\u01b1\u01b2\7U\2\2\u01b2\u01b3\7V\2\2\u01b3\u01b4\7K\2\2\u01b4\u01b5"+ - "\7P\2\2\u01b5\u01b6\7E\2\2\u01b6\u01b7\7V\2\2\u01b78\3\2\2\2\u01b8\u01b9"+ - "\7G\2\2\u01b9\u01ba\7U\2\2\u01ba\u01bb\7E\2\2\u01bb\u01bc\7C\2\2\u01bc"+ - "\u01bd\7R\2\2\u01bd\u01be\7G\2\2\u01be:\3\2\2\2\u01bf\u01c0\7G\2\2\u01c0"+ - "\u01c1\7Z\2\2\u01c1\u01c2\7G\2\2\u01c2\u01c3\7E\2\2\u01c3\u01c4\7W\2\2"+ - "\u01c4\u01c5\7V\2\2\u01c5\u01c6\7C\2\2\u01c6\u01c7\7D\2\2\u01c7\u01c8"+ - "\7N\2\2\u01c8\u01c9\7G\2\2\u01c9<\3\2\2\2\u01ca\u01cb\7G\2\2\u01cb\u01cc"+ - "\7Z\2\2\u01cc\u01cd\7K\2\2\u01cd\u01ce\7U\2\2\u01ce\u01cf\7V\2\2\u01cf"+ - "\u01d0\7U\2\2\u01d0>\3\2\2\2\u01d1\u01d2\7G\2\2\u01d2\u01d3\7Z\2\2\u01d3"+ - "\u01d4\7R\2\2\u01d4\u01d5\7N\2\2\u01d5\u01d6\7C\2\2\u01d6\u01d7\7K\2\2"+ - "\u01d7\u01d8\7P\2\2\u01d8@\3\2\2\2\u01d9\u01da\7G\2\2\u01da\u01db\7Z\2"+ - "\2\u01db\u01dc\7V\2\2\u01dc\u01dd\7T\2\2\u01dd\u01de\7C\2\2\u01de\u01df"+ - "\7E\2\2\u01df\u01e0\7V\2\2\u01e0B\3\2\2\2\u01e1\u01e2\7H\2\2\u01e2\u01e3"+ - "\7C\2\2\u01e3\u01e4\7N\2\2\u01e4\u01e5\7U\2\2\u01e5\u01e6\7G\2\2\u01e6"+ - "D\3\2\2\2\u01e7\u01e8\7H\2\2\u01e8\u01e9\7K\2\2\u01e9\u01ea\7T\2\2\u01ea"+ - "\u01eb\7U\2\2\u01eb\u01ec\7V\2\2\u01ecF\3\2\2\2\u01ed\u01ee\7H\2\2\u01ee"+ - "\u01ef\7Q\2\2\u01ef\u01f0\7T\2\2\u01f0\u01f1\7O\2\2\u01f1\u01f2\7C\2\2"+ - "\u01f2\u01f3\7V\2\2\u01f3H\3\2\2\2\u01f4\u01f5\7H\2\2\u01f5\u01f6\7T\2"+ - "\2\u01f6\u01f7\7Q\2\2\u01f7\u01f8\7O\2\2\u01f8J\3\2\2\2\u01f9\u01fa\7"+ - "H\2\2\u01fa\u01fb\7W\2\2\u01fb\u01fc\7N\2\2\u01fc\u01fd\7N\2\2\u01fdL"+ - "\3\2\2\2\u01fe\u01ff\7H\2\2\u01ff\u0200\7W\2\2\u0200\u0201\7P\2\2\u0201"+ - "\u0202\7E\2\2\u0202\u0203\7V\2\2\u0203\u0204\7K\2\2\u0204\u0205\7Q\2\2"+ - "\u0205\u0206\7P\2\2\u0206\u0207\7U\2\2\u0207N\3\2\2\2\u0208\u0209\7I\2"+ - "\2\u0209\u020a\7T\2\2\u020a\u020b\7C\2\2\u020b\u020c\7R\2\2\u020c\u020d"+ - "\7J\2\2\u020d\u020e\7X\2\2\u020e\u020f\7K\2\2\u020f\u0210\7\\\2\2\u0210"+ - "P\3\2\2\2\u0211\u0212\7I\2\2\u0212\u0213\7T\2\2\u0213\u0214\7Q\2\2\u0214"+ - "\u0215\7W\2\2\u0215\u0216\7R\2\2\u0216R\3\2\2\2\u0217\u0218\7J\2\2\u0218"+ - "\u0219\7C\2\2\u0219\u021a\7X\2\2\u021a\u021b\7K\2\2\u021b\u021c\7P\2\2"+ - "\u021c\u021d\7I\2\2\u021dT\3\2\2\2\u021e\u021f\7J\2\2\u021f\u0220\7Q\2"+ - "\2\u0220\u0221\7W\2\2\u0221\u0222\7T\2\2\u0222V\3\2\2\2\u0223\u0224\7"+ - "J\2\2\u0224\u0225\7Q\2\2\u0225\u0226\7W\2\2\u0226\u0227\7T\2\2\u0227\u0228"+ - "\7U\2\2\u0228X\3\2\2\2\u0229\u022a\7K\2\2\u022a\u022b\7P\2\2\u022bZ\3"+ - "\2\2\2\u022c\u022d\7K\2\2\u022d\u022e\7P\2\2\u022e\u022f\7P\2\2\u022f"+ - "\u0230\7G\2\2\u0230\u0231\7T\2\2\u0231\\\3\2\2\2\u0232\u0233\7K\2\2\u0233"+ - "\u0234\7P\2\2\u0234\u0235\7V\2\2\u0235\u0236\7G\2\2\u0236\u0237\7T\2\2"+ - "\u0237\u0238\7X\2\2\u0238\u0239\7C\2\2\u0239\u023a\7N\2\2\u023a^\3\2\2"+ - "\2\u023b\u023c\7K\2\2\u023c\u023d\7U\2\2\u023d`\3\2\2\2\u023e\u023f\7"+ - "L\2\2\u023f\u0240\7Q\2\2\u0240\u0241\7K\2\2\u0241\u0242\7P\2\2\u0242b"+ - "\3\2\2\2\u0243\u0244\7N\2\2\u0244\u0245\7C\2\2\u0245\u0246\7U\2\2\u0246"+ - "\u0247\7V\2\2\u0247d\3\2\2\2\u0248\u0249\7N\2\2\u0249\u024a\7G\2\2\u024a"+ - "\u024b\7H\2\2\u024b\u024c\7V\2\2\u024cf\3\2\2\2\u024d\u024e\7N\2\2\u024e"+ - "\u024f\7K\2\2\u024f\u0250\7M\2\2\u0250\u0251\7G\2\2\u0251h\3\2\2\2\u0252"+ - "\u0253\7N\2\2\u0253\u0254\7K\2\2\u0254\u0255\7O\2\2\u0255\u0256\7K\2\2"+ - "\u0256\u0257\7V\2\2\u0257j\3\2\2\2\u0258\u0259\7O\2\2\u0259\u025a\7C\2"+ - "\2\u025a\u025b\7R\2\2\u025b\u025c\7R\2\2\u025c\u025d\7G\2\2\u025d\u025e"+ - "\7F\2\2\u025el\3\2\2\2\u025f\u0260\7O\2\2\u0260\u0261\7C\2\2\u0261\u0262"+ - "\7V\2\2\u0262\u0263\7E\2\2\u0263\u0264\7J\2\2\u0264n\3\2\2\2\u0265\u0266"+ - "\7O\2\2\u0266\u0267\7K\2\2\u0267\u0268\7P\2\2\u0268\u0269\7W\2\2\u0269"+ - "\u026a\7V\2\2\u026a\u026b\7G\2\2\u026bp\3\2\2\2\u026c\u026d\7O\2\2\u026d"+ - "\u026e\7K\2\2\u026e\u026f\7P\2\2\u026f\u0270\7W\2\2\u0270\u0271\7V\2\2"+ - "\u0271\u0272\7G\2\2\u0272\u0273\7U\2\2\u0273r\3\2\2\2\u0274\u0275\7O\2"+ - "\2\u0275\u0276\7Q\2\2\u0276\u0277\7P\2\2\u0277\u0278\7V\2\2\u0278\u0279"+ - "\7J\2\2\u0279t\3\2\2\2\u027a\u027b\7O\2\2\u027b\u027c\7Q\2\2\u027c\u027d"+ - "\7P\2\2\u027d\u027e\7V\2\2\u027e\u027f\7J\2\2\u027f\u0280\7U\2\2\u0280"+ - "v\3\2\2\2\u0281\u0282\7P\2\2\u0282\u0283\7C\2\2\u0283\u0284\7V\2\2\u0284"+ - "\u0285\7W\2\2\u0285\u0286\7T\2\2\u0286\u0287\7C\2\2\u0287\u0288\7N\2\2"+ - "\u0288x\3\2\2\2\u0289\u028a\7P\2\2\u028a\u028b\7Q\2\2\u028b\u028c\7V\2"+ - "\2\u028cz\3\2\2\2\u028d\u028e\7P\2\2\u028e\u028f\7W\2\2\u028f\u0290\7"+ - "N\2\2\u0290\u0291\7N\2\2\u0291|\3\2\2\2\u0292\u0293\7P\2\2\u0293\u0294"+ - "\7W\2\2\u0294\u0295\7N\2\2\u0295\u0296\7N\2\2\u0296\u0297\7U\2\2\u0297"+ - "~\3\2\2\2\u0298\u0299\7Q\2\2\u0299\u029a\7P\2\2\u029a\u0080\3\2\2\2\u029b"+ - "\u029c\7Q\2\2\u029c\u029d\7R\2\2\u029d\u029e\7V\2\2\u029e\u029f\7K\2\2"+ - "\u029f\u02a0\7O\2\2\u02a0\u02a1\7K\2\2\u02a1\u02a2\7\\\2\2\u02a2\u02a3"+ - "\7G\2\2\u02a3\u02a4\7F\2\2\u02a4\u0082\3\2\2\2\u02a5\u02a6\7Q\2\2\u02a6"+ - "\u02a7\7T\2\2\u02a7\u0084\3\2\2\2\u02a8\u02a9\7Q\2\2\u02a9\u02aa\7T\2"+ - "\2\u02aa\u02ab\7F\2\2\u02ab\u02ac\7G\2\2\u02ac\u02ad\7T\2\2\u02ad\u0086"+ - "\3\2\2\2\u02ae\u02af\7Q\2\2\u02af\u02b0\7W\2\2\u02b0\u02b1\7V\2\2\u02b1"+ - "\u02b2\7G\2\2\u02b2\u02b3\7T\2\2\u02b3\u0088\3\2\2\2\u02b4\u02b5\7R\2"+ - "\2\u02b5\u02b6\7C\2\2\u02b6\u02b7\7T\2\2\u02b7\u02b8\7U\2\2\u02b8\u02b9"+ - "\7G\2\2\u02b9\u02ba\7F\2\2\u02ba\u008a\3\2\2\2\u02bb\u02bc\7R\2\2\u02bc"+ - "\u02bd\7J\2\2\u02bd\u02be\7[\2\2\u02be\u02bf\7U\2\2\u02bf\u02c0\7K\2\2"+ - "\u02c0\u02c1\7E\2\2\u02c1\u02c2\7C\2\2\u02c2\u02c3\7N\2\2\u02c3\u008c"+ - "\3\2\2\2\u02c4\u02c5\7R\2\2\u02c5\u02c6\7N\2\2\u02c6\u02c7\7C\2\2\u02c7"+ - "\u02c8\7P\2\2\u02c8\u008e\3\2\2\2\u02c9\u02ca\7T\2\2\u02ca\u02cb\7K\2"+ - "\2\u02cb\u02cc\7I\2\2\u02cc\u02cd\7J\2\2\u02cd\u02ce\7V\2\2\u02ce\u0090"+ - "\3\2\2\2\u02cf\u02d0\7T\2\2\u02d0\u02d1\7N\2\2\u02d1\u02d2\7K\2\2\u02d2"+ - "\u02d3\7M\2\2\u02d3\u02d4\7G\2\2\u02d4\u0092\3\2\2\2\u02d5\u02d6\7S\2"+ - "\2\u02d6\u02d7\7W\2\2\u02d7\u02d8\7G\2\2\u02d8\u02d9\7T\2\2\u02d9\u02da"+ - "\7[\2\2\u02da\u0094\3\2\2\2\u02db\u02dc\7U\2\2\u02dc\u02dd\7E\2\2\u02dd"+ - "\u02de\7J\2\2\u02de\u02df\7G\2\2\u02df\u02e0\7O\2\2\u02e0\u02e1\7C\2\2"+ - "\u02e1\u02e2\7U\2\2\u02e2\u0096\3\2\2\2\u02e3\u02e4\7U\2\2\u02e4\u02e5"+ - "\7G\2\2\u02e5\u02e6\7E\2\2\u02e6\u02e7\7Q\2\2\u02e7\u02e8\7P\2\2\u02e8"+ - "\u02e9\7F\2\2\u02e9\u0098\3\2\2\2\u02ea\u02eb\7U\2\2\u02eb\u02ec\7G\2"+ - "\2\u02ec\u02ed\7E\2\2\u02ed\u02ee\7Q\2\2\u02ee\u02ef\7P\2\2\u02ef\u02f0"+ - "\7F\2\2\u02f0\u02f1\7U\2\2\u02f1\u009a\3\2\2\2\u02f2\u02f3\7U\2\2\u02f3"+ - "\u02f4\7G\2\2\u02f4\u02f5\7N\2\2\u02f5\u02f6\7G\2\2\u02f6\u02f7\7E\2\2"+ - "\u02f7\u02f8\7V\2\2\u02f8\u009c\3\2\2\2\u02f9\u02fa\7U\2\2\u02fa\u02fb"+ - "\7J\2\2\u02fb\u02fc\7Q\2\2\u02fc\u02fd\7Y\2\2\u02fd\u009e\3\2\2\2\u02fe"+ - "\u02ff\7U\2\2\u02ff\u0300\7[\2\2\u0300\u0301\7U\2\2\u0301\u00a0\3\2\2"+ - "\2\u0302\u0303\7V\2\2\u0303\u0304\7C\2\2\u0304\u0305\7D\2\2\u0305\u0306"+ - "\7N\2\2\u0306\u0307\7G\2\2\u0307\u00a2\3\2\2\2\u0308\u0309\7V\2\2\u0309"+ - "\u030a\7C\2\2\u030a\u030b\7D\2\2\u030b\u030c\7N\2\2\u030c\u030d\7G\2\2"+ - "\u030d\u030e\7U\2\2\u030e\u00a4\3\2\2\2\u030f\u0310\7V\2\2\u0310\u0311"+ - "\7G\2\2\u0311\u0312\7Z\2\2\u0312\u0313\7V\2\2\u0313\u00a6\3\2\2\2\u0314"+ - "\u0315\7V\2\2\u0315\u0316\7T\2\2\u0316\u0317\7W\2\2\u0317\u0318\7G\2\2"+ - "\u0318\u00a8\3\2\2\2\u0319\u031a\7V\2\2\u031a\u031b\7Q\2\2\u031b\u00aa"+ - "\3\2\2\2\u031c\u031d\7V\2\2\u031d\u031e\7[\2\2\u031e\u031f\7R\2\2\u031f"+ - "\u0320\7G\2\2\u0320\u00ac\3\2\2\2\u0321\u0322\7V\2\2\u0322\u0323\7[\2"+ - "\2\u0323\u0324\7R\2\2\u0324\u0325\7G\2\2\u0325\u0326\7U\2\2\u0326\u00ae"+ - "\3\2\2\2\u0327\u0328\7W\2\2\u0328\u0329\7U\2\2\u0329\u032a\7K\2\2\u032a"+ - "\u032b\7P\2\2\u032b\u032c\7I\2\2\u032c\u00b0\3\2\2\2\u032d\u032e\7X\2"+ - "\2\u032e\u032f\7G\2\2\u032f\u0330\7T\2\2\u0330\u0331\7K\2\2\u0331\u0332"+ - "\7H\2\2\u0332\u0333\7[\2\2\u0333\u00b2\3\2\2\2\u0334\u0335\7Y\2\2\u0335"+ - "\u0336\7J\2\2\u0336\u0337\7G\2\2\u0337\u0338\7T\2\2\u0338\u0339\7G\2\2"+ - "\u0339\u00b4\3\2\2\2\u033a\u033b\7Y\2\2\u033b\u033c\7K\2\2\u033c\u033d"+ - "\7V\2\2\u033d\u033e\7J\2\2\u033e\u00b6\3\2\2\2\u033f\u0340\7[\2\2\u0340"+ - "\u0341\7G\2\2\u0341\u0342\7C\2\2\u0342\u0343\7T\2\2\u0343\u00b8\3\2\2"+ - "\2\u0344\u0345\7[\2\2\u0345\u0346\7G\2\2\u0346\u0347\7C\2\2\u0347\u0348"+ - "\7T\2\2\u0348\u0349\7U\2\2\u0349\u00ba\3\2\2\2\u034a\u034b\7}\2\2\u034b"+ - "\u034c\7G\2\2\u034c\u034d\7U\2\2\u034d\u034e\7E\2\2\u034e\u034f\7C\2\2"+ - "\u034f\u0350\7R\2\2\u0350\u0351\7G\2\2\u0351\u00bc\3\2\2\2\u0352\u0353"+ - "\7}\2\2\u0353\u0354\7H\2\2\u0354\u0355\7P\2\2\u0355\u00be\3\2\2\2\u0356"+ - "\u0357\7}\2\2\u0357\u0358\7N\2\2\u0358\u0359\7K\2\2\u0359\u035a\7O\2\2"+ - "\u035a\u035b\7K\2\2\u035b\u035c\7V\2\2\u035c\u00c0\3\2\2\2\u035d\u035e"+ - "\7}\2\2\u035e\u035f\7F\2\2\u035f\u00c2\3\2\2\2\u0360\u0361\7}\2\2\u0361"+ - "\u0362\7V\2\2\u0362\u00c4\3\2\2\2\u0363\u0364\7}\2\2\u0364\u0365\7V\2"+ - "\2\u0365\u0366\7U\2\2\u0366\u00c6\3\2\2\2\u0367\u0368\7}\2\2\u0368\u0369"+ - "\7I\2\2\u0369\u036a\7W\2\2\u036a\u036b\7K\2\2\u036b\u036c\7F\2\2\u036c"+ - "\u00c8\3\2\2\2\u036d\u036e\7\177\2\2\u036e\u00ca\3\2\2\2\u036f\u0370\7"+ - "?\2\2\u0370\u00cc\3\2\2\2\u0371\u0372\7>\2\2\u0372\u0373\7?\2\2\u0373"+ - "\u0374\7@\2\2\u0374\u00ce\3\2\2\2\u0375\u0376\7>\2\2\u0376\u037a\7@\2"+ - "\2\u0377\u0378\7#\2\2\u0378\u037a\7?\2\2\u0379\u0375\3\2\2\2\u0379\u0377"+ - "\3\2\2\2\u037a\u00d0\3\2\2\2\u037b\u037c\7>\2\2\u037c\u00d2\3\2\2\2\u037d"+ - "\u037e\7>\2\2\u037e\u037f\7?\2\2\u037f\u00d4\3\2\2\2\u0380\u0381\7@\2"+ - "\2\u0381\u00d6\3\2\2\2\u0382\u0383\7@\2\2\u0383\u0384\7?\2\2\u0384\u00d8"+ - "\3\2\2\2\u0385\u0386\7-\2\2\u0386\u00da\3\2\2\2\u0387\u0388\7/\2\2\u0388"+ - "\u00dc\3\2\2\2\u0389\u038a\7,\2\2\u038a\u00de\3\2\2\2\u038b\u038c\7\61"+ - "\2\2\u038c\u00e0\3\2\2\2\u038d\u038e\7\'\2\2\u038e\u00e2\3\2\2\2\u038f"+ - "\u0390\7<\2\2\u0390\u0391\7<\2\2\u0391\u00e4\3\2\2\2\u0392\u0393\7~\2"+ - "\2\u0393\u0394\7~\2\2\u0394\u00e6\3\2\2\2\u0395\u0396\7\60\2\2\u0396\u00e8"+ - "\3\2\2\2\u0397\u0398\7A\2\2\u0398\u00ea\3\2\2\2\u0399\u039f\7)\2\2\u039a"+ - "\u039e\n\2\2\2\u039b\u039c\7)\2\2\u039c\u039e\7)\2\2\u039d\u039a\3\2\2"+ - "\2\u039d\u039b\3\2\2\2\u039e\u03a1\3\2\2\2\u039f\u039d\3\2\2\2\u039f\u03a0"+ - "\3\2\2\2\u03a0\u03a2\3\2\2\2\u03a1\u039f\3\2\2\2\u03a2\u03a3\7)\2\2\u03a3"+ - "\u00ec\3\2\2\2\u03a4\u03a6\5\u00fd\177\2\u03a5\u03a4\3\2\2\2\u03a6\u03a7"+ - "\3\2\2\2\u03a7\u03a5\3\2\2\2\u03a7\u03a8\3\2\2\2\u03a8\u00ee\3\2\2\2\u03a9"+ - "\u03ab\5\u00fd\177\2\u03aa\u03a9\3\2\2\2\u03ab\u03ac\3\2\2\2\u03ac\u03aa"+ - "\3\2\2\2\u03ac\u03ad\3\2\2\2\u03ad\u03ae\3\2\2\2\u03ae\u03b2\5\u00e7t"+ - "\2\u03af\u03b1\5\u00fd\177\2\u03b0\u03af\3\2\2\2\u03b1\u03b4\3\2\2\2\u03b2"+ - "\u03b0\3\2\2\2\u03b2\u03b3\3\2\2\2\u03b3\u03d4\3\2\2\2\u03b4\u03b2\3\2"+ - "\2\2\u03b5\u03b7\5\u00e7t\2\u03b6\u03b8\5\u00fd\177\2\u03b7\u03b6\3\2"+ - "\2\2\u03b8\u03b9\3\2\2\2\u03b9\u03b7\3\2\2\2\u03b9\u03ba\3\2\2\2\u03ba"+ - "\u03d4\3\2\2\2\u03bb\u03bd\5\u00fd\177\2\u03bc\u03bb\3\2\2\2\u03bd\u03be"+ - "\3\2\2\2\u03be\u03bc\3\2\2\2\u03be\u03bf\3\2\2\2\u03bf\u03c7\3\2\2\2\u03c0"+ - "\u03c4\5\u00e7t\2\u03c1\u03c3\5\u00fd\177\2\u03c2\u03c1\3\2\2\2\u03c3"+ - "\u03c6\3\2\2\2\u03c4\u03c2\3\2\2\2\u03c4\u03c5\3\2\2\2\u03c5\u03c8\3\2"+ - "\2\2\u03c6\u03c4\3\2\2\2\u03c7\u03c0\3\2\2\2\u03c7\u03c8\3\2\2\2\u03c8"+ - "\u03c9\3\2\2\2\u03c9\u03ca\5\u00fb~\2\u03ca\u03d4\3\2\2\2\u03cb\u03cd"+ - "\5\u00e7t\2\u03cc\u03ce\5\u00fd\177\2\u03cd\u03cc\3\2\2\2\u03ce\u03cf"+ - "\3\2\2\2\u03cf\u03cd\3\2\2\2\u03cf\u03d0\3\2\2\2\u03d0\u03d1\3\2\2\2\u03d1"+ - "\u03d2\5\u00fb~\2\u03d2\u03d4\3\2\2\2\u03d3\u03aa\3\2\2\2\u03d3\u03b5"+ - "\3\2\2\2\u03d3\u03bc\3\2\2\2\u03d3\u03cb\3\2\2\2\u03d4\u00f0\3\2\2\2\u03d5"+ - "\u03d8\5\u00ff\u0080\2\u03d6\u03d8\7a\2\2\u03d7\u03d5\3\2\2\2\u03d7\u03d6"+ - "\3\2\2\2\u03d8\u03de\3\2\2\2\u03d9\u03dd\5\u00ff\u0080\2\u03da\u03dd\5"+ - "\u00fd\177\2\u03db\u03dd\t\3\2\2\u03dc\u03d9\3\2\2\2\u03dc\u03da\3\2\2"+ - "\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\u03df\u00f2\3\2\2\2\u03e0\u03de\3\2\2\2\u03e1\u03e5\5\u00fd\177"+ - "\2\u03e2\u03e6\5\u00ff\u0080\2\u03e3\u03e6\5\u00fd\177\2\u03e4\u03e6\t"+ - "\3\2\2\u03e5\u03e2\3\2\2\2\u03e5\u03e3\3\2\2\2\u03e5\u03e4\3\2\2\2\u03e6"+ - "\u03e7\3\2\2\2\u03e7\u03e5\3\2\2\2\u03e7\u03e8\3\2\2\2\u03e8\u00f4\3\2"+ - "\2\2\u03e9\u03ed\5\u00ff\u0080\2\u03ea\u03ed\5\u00fd\177\2\u03eb\u03ed"+ - "\7a\2\2\u03ec\u03e9\3\2\2\2\u03ec\u03ea\3\2\2\2\u03ec\u03eb\3\2\2\2\u03ed"+ - "\u03ee\3\2\2\2\u03ee\u03ec\3\2\2\2\u03ee\u03ef\3\2\2\2\u03ef\u00f6\3\2"+ - "\2\2\u03f0\u03f6\7$\2\2\u03f1\u03f5\n\4\2\2\u03f2\u03f3\7$\2\2\u03f3\u03f5"+ - "\7$\2\2\u03f4\u03f1\3\2\2\2\u03f4\u03f2\3\2\2\2\u03f5\u03f8\3\2\2\2\u03f6"+ - "\u03f4\3\2\2\2\u03f6\u03f7\3\2\2\2\u03f7\u03f9\3\2\2\2\u03f8\u03f6\3\2"+ - "\2\2\u03f9\u03fa\7$\2\2\u03fa\u00f8\3\2\2\2\u03fb\u0401\7b\2\2\u03fc\u0400"+ - "\n\5\2\2\u03fd\u03fe\7b\2\2\u03fe\u0400\7b\2\2\u03ff\u03fc\3\2\2\2\u03ff"+ - "\u03fd\3\2\2\2\u0400\u0403\3\2\2\2\u0401\u03ff\3\2\2\2\u0401\u0402\3\2"+ - "\2\2\u0402\u0404\3\2\2\2\u0403\u0401\3\2\2\2\u0404\u0405\7b\2\2\u0405"+ - "\u00fa\3\2\2\2\u0406\u0408\7G\2\2\u0407\u0409\t\6\2\2\u0408\u0407\3\2"+ - "\2\2\u0408\u0409\3\2\2\2\u0409\u040b\3\2\2\2\u040a\u040c\5\u00fd\177\2"+ - "\u040b\u040a\3\2\2\2\u040c\u040d\3\2\2\2\u040d\u040b\3\2\2\2\u040d\u040e"+ - "\3\2\2\2\u040e\u00fc\3\2\2\2\u040f\u0410\t\7\2\2\u0410\u00fe\3\2\2\2\u0411"+ - "\u0412\t\b\2\2\u0412\u0100\3\2\2\2\u0413\u0414\7/\2\2\u0414\u0415\7/\2"+ - "\2\u0415\u0419\3\2\2\2\u0416\u0418\n\t\2\2\u0417\u0416\3\2\2\2\u0418\u041b"+ - "\3\2\2\2\u0419\u0417\3\2\2\2\u0419\u041a\3\2\2\2\u041a\u041d\3\2\2\2\u041b"+ - "\u0419\3\2\2\2\u041c\u041e\7\17\2\2\u041d\u041c\3\2\2\2\u041d\u041e\3"+ - "\2\2\2\u041e\u0420\3\2\2\2\u041f\u0421\7\f\2\2\u0420\u041f\3\2\2\2\u0420"+ - "\u0421\3\2\2\2\u0421\u0422\3\2\2\2\u0422\u0423\b\u0081\2\2\u0423\u0102"+ - "\3\2\2\2\u0424\u0425\7\61\2\2\u0425\u0426\7,\2\2\u0426\u042b\3\2\2\2\u0427"+ - "\u042a\5\u0103\u0082\2\u0428\u042a\13\2\2\2\u0429\u0427\3\2\2\2\u0429"+ - "\u0428\3\2\2\2\u042a\u042d\3\2\2\2\u042b\u042c\3\2\2\2\u042b\u0429\3\2"+ - "\2\2\u042c\u042e\3\2\2\2\u042d\u042b\3\2\2\2\u042e\u042f\7,\2\2\u042f"+ - "\u0430\7\61\2\2\u0430\u0431\3\2\2\2\u0431\u0432\b\u0082\2\2\u0432\u0104"+ - "\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"; + "z\u00f3{\u00f5|\u00f7}\u00f9~\u00fb\177\u00fd\u0080\u00ff\u0081\u0101"+ + "\u0082\u0103\u0083\u0105\2\u0107\2\u0109\2\u010b\u0084\u010d\u0085\u010f"+ + "\u0086\u0111\u0087\3\2\13\3\2))\4\2BBaa\3\2$$\3\2bb\4\2--//\3\2\62;\3"+ + "\2C\\\4\2\f\f\17\17\5\2\13\f\17\17\"\"\u047e\2\3\3\2\2\2\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\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\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\'\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\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\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\2K\3\2\2\2\2"+ + "M\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\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\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\2q\3\2\2\2\2"+ + "s\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\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\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\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\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\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\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\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\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\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\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\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\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\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\3\2\2"+ + "\2\2\u00f5\3\2\2\2\2\u00f7\3\2\2\2\2\u00f9\3\2\2\2\2\u00fb\3\2\2\2\2\u00fd"+ + "\3\2\2\2\2\u00ff\3\2\2\2\2\u0101\3\2\2\2\2\u0103\3\2\2\2\2\u010b\3\2\2"+ + "\2\2\u010d\3\2\2\2\2\u010f\3\2\2\2\2\u0111\3\2\2\2\3\u0113\3\2\2\2\5\u0115"+ + "\3\2\2\2\7\u0117\3\2\2\2\t\u0119\3\2\2\2\13\u011b\3\2\2\2\r\u011f\3\2"+ + "\2\2\17\u0127\3\2\2\2\21\u0130\3\2\2\2\23\u0134\3\2\2\2\25\u0138\3\2\2"+ + "\2\27\u013b\3\2\2\2\31\u013f\3\2\2\2\33\u0147\3\2\2\2\35\u014a\3\2\2\2"+ + "\37\u014f\3\2\2\2!\u0154\3\2\2\2#\u015c\3\2\2\2%\u0165\3\2\2\2\'\u016d"+ + "\3\2\2\2)\u0175\3\2\2\2+\u0182\3\2\2\2-\u018f\3\2\2\2/\u01a1\3\2\2\2\61"+ + "\u01a5\3\2\2\2\63\u01aa\3\2\2\2\65\u01b0\3\2\2\2\67\u01b5\3\2\2\29\u01be"+ + "\3\2\2\2;\u01c7\3\2\2\2=\u01cc\3\2\2\2?\u01d0\3\2\2\2A\u01d7\3\2\2\2C"+ + "\u01e2\3\2\2\2E\u01e9\3\2\2\2G\u01f1\3\2\2\2I\u01f9\3\2\2\2K\u01ff\3\2"+ + "\2\2M\u0205\3\2\2\2O\u020c\3\2\2\2Q\u0211\3\2\2\2S\u0216\3\2\2\2U\u0220"+ + "\3\2\2\2W\u0229\3\2\2\2Y\u022f\3\2\2\2[\u0236\3\2\2\2]\u023b\3\2\2\2_"+ + "\u0241\3\2\2\2a\u0244\3\2\2\2c\u024a\3\2\2\2e\u0253\3\2\2\2g\u0256\3\2"+ + "\2\2i\u025b\3\2\2\2k\u0260\3\2\2\2m\u0265\3\2\2\2o\u026a\3\2\2\2q\u0270"+ + "\3\2\2\2s\u0277\3\2\2\2u\u027d\3\2\2\2w\u0284\3\2\2\2y\u028c\3\2\2\2{"+ + "\u0292\3\2\2\2}\u0299\3\2\2\2\177\u02a1\3\2\2\2\u0081\u02a5\3\2\2\2\u0083"+ + "\u02aa\3\2\2\2\u0085\u02b0\3\2\2\2\u0087\u02b3\3\2\2\2\u0089\u02bd\3\2"+ + "\2\2\u008b\u02c0\3\2\2\2\u008d\u02c6\3\2\2\2\u008f\u02cc\3\2\2\2\u0091"+ + "\u02d3\3\2\2\2\u0093\u02dc\3\2\2\2\u0095\u02e1\3\2\2\2\u0097\u02e7\3\2"+ + "\2\2\u0099\u02ed\3\2\2\2\u009b\u02f3\3\2\2\2\u009d\u02fb\3\2\2\2\u009f"+ + "\u0302\3\2\2\2\u00a1\u030a\3\2\2\2\u00a3\u0311\3\2\2\2\u00a5\u0316\3\2"+ + "\2\2\u00a7\u031a\3\2\2\2\u00a9\u0320\3\2\2\2\u00ab\u0327\3\2\2\2\u00ad"+ + "\u032c\3\2\2\2\u00af\u0331\3\2\2\2\u00b1\u0336\3\2\2\2\u00b3\u0339\3\2"+ + "\2\2\u00b5\u033e\3\2\2\2\u00b7\u0344\3\2\2\2\u00b9\u034a\3\2\2\2\u00bb"+ + "\u0351\3\2\2\2\u00bd\u0356\3\2\2\2\u00bf\u035c\3\2\2\2\u00c1\u0361\3\2"+ + "\2\2\u00c3\u0366\3\2\2\2\u00c5\u036c\3\2\2\2\u00c7\u0374\3\2\2\2\u00c9"+ + "\u0378\3\2\2\2\u00cb\u037f\3\2\2\2\u00cd\u0382\3\2\2\2\u00cf\u0385\3\2"+ + "\2\2\u00d1\u0389\3\2\2\2\u00d3\u038f\3\2\2\2\u00d5\u0391\3\2\2\2\u00d7"+ + "\u0393\3\2\2\2\u00d9\u039b\3\2\2\2\u00db\u039d\3\2\2\2\u00dd\u039f\3\2"+ + "\2\2\u00df\u03a2\3\2\2\2\u00e1\u03a4\3\2\2\2\u00e3\u03a7\3\2\2\2\u00e5"+ + "\u03a9\3\2\2\2\u00e7\u03ab\3\2\2\2\u00e9\u03ad\3\2\2\2\u00eb\u03af\3\2"+ + "\2\2\u00ed\u03b1\3\2\2\2\u00ef\u03b4\3\2\2\2\u00f1\u03b7\3\2\2\2\u00f3"+ + "\u03b9\3\2\2\2\u00f5\u03bb\3\2\2\2\u00f7\u03c7\3\2\2\2\u00f9\u03f5\3\2"+ + "\2\2\u00fb\u03f9\3\2\2\2\u00fd\u0403\3\2\2\2\u00ff\u040e\3\2\2\2\u0101"+ + "\u0412\3\2\2\2\u0103\u041d\3\2\2\2\u0105\u0428\3\2\2\2\u0107\u0431\3\2"+ + "\2\2\u0109\u0433\3\2\2\2\u010b\u0435\3\2\2\2\u010d\u0446\3\2\2\2\u010f"+ + "\u0456\3\2\2\2\u0111\u045c\3\2\2\2\u0113\u0114\7*\2\2\u0114\4\3\2\2\2"+ + "\u0115\u0116\7+\2\2\u0116\6\3\2\2\2\u0117\u0118\7.\2\2\u0118\b\3\2\2\2"+ + "\u0119\u011a\7<\2\2\u011a\n\3\2\2\2\u011b\u011c\7C\2\2\u011c\u011d\7N"+ + "\2\2\u011d\u011e\7N\2\2\u011e\f\3\2\2\2\u011f\u0120\7C\2\2\u0120\u0121"+ + "\7P\2\2\u0121\u0122\7C\2\2\u0122\u0123\7N\2\2\u0123\u0124\7[\2\2\u0124"+ + "\u0125\7\\\2\2\u0125\u0126\7G\2\2\u0126\16\3\2\2\2\u0127\u0128\7C\2\2"+ + "\u0128\u0129\7P\2\2\u0129\u012a\7C\2\2\u012a\u012b\7N\2\2\u012b\u012c"+ + "\7[\2\2\u012c\u012d\7\\\2\2\u012d\u012e\7G\2\2\u012e\u012f\7F\2\2\u012f"+ + "\20\3\2\2\2\u0130\u0131\7C\2\2\u0131\u0132\7P\2\2\u0132\u0133\7F\2\2\u0133"+ + "\22\3\2\2\2\u0134\u0135\7C\2\2\u0135\u0136\7P\2\2\u0136\u0137\7[\2\2\u0137"+ + "\24\3\2\2\2\u0138\u0139\7C\2\2\u0139\u013a\7U\2\2\u013a\26\3\2\2\2\u013b"+ + "\u013c\7C\2\2\u013c\u013d\7U\2\2\u013d\u013e\7E\2\2\u013e\30\3\2\2\2\u013f"+ + "\u0140\7D\2\2\u0140\u0141\7G\2\2\u0141\u0142\7V\2\2\u0142\u0143\7Y\2\2"+ + "\u0143\u0144\7G\2\2\u0144\u0145\7G\2\2\u0145\u0146\7P\2\2\u0146\32\3\2"+ + "\2\2\u0147\u0148\7D\2\2\u0148\u0149\7[\2\2\u0149\34\3\2\2\2\u014a\u014b"+ + "\7E\2\2\u014b\u014c\7C\2\2\u014c\u014d\7U\2\2\u014d\u014e\7G\2\2\u014e"+ + "\36\3\2\2\2\u014f\u0150\7E\2\2\u0150\u0151\7C\2\2\u0151\u0152\7U\2\2\u0152"+ + "\u0153\7V\2\2\u0153 \3\2\2\2\u0154\u0155\7E\2\2\u0155\u0156\7C\2\2\u0156"+ + "\u0157\7V\2\2\u0157\u0158\7C\2\2\u0158\u0159\7N\2\2\u0159\u015a\7Q\2\2"+ + "\u015a\u015b\7I\2\2\u015b\"\3\2\2\2\u015c\u015d\7E\2\2\u015d\u015e\7C"+ + "\2\2\u015e\u015f\7V\2\2\u015f\u0160\7C\2\2\u0160\u0161\7N\2\2\u0161\u0162"+ + "\7Q\2\2\u0162\u0163\7I\2\2\u0163\u0164\7U\2\2\u0164$\3\2\2\2\u0165\u0166"+ + "\7E\2\2\u0166\u0167\7Q\2\2\u0167\u0168\7N\2\2\u0168\u0169\7W\2\2\u0169"+ + "\u016a\7O\2\2\u016a\u016b\7P\2\2\u016b\u016c\7U\2\2\u016c&\3\2\2\2\u016d"+ + "\u016e\7E\2\2\u016e\u016f\7Q\2\2\u016f\u0170\7P\2\2\u0170\u0171\7X\2\2"+ + "\u0171\u0172\7G\2\2\u0172\u0173\7T\2\2\u0173\u0174\7V\2\2\u0174(\3\2\2"+ + "\2\u0175\u0176\7E\2\2\u0176\u0177\7W\2\2\u0177\u0178\7T\2\2\u0178\u0179"+ + "\7T\2\2\u0179\u017a\7G\2\2\u017a\u017b\7P\2\2\u017b\u017c\7V\2\2\u017c"+ + "\u017d\7a\2\2\u017d\u017e\7F\2\2\u017e\u017f\7C\2\2\u017f\u0180\7V\2\2"+ + "\u0180\u0181\7G\2\2\u0181*\3\2\2\2\u0182\u0183\7E\2\2\u0183\u0184\7W\2"+ + "\2\u0184\u0185\7T\2\2\u0185\u0186\7T\2\2\u0186\u0187\7G\2\2\u0187\u0188"+ + "\7P\2\2\u0188\u0189\7V\2\2\u0189\u018a\7a\2\2\u018a\u018b\7V\2\2\u018b"+ + "\u018c\7K\2\2\u018c\u018d\7O\2\2\u018d\u018e\7G\2\2\u018e,\3\2\2\2\u018f"+ + "\u0190\7E\2\2\u0190\u0191\7W\2\2\u0191\u0192\7T\2\2\u0192\u0193\7T\2\2"+ + "\u0193\u0194\7G\2\2\u0194\u0195\7P\2\2\u0195\u0196\7V\2\2\u0196\u0197"+ + "\7a\2\2\u0197\u0198\7V\2\2\u0198\u0199\7K\2\2\u0199\u019a\7O\2\2\u019a"+ + "\u019b\7G\2\2\u019b\u019c\7U\2\2\u019c\u019d\7V\2\2\u019d\u019e\7C\2\2"+ + "\u019e\u019f\7O\2\2\u019f\u01a0\7R\2\2\u01a0.\3\2\2\2\u01a1\u01a2\7F\2"+ + "\2\u01a2\u01a3\7C\2\2\u01a3\u01a4\7[\2\2\u01a4\60\3\2\2\2\u01a5\u01a6"+ + "\7F\2\2\u01a6\u01a7\7C\2\2\u01a7\u01a8\7[\2\2\u01a8\u01a9\7U\2\2\u01a9"+ + "\62\3\2\2\2\u01aa\u01ab\7F\2\2\u01ab\u01ac\7G\2\2\u01ac\u01ad\7D\2\2\u01ad"+ + "\u01ae\7W\2\2\u01ae\u01af\7I\2\2\u01af\64\3\2\2\2\u01b0\u01b1\7F\2\2\u01b1"+ + "\u01b2\7G\2\2\u01b2\u01b3\7U\2\2\u01b3\u01b4\7E\2\2\u01b4\66\3\2\2\2\u01b5"+ + "\u01b6\7F\2\2\u01b6\u01b7\7G\2\2\u01b7\u01b8\7U\2\2\u01b8\u01b9\7E\2\2"+ + "\u01b9\u01ba\7T\2\2\u01ba\u01bb\7K\2\2\u01bb\u01bc\7D\2\2\u01bc\u01bd"+ + "\7G\2\2\u01bd8\3\2\2\2\u01be\u01bf\7F\2\2\u01bf\u01c0\7K\2\2\u01c0\u01c1"+ + "\7U\2\2\u01c1\u01c2\7V\2\2\u01c2\u01c3\7K\2\2\u01c3\u01c4\7P\2\2\u01c4"+ + "\u01c5\7E\2\2\u01c5\u01c6\7V\2\2\u01c6:\3\2\2\2\u01c7\u01c8\7G\2\2\u01c8"+ + "\u01c9\7N\2\2\u01c9\u01ca\7U\2\2\u01ca\u01cb\7G\2\2\u01cb<\3\2\2\2\u01cc"+ + "\u01cd\7G\2\2\u01cd\u01ce\7P\2\2\u01ce\u01cf\7F\2\2\u01cf>\3\2\2\2\u01d0"+ + "\u01d1\7G\2\2\u01d1\u01d2\7U\2\2\u01d2\u01d3\7E\2\2\u01d3\u01d4\7C\2\2"+ + "\u01d4\u01d5\7R\2\2\u01d5\u01d6\7G\2\2\u01d6@\3\2\2\2\u01d7\u01d8\7G\2"+ + "\2\u01d8\u01d9\7Z\2\2\u01d9\u01da\7G\2\2\u01da\u01db\7E\2\2\u01db\u01dc"+ + "\7W\2\2\u01dc\u01dd\7V\2\2\u01dd\u01de\7C\2\2\u01de\u01df\7D\2\2\u01df"+ + "\u01e0\7N\2\2\u01e0\u01e1\7G\2\2\u01e1B\3\2\2\2\u01e2\u01e3\7G\2\2\u01e3"+ + "\u01e4\7Z\2\2\u01e4\u01e5\7K\2\2\u01e5\u01e6\7U\2\2\u01e6\u01e7\7V\2\2"+ + "\u01e7\u01e8\7U\2\2\u01e8D\3\2\2\2\u01e9\u01ea\7G\2\2\u01ea\u01eb\7Z\2"+ + "\2\u01eb\u01ec\7R\2\2\u01ec\u01ed\7N\2\2\u01ed\u01ee\7C\2\2\u01ee\u01ef"+ + "\7K\2\2\u01ef\u01f0\7P\2\2\u01f0F\3\2\2\2\u01f1\u01f2\7G\2\2\u01f2\u01f3"+ + "\7Z\2\2\u01f3\u01f4\7V\2\2\u01f4\u01f5\7T\2\2\u01f5\u01f6\7C\2\2\u01f6"+ + "\u01f7\7E\2\2\u01f7\u01f8\7V\2\2\u01f8H\3\2\2\2\u01f9\u01fa\7H\2\2\u01fa"+ + "\u01fb\7C\2\2\u01fb\u01fc\7N\2\2\u01fc\u01fd\7U\2\2\u01fd\u01fe\7G\2\2"+ + "\u01feJ\3\2\2\2\u01ff\u0200\7H\2\2\u0200\u0201\7K\2\2\u0201\u0202\7T\2"+ + "\2\u0202\u0203\7U\2\2\u0203\u0204\7V\2\2\u0204L\3\2\2\2\u0205\u0206\7"+ + "H\2\2\u0206\u0207\7Q\2\2\u0207\u0208\7T\2\2\u0208\u0209\7O\2\2\u0209\u020a"+ + "\7C\2\2\u020a\u020b\7V\2\2\u020bN\3\2\2\2\u020c\u020d\7H\2\2\u020d\u020e"+ + "\7T\2\2\u020e\u020f\7Q\2\2\u020f\u0210\7O\2\2\u0210P\3\2\2\2\u0211\u0212"+ + "\7H\2\2\u0212\u0213\7W\2\2\u0213\u0214\7N\2\2\u0214\u0215\7N\2\2\u0215"+ + "R\3\2\2\2\u0216\u0217\7H\2\2\u0217\u0218\7W\2\2\u0218\u0219\7P\2\2\u0219"+ + "\u021a\7E\2\2\u021a\u021b\7V\2\2\u021b\u021c\7K\2\2\u021c\u021d\7Q\2\2"+ + "\u021d\u021e\7P\2\2\u021e\u021f\7U\2\2\u021fT\3\2\2\2\u0220\u0221\7I\2"+ + "\2\u0221\u0222\7T\2\2\u0222\u0223\7C\2\2\u0223\u0224\7R\2\2\u0224\u0225"+ + "\7J\2\2\u0225\u0226\7X\2\2\u0226\u0227\7K\2\2\u0227\u0228\7\\\2\2\u0228"+ + "V\3\2\2\2\u0229\u022a\7I\2\2\u022a\u022b\7T\2\2\u022b\u022c\7Q\2\2\u022c"+ + "\u022d\7W\2\2\u022d\u022e\7R\2\2\u022eX\3\2\2\2\u022f\u0230\7J\2\2\u0230"+ + "\u0231\7C\2\2\u0231\u0232\7X\2\2\u0232\u0233\7K\2\2\u0233\u0234\7P\2\2"+ + "\u0234\u0235\7I\2\2\u0235Z\3\2\2\2\u0236\u0237\7J\2\2\u0237\u0238\7Q\2"+ + "\2\u0238\u0239\7W\2\2\u0239\u023a\7T\2\2\u023a\\\3\2\2\2\u023b\u023c\7"+ + "J\2\2\u023c\u023d\7Q\2\2\u023d\u023e\7W\2\2\u023e\u023f\7T\2\2\u023f\u0240"+ + "\7U\2\2\u0240^\3\2\2\2\u0241\u0242\7K\2\2\u0242\u0243\7P\2\2\u0243`\3"+ + "\2\2\2\u0244\u0245\7K\2\2\u0245\u0246\7P\2\2\u0246\u0247\7P\2\2\u0247"+ + "\u0248\7G\2\2\u0248\u0249\7T\2\2\u0249b\3\2\2\2\u024a\u024b\7K\2\2\u024b"+ + "\u024c\7P\2\2\u024c\u024d\7V\2\2\u024d\u024e\7G\2\2\u024e\u024f\7T\2\2"+ + "\u024f\u0250\7X\2\2\u0250\u0251\7C\2\2\u0251\u0252\7N\2\2\u0252d\3\2\2"+ + "\2\u0253\u0254\7K\2\2\u0254\u0255\7U\2\2\u0255f\3\2\2\2\u0256\u0257\7"+ + "L\2\2\u0257\u0258\7Q\2\2\u0258\u0259\7K\2\2\u0259\u025a\7P\2\2\u025ah"+ + "\3\2\2\2\u025b\u025c\7N\2\2\u025c\u025d\7C\2\2\u025d\u025e\7U\2\2\u025e"+ + "\u025f\7V\2\2\u025fj\3\2\2\2\u0260\u0261\7N\2\2\u0261\u0262\7G\2\2\u0262"+ + "\u0263\7H\2\2\u0263\u0264\7V\2\2\u0264l\3\2\2\2\u0265\u0266\7N\2\2\u0266"+ + "\u0267\7K\2\2\u0267\u0268\7M\2\2\u0268\u0269\7G\2\2\u0269n\3\2\2\2\u026a"+ + "\u026b\7N\2\2\u026b\u026c\7K\2\2\u026c\u026d\7O\2\2\u026d\u026e\7K\2\2"+ + "\u026e\u026f\7V\2\2\u026fp\3\2\2\2\u0270\u0271\7O\2\2\u0271\u0272\7C\2"+ + "\2\u0272\u0273\7R\2\2\u0273\u0274\7R\2\2\u0274\u0275\7G\2\2\u0275\u0276"+ + "\7F\2\2\u0276r\3\2\2\2\u0277\u0278\7O\2\2\u0278\u0279\7C\2\2\u0279\u027a"+ + "\7V\2\2\u027a\u027b\7E\2\2\u027b\u027c\7J\2\2\u027ct\3\2\2\2\u027d\u027e"+ + "\7O\2\2\u027e\u027f\7K\2\2\u027f\u0280\7P\2\2\u0280\u0281\7W\2\2\u0281"+ + "\u0282\7V\2\2\u0282\u0283\7G\2\2\u0283v\3\2\2\2\u0284\u0285\7O\2\2\u0285"+ + "\u0286\7K\2\2\u0286\u0287\7P\2\2\u0287\u0288\7W\2\2\u0288\u0289\7V\2\2"+ + "\u0289\u028a\7G\2\2\u028a\u028b\7U\2\2\u028bx\3\2\2\2\u028c\u028d\7O\2"+ + "\2\u028d\u028e\7Q\2\2\u028e\u028f\7P\2\2\u028f\u0290\7V\2\2\u0290\u0291"+ + "\7J\2\2\u0291z\3\2\2\2\u0292\u0293\7O\2\2\u0293\u0294\7Q\2\2\u0294\u0295"+ + "\7P\2\2\u0295\u0296\7V\2\2\u0296\u0297\7J\2\2\u0297\u0298\7U\2\2\u0298"+ + "|\3\2\2\2\u0299\u029a\7P\2\2\u029a\u029b\7C\2\2\u029b\u029c\7V\2\2\u029c"+ + "\u029d\7W\2\2\u029d\u029e\7T\2\2\u029e\u029f\7C\2\2\u029f\u02a0\7N\2\2"+ + "\u02a0~\3\2\2\2\u02a1\u02a2\7P\2\2\u02a2\u02a3\7Q\2\2\u02a3\u02a4\7V\2"+ + "\2\u02a4\u0080\3\2\2\2\u02a5\u02a6\7P\2\2\u02a6\u02a7\7W\2\2\u02a7\u02a8"+ + "\7N\2\2\u02a8\u02a9\7N\2\2\u02a9\u0082\3\2\2\2\u02aa\u02ab\7P\2\2\u02ab"+ + "\u02ac\7W\2\2\u02ac\u02ad\7N\2\2\u02ad\u02ae\7N\2\2\u02ae\u02af\7U\2\2"+ + "\u02af\u0084\3\2\2\2\u02b0\u02b1\7Q\2\2\u02b1\u02b2\7P\2\2\u02b2\u0086"+ + "\3\2\2\2\u02b3\u02b4\7Q\2\2\u02b4\u02b5\7R\2\2\u02b5\u02b6\7V\2\2\u02b6"+ + "\u02b7\7K\2\2\u02b7\u02b8\7O\2\2\u02b8\u02b9\7K\2\2\u02b9\u02ba\7\\\2"+ + "\2\u02ba\u02bb\7G\2\2\u02bb\u02bc\7F\2\2\u02bc\u0088\3\2\2\2\u02bd\u02be"+ + "\7Q\2\2\u02be\u02bf\7T\2\2\u02bf\u008a\3\2\2\2\u02c0\u02c1\7Q\2\2\u02c1"+ + "\u02c2\7T\2\2\u02c2\u02c3\7F\2\2\u02c3\u02c4\7G\2\2\u02c4\u02c5\7T\2\2"+ + "\u02c5\u008c\3\2\2\2\u02c6\u02c7\7Q\2\2\u02c7\u02c8\7W\2\2\u02c8\u02c9"+ + "\7V\2\2\u02c9\u02ca\7G\2\2\u02ca\u02cb\7T\2\2\u02cb\u008e\3\2\2\2\u02cc"+ + "\u02cd\7R\2\2\u02cd\u02ce\7C\2\2\u02ce\u02cf\7T\2\2\u02cf\u02d0\7U\2\2"+ + "\u02d0\u02d1\7G\2\2\u02d1\u02d2\7F\2\2\u02d2\u0090\3\2\2\2\u02d3\u02d4"+ + "\7R\2\2\u02d4\u02d5\7J\2\2\u02d5\u02d6\7[\2\2\u02d6\u02d7\7U\2\2\u02d7"+ + "\u02d8\7K\2\2\u02d8\u02d9\7E\2\2\u02d9\u02da\7C\2\2\u02da\u02db\7N\2\2"+ + "\u02db\u0092\3\2\2\2\u02dc\u02dd\7R\2\2\u02dd\u02de\7N\2\2\u02de\u02df"+ + "\7C\2\2\u02df\u02e0\7P\2\2\u02e0\u0094\3\2\2\2\u02e1\u02e2\7T\2\2\u02e2"+ + "\u02e3\7K\2\2\u02e3\u02e4\7I\2\2\u02e4\u02e5\7J\2\2\u02e5\u02e6\7V\2\2"+ + "\u02e6\u0096\3\2\2\2\u02e7\u02e8\7T\2\2\u02e8\u02e9\7N\2\2\u02e9\u02ea"+ + "\7K\2\2\u02ea\u02eb\7M\2\2\u02eb\u02ec\7G\2\2\u02ec\u0098\3\2\2\2\u02ed"+ + "\u02ee\7S\2\2\u02ee\u02ef\7W\2\2\u02ef\u02f0\7G\2\2\u02f0\u02f1\7T\2\2"+ + "\u02f1\u02f2\7[\2\2\u02f2\u009a\3\2\2\2\u02f3\u02f4\7U\2\2\u02f4\u02f5"+ + "\7E\2\2\u02f5\u02f6\7J\2\2\u02f6\u02f7\7G\2\2\u02f7\u02f8\7O\2\2\u02f8"+ + "\u02f9\7C\2\2\u02f9\u02fa\7U\2\2\u02fa\u009c\3\2\2\2\u02fb\u02fc\7U\2"+ + "\2\u02fc\u02fd\7G\2\2\u02fd\u02fe\7E\2\2\u02fe\u02ff\7Q\2\2\u02ff\u0300"+ + "\7P\2\2\u0300\u0301\7F\2\2\u0301\u009e\3\2\2\2\u0302\u0303\7U\2\2\u0303"+ + "\u0304\7G\2\2\u0304\u0305\7E\2\2\u0305\u0306\7Q\2\2\u0306\u0307\7P\2\2"+ + "\u0307\u0308\7F\2\2\u0308\u0309\7U\2\2\u0309\u00a0\3\2\2\2\u030a\u030b"+ + "\7U\2\2\u030b\u030c\7G\2\2\u030c\u030d\7N\2\2\u030d\u030e\7G\2\2\u030e"+ + "\u030f\7E\2\2\u030f\u0310\7V\2\2\u0310\u00a2\3\2\2\2\u0311\u0312\7U\2"+ + "\2\u0312\u0313\7J\2\2\u0313\u0314\7Q\2\2\u0314\u0315\7Y\2\2\u0315\u00a4"+ + "\3\2\2\2\u0316\u0317\7U\2\2\u0317\u0318\7[\2\2\u0318\u0319\7U\2\2\u0319"+ + "\u00a6\3\2\2\2\u031a\u031b\7V\2\2\u031b\u031c\7C\2\2\u031c\u031d\7D\2"+ + "\2\u031d\u031e\7N\2\2\u031e\u031f\7G\2\2\u031f\u00a8\3\2\2\2\u0320\u0321"+ + "\7V\2\2\u0321\u0322\7C\2\2\u0322\u0323\7D\2\2\u0323\u0324\7N\2\2\u0324"+ + "\u0325\7G\2\2\u0325\u0326\7U\2\2\u0326\u00aa\3\2\2\2\u0327\u0328\7V\2"+ + "\2\u0328\u0329\7G\2\2\u0329\u032a\7Z\2\2\u032a\u032b\7V\2\2\u032b\u00ac"+ + "\3\2\2\2\u032c\u032d\7V\2\2\u032d\u032e\7J\2\2\u032e\u032f\7G\2\2\u032f"+ + "\u0330\7P\2\2\u0330\u00ae\3\2\2\2\u0331\u0332\7V\2\2\u0332\u0333\7T\2"+ + "\2\u0333\u0334\7W\2\2\u0334\u0335\7G\2\2\u0335\u00b0\3\2\2\2\u0336\u0337"+ + "\7V\2\2\u0337\u0338\7Q\2\2\u0338\u00b2\3\2\2\2\u0339\u033a\7V\2\2\u033a"+ + "\u033b\7[\2\2\u033b\u033c\7R\2\2\u033c\u033d\7G\2\2\u033d\u00b4\3\2\2"+ + "\2\u033e\u033f\7V\2\2\u033f\u0340\7[\2\2\u0340\u0341\7R\2\2\u0341\u0342"+ + "\7G\2\2\u0342\u0343\7U\2\2\u0343\u00b6\3\2\2\2\u0344\u0345\7W\2\2\u0345"+ + "\u0346\7U\2\2\u0346\u0347\7K\2\2\u0347\u0348\7P\2\2\u0348\u0349\7I\2\2"+ + "\u0349\u00b8\3\2\2\2\u034a\u034b\7X\2\2\u034b\u034c\7G\2\2\u034c\u034d"+ + "\7T\2\2\u034d\u034e\7K\2\2\u034e\u034f\7H\2\2\u034f\u0350\7[\2\2\u0350"+ + "\u00ba\3\2\2\2\u0351\u0352\7Y\2\2\u0352\u0353\7J\2\2\u0353\u0354\7G\2"+ + "\2\u0354\u0355\7P\2\2\u0355\u00bc\3\2\2\2\u0356\u0357\7Y\2\2\u0357\u0358"+ + "\7J\2\2\u0358\u0359\7G\2\2\u0359\u035a\7T\2\2\u035a\u035b\7G\2\2\u035b"+ + "\u00be\3\2\2\2\u035c\u035d\7Y\2\2\u035d\u035e\7K\2\2\u035e\u035f\7V\2"+ + "\2\u035f\u0360\7J\2\2\u0360\u00c0\3\2\2\2\u0361\u0362\7[\2\2\u0362\u0363"+ + "\7G\2\2\u0363\u0364\7C\2\2\u0364\u0365\7T\2\2\u0365\u00c2\3\2\2\2\u0366"+ + "\u0367\7[\2\2\u0367\u0368\7G\2\2\u0368\u0369\7C\2\2\u0369\u036a\7T\2\2"+ + "\u036a\u036b\7U\2\2\u036b\u00c4\3\2\2\2\u036c\u036d\7}\2\2\u036d\u036e"+ + "\7G\2\2\u036e\u036f\7U\2\2\u036f\u0370\7E\2\2\u0370\u0371\7C\2\2\u0371"+ + "\u0372\7R\2\2\u0372\u0373\7G\2\2\u0373\u00c6\3\2\2\2\u0374\u0375\7}\2"+ + "\2\u0375\u0376\7H\2\2\u0376\u0377\7P\2\2\u0377\u00c8\3\2\2\2\u0378\u0379"+ + "\7}\2\2\u0379\u037a\7N\2\2\u037a\u037b\7K\2\2\u037b\u037c\7O\2\2\u037c"+ + "\u037d\7K\2\2\u037d\u037e\7V\2\2\u037e\u00ca\3\2\2\2\u037f\u0380\7}\2"+ + "\2\u0380\u0381\7F\2\2\u0381\u00cc\3\2\2\2\u0382\u0383\7}\2\2\u0383\u0384"+ + "\7V\2\2\u0384\u00ce\3\2\2\2\u0385\u0386\7}\2\2\u0386\u0387\7V\2\2\u0387"+ + "\u0388\7U\2\2\u0388\u00d0\3\2\2\2\u0389\u038a\7}\2\2\u038a\u038b\7I\2"+ + "\2\u038b\u038c\7W\2\2\u038c\u038d\7K\2\2\u038d\u038e\7F\2\2\u038e\u00d2"+ + "\3\2\2\2\u038f\u0390\7\177\2\2\u0390\u00d4\3\2\2\2\u0391\u0392\7?\2\2"+ + "\u0392\u00d6\3\2\2\2\u0393\u0394\7>\2\2\u0394\u0395\7?\2\2\u0395\u0396"+ + "\7@\2\2\u0396\u00d8\3\2\2\2\u0397\u0398\7>\2\2\u0398\u039c\7@\2\2\u0399"+ + "\u039a\7#\2\2\u039a\u039c\7?\2\2\u039b\u0397\3\2\2\2\u039b\u0399\3\2\2"+ + "\2\u039c\u00da\3\2\2\2\u039d\u039e\7>\2\2\u039e\u00dc\3\2\2\2\u039f\u03a0"+ + "\7>\2\2\u03a0\u03a1\7?\2\2\u03a1\u00de\3\2\2\2\u03a2\u03a3\7@\2\2\u03a3"+ + "\u00e0\3\2\2\2\u03a4\u03a5\7@\2\2\u03a5\u03a6\7?\2\2\u03a6\u00e2\3\2\2"+ + "\2\u03a7\u03a8\7-\2\2\u03a8\u00e4\3\2\2\2\u03a9\u03aa\7/\2\2\u03aa\u00e6"+ + "\3\2\2\2\u03ab\u03ac\7,\2\2\u03ac\u00e8\3\2\2\2\u03ad\u03ae\7\61\2\2\u03ae"+ + "\u00ea\3\2\2\2\u03af\u03b0\7\'\2\2\u03b0\u00ec\3\2\2\2\u03b1\u03b2\7<"+ + "\2\2\u03b2\u03b3\7<\2\2\u03b3\u00ee\3\2\2\2\u03b4\u03b5\7~\2\2\u03b5\u03b6"+ + "\7~\2\2\u03b6\u00f0\3\2\2\2\u03b7\u03b8\7\60\2\2\u03b8\u00f2\3\2\2\2\u03b9"+ + "\u03ba\7A\2\2\u03ba\u00f4\3\2\2\2\u03bb\u03c1\7)\2\2\u03bc\u03c0\n\2\2"+ + "\2\u03bd\u03be\7)\2\2\u03be\u03c0\7)\2\2\u03bf\u03bc\3\2\2\2\u03bf\u03bd"+ + "\3\2\2\2\u03c0\u03c3\3\2\2\2\u03c1\u03bf\3\2\2\2\u03c1\u03c2\3\2\2\2\u03c2"+ + "\u03c4\3\2\2\2\u03c3\u03c1\3\2\2\2\u03c4\u03c5\7)\2\2\u03c5\u00f6\3\2"+ + "\2\2\u03c6\u03c8\5\u0107\u0084\2\u03c7\u03c6\3\2\2\2\u03c8\u03c9\3\2\2"+ + "\2\u03c9\u03c7\3\2\2\2\u03c9\u03ca\3\2\2\2\u03ca\u00f8\3\2\2\2\u03cb\u03cd"+ + "\5\u0107\u0084\2\u03cc\u03cb\3\2\2\2\u03cd\u03ce\3\2\2\2\u03ce\u03cc\3"+ + "\2\2\2\u03ce\u03cf\3\2\2\2\u03cf\u03d0\3\2\2\2\u03d0\u03d4\5\u00f1y\2"+ + "\u03d1\u03d3\5\u0107\u0084\2\u03d2\u03d1\3\2\2\2\u03d3\u03d6\3\2\2\2\u03d4"+ + "\u03d2\3\2\2\2\u03d4\u03d5\3\2\2\2\u03d5\u03f6\3\2\2\2\u03d6\u03d4\3\2"+ + "\2\2\u03d7\u03d9\5\u00f1y\2\u03d8\u03da\5\u0107\u0084\2\u03d9\u03d8\3"+ + "\2\2\2\u03da\u03db\3\2\2\2\u03db\u03d9\3\2\2\2\u03db\u03dc\3\2\2\2\u03dc"+ + "\u03f6\3\2\2\2\u03dd\u03df\5\u0107\u0084\2\u03de\u03dd\3\2\2\2\u03df\u03e0"+ + "\3\2\2\2\u03e0\u03de\3\2\2\2\u03e0\u03e1\3\2\2\2\u03e1\u03e9\3\2\2\2\u03e2"+ + "\u03e6\5\u00f1y\2\u03e3\u03e5\5\u0107\u0084\2\u03e4\u03e3\3\2\2\2\u03e5"+ + "\u03e8\3\2\2\2\u03e6\u03e4\3\2\2\2\u03e6\u03e7\3\2\2\2\u03e7\u03ea\3\2"+ + "\2\2\u03e8\u03e6\3\2\2\2\u03e9\u03e2\3\2\2\2\u03e9\u03ea\3\2\2\2\u03ea"+ + "\u03eb\3\2\2\2\u03eb\u03ec\5\u0105\u0083\2\u03ec\u03f6\3\2\2\2\u03ed\u03ef"+ + "\5\u00f1y\2\u03ee\u03f0\5\u0107\u0084\2\u03ef\u03ee\3\2\2\2\u03f0\u03f1"+ + "\3\2\2\2\u03f1\u03ef\3\2\2\2\u03f1\u03f2\3\2\2\2\u03f2\u03f3\3\2\2\2\u03f3"+ + "\u03f4\5\u0105\u0083\2\u03f4\u03f6\3\2\2\2\u03f5\u03cc\3\2\2\2\u03f5\u03d7"+ + "\3\2\2\2\u03f5\u03de\3\2\2\2\u03f5\u03ed\3\2\2\2\u03f6\u00fa\3\2\2\2\u03f7"+ + "\u03fa\5\u0109\u0085\2\u03f8\u03fa\7a\2\2\u03f9\u03f7\3\2\2\2\u03f9\u03f8"+ + "\3\2\2\2\u03fa\u0400\3\2\2\2\u03fb\u03ff\5\u0109\u0085\2\u03fc\u03ff\5"+ + "\u0107\u0084\2\u03fd\u03ff\t\3\2\2\u03fe\u03fb\3\2\2\2\u03fe\u03fc\3\2"+ + "\2\2\u03fe\u03fd\3\2\2\2\u03ff\u0402\3\2\2\2\u0400\u03fe\3\2\2\2\u0400"+ + "\u0401\3\2\2\2\u0401\u00fc\3\2\2\2\u0402\u0400\3\2\2\2\u0403\u0407\5\u0107"+ + "\u0084\2\u0404\u0408\5\u0109\u0085\2\u0405\u0408\5\u0107\u0084\2\u0406"+ + "\u0408\t\3\2\2\u0407\u0404\3\2\2\2\u0407\u0405\3\2\2\2\u0407\u0406\3\2"+ + "\2\2\u0408\u0409\3\2\2\2\u0409\u0407\3\2\2\2\u0409\u040a\3\2\2\2\u040a"+ + "\u00fe\3\2\2\2\u040b\u040f\5\u0109\u0085\2\u040c\u040f\5\u0107\u0084\2"+ + "\u040d\u040f\7a\2\2\u040e\u040b\3\2\2\2\u040e\u040c\3\2\2\2\u040e\u040d"+ + "\3\2\2\2\u040f\u0410\3\2\2\2\u0410\u040e\3\2\2\2\u0410\u0411\3\2\2\2\u0411"+ + "\u0100\3\2\2\2\u0412\u0418\7$\2\2\u0413\u0417\n\4\2\2\u0414\u0415\7$\2"+ + "\2\u0415\u0417\7$\2\2\u0416\u0413\3\2\2\2\u0416\u0414\3\2\2\2\u0417\u041a"+ + "\3\2\2\2\u0418\u0416\3\2\2\2\u0418\u0419\3\2\2\2\u0419\u041b\3\2\2\2\u041a"+ + "\u0418\3\2\2\2\u041b\u041c\7$\2\2\u041c\u0102\3\2\2\2\u041d\u0423\7b\2"+ + "\2\u041e\u0422\n\5\2\2\u041f\u0420\7b\2\2\u0420\u0422\7b\2\2\u0421\u041e"+ + "\3\2\2\2\u0421\u041f\3\2\2\2\u0422\u0425\3\2\2\2\u0423\u0421\3\2\2\2\u0423"+ + "\u0424\3\2\2\2\u0424\u0426\3\2\2\2\u0425\u0423\3\2\2\2\u0426\u0427\7b"+ + "\2\2\u0427\u0104\3\2\2\2\u0428\u042a\7G\2\2\u0429\u042b\t\6\2\2\u042a"+ + "\u0429\3\2\2\2\u042a\u042b\3\2\2\2\u042b\u042d\3\2\2\2\u042c\u042e\5\u0107"+ + "\u0084\2\u042d\u042c\3\2\2\2\u042e\u042f\3\2\2\2\u042f\u042d\3\2\2\2\u042f"+ + "\u0430\3\2\2\2\u0430\u0106\3\2\2\2\u0431\u0432\t\7\2\2\u0432\u0108\3\2"+ + "\2\2\u0433\u0434\t\b\2\2\u0434\u010a\3\2\2\2\u0435\u0436\7/\2\2\u0436"+ + "\u0437\7/\2\2\u0437\u043b\3\2\2\2\u0438\u043a\n\t\2\2\u0439\u0438\3\2"+ + "\2\2\u043a\u043d\3\2\2\2\u043b\u0439\3\2\2\2\u043b\u043c\3\2\2\2\u043c"+ + "\u043f\3\2\2\2\u043d\u043b\3\2\2\2\u043e\u0440\7\17\2\2\u043f\u043e\3"+ + "\2\2\2\u043f\u0440\3\2\2\2\u0440\u0442\3\2\2\2\u0441\u0443\7\f\2\2\u0442"+ + "\u0441\3\2\2\2\u0442\u0443\3\2\2\2\u0443\u0444\3\2\2\2\u0444\u0445\b\u0086"+ + "\2\2\u0445\u010c\3\2\2\2\u0446\u0447\7\61\2\2\u0447\u0448\7,\2\2\u0448"+ + "\u044d\3\2\2\2\u0449\u044c\5\u010d\u0087\2\u044a\u044c\13\2\2\2\u044b"+ + "\u0449\3\2\2\2\u044b\u044a\3\2\2\2\u044c\u044f\3\2\2\2\u044d\u044e\3\2"+ + "\2\2\u044d\u044b\3\2\2\2\u044e\u0450\3\2\2\2\u044f\u044d\3\2\2\2\u0450"+ + "\u0451\7,\2\2\u0451\u0452\7\61\2\2\u0452\u0453\3\2\2\2\u0453\u0454\b\u0087"+ + "\2\2\u0454\u010e\3\2\2\2\u0455\u0457\t\n\2\2\u0456\u0455\3\2\2\2\u0457"+ + "\u0458\3\2\2\2\u0458\u0456\3\2\2\2\u0458\u0459\3\2\2\2\u0459\u045a\3\2"+ + "\2\2\u045a\u045b\b\u0088\2\2\u045b\u0110\3\2\2\2\u045c\u045d\13\2\2\2"+ + "\u045d\u0112\3\2\2\2\"\2\u039b\u03bf\u03c1\u03c9\u03ce\u03d4\u03db\u03e0"+ + "\u03e6\u03e9\u03f1\u03f5\u03f9\u03fe\u0400\u0407\u0409\u040e\u0410\u0416"+ + "\u0418\u0421\u0423\u042a\u042f\u043b\u043f\u0442\u044b\u044d\u0458\3\2"+ + "\3\2"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseListener.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseListener.java index 9d9bc1a23c0..c0845b7adb5 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseListener.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseListener.java @@ -693,6 +693,18 @@ interface SqlBaseListener extends ParseTreeListener { * @param ctx the parse tree */ void exitSubqueryExpression(SqlBaseParser.SubqueryExpressionContext ctx); + /** + * Enter a parse tree produced by the {@code case} + * labeled alternative in {@link SqlBaseParser#primaryExpression}. + * @param ctx the parse tree + */ + void enterCase(SqlBaseParser.CaseContext ctx); + /** + * Exit a parse tree produced by the {@code case} + * labeled alternative in {@link SqlBaseParser#primaryExpression}. + * @param ctx the parse tree + */ + void exitCase(SqlBaseParser.CaseContext ctx); /** * Enter a parse tree produced by {@link SqlBaseParser#builtinDateTimeFunction}. * @param ctx the parse tree @@ -1067,6 +1079,16 @@ interface SqlBaseListener extends ParseTreeListener { * @param ctx the parse tree */ void exitString(SqlBaseParser.StringContext ctx); + /** + * Enter a parse tree produced by {@link SqlBaseParser#whenClause}. + * @param ctx the parse tree + */ + void enterWhenClause(SqlBaseParser.WhenClauseContext ctx); + /** + * Exit a parse tree produced by {@link SqlBaseParser#whenClause}. + * @param ctx the parse tree + */ + void exitWhenClause(SqlBaseParser.WhenClauseContext ctx); /** * Enter a parse tree produced by {@link SqlBaseParser#nonReserved}. * @param ctx the parse tree diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseParser.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseParser.java index 6769cc88695..1ae31755226 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseParser.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseParser.java @@ -32,25 +32,25 @@ class SqlBaseParser extends Parser { new PredictionContextCache(); 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, - AS=10, ASC=11, BETWEEN=12, BY=13, CAST=14, CATALOG=15, CATALOGS=16, COLUMNS=17, - CONVERT=18, CURRENT_DATE=19, CURRENT_TIME=20, CURRENT_TIMESTAMP=21, DAY=22, - DAYS=23, DEBUG=24, DESC=25, DESCRIBE=26, DISTINCT=27, ESCAPE=28, EXECUTABLE=29, - EXISTS=30, EXPLAIN=31, EXTRACT=32, FALSE=33, FIRST=34, FORMAT=35, FROM=36, - FULL=37, FUNCTIONS=38, GRAPHVIZ=39, GROUP=40, HAVING=41, HOUR=42, HOURS=43, - IN=44, INNER=45, INTERVAL=46, IS=47, JOIN=48, LAST=49, LEFT=50, LIKE=51, - LIMIT=52, MAPPED=53, MATCH=54, MINUTE=55, MINUTES=56, MONTH=57, MONTHS=58, - NATURAL=59, NOT=60, NULL=61, NULLS=62, ON=63, OPTIMIZED=64, OR=65, ORDER=66, - OUTER=67, PARSED=68, PHYSICAL=69, PLAN=70, RIGHT=71, RLIKE=72, QUERY=73, - SCHEMAS=74, SECOND=75, SECONDS=76, SELECT=77, SHOW=78, SYS=79, TABLE=80, - TABLES=81, TEXT=82, TRUE=83, TO=84, TYPE=85, TYPES=86, USING=87, VERIFY=88, - WHERE=89, WITH=90, YEAR=91, YEARS=92, ESCAPE_ESC=93, FUNCTION_ESC=94, - LIMIT_ESC=95, DATE_ESC=96, TIME_ESC=97, TIMESTAMP_ESC=98, GUID_ESC=99, - ESC_END=100, EQ=101, NULLEQ=102, NEQ=103, LT=104, LTE=105, GT=106, GTE=107, - PLUS=108, MINUS=109, ASTERISK=110, SLASH=111, PERCENT=112, CAST_OP=113, - CONCAT=114, DOT=115, PARAM=116, STRING=117, INTEGER_VALUE=118, DECIMAL_VALUE=119, - IDENTIFIER=120, DIGIT_IDENTIFIER=121, TABLE_IDENTIFIER=122, QUOTED_IDENTIFIER=123, - BACKQUOTED_IDENTIFIER=124, SIMPLE_COMMENT=125, BRACKETED_COMMENT=126, - WS=127, UNRECOGNIZED=128, DELIMITER=129; + AS=10, ASC=11, BETWEEN=12, BY=13, CASE=14, CAST=15, CATALOG=16, CATALOGS=17, + COLUMNS=18, CONVERT=19, CURRENT_DATE=20, CURRENT_TIME=21, CURRENT_TIMESTAMP=22, + DAY=23, DAYS=24, DEBUG=25, DESC=26, DESCRIBE=27, DISTINCT=28, ELSE=29, + END=30, ESCAPE=31, EXECUTABLE=32, EXISTS=33, EXPLAIN=34, EXTRACT=35, FALSE=36, + FIRST=37, FORMAT=38, FROM=39, FULL=40, FUNCTIONS=41, GRAPHVIZ=42, GROUP=43, + HAVING=44, HOUR=45, HOURS=46, IN=47, INNER=48, INTERVAL=49, IS=50, JOIN=51, + LAST=52, LEFT=53, LIKE=54, LIMIT=55, MAPPED=56, MATCH=57, MINUTE=58, MINUTES=59, + MONTH=60, MONTHS=61, NATURAL=62, NOT=63, NULL=64, NULLS=65, ON=66, OPTIMIZED=67, + OR=68, ORDER=69, OUTER=70, PARSED=71, PHYSICAL=72, PLAN=73, RIGHT=74, + RLIKE=75, QUERY=76, SCHEMAS=77, SECOND=78, SECONDS=79, SELECT=80, SHOW=81, + SYS=82, TABLE=83, TABLES=84, TEXT=85, THEN=86, TRUE=87, TO=88, TYPE=89, + TYPES=90, USING=91, VERIFY=92, WHEN=93, WHERE=94, WITH=95, YEAR=96, YEARS=97, + ESCAPE_ESC=98, FUNCTION_ESC=99, LIMIT_ESC=100, DATE_ESC=101, TIME_ESC=102, + TIMESTAMP_ESC=103, GUID_ESC=104, ESC_END=105, EQ=106, NULLEQ=107, NEQ=108, + LT=109, LTE=110, GT=111, GTE=112, PLUS=113, MINUS=114, ASTERISK=115, SLASH=116, + PERCENT=117, CAST_OP=118, CONCAT=119, DOT=120, PARAM=121, STRING=122, + INTEGER_VALUE=123, DECIMAL_VALUE=124, IDENTIFIER=125, DIGIT_IDENTIFIER=126, + TABLE_IDENTIFIER=127, QUOTED_IDENTIFIER=128, BACKQUOTED_IDENTIFIER=129, + SIMPLE_COMMENT=130, BRACKETED_COMMENT=131, WS=132, UNRECOGNIZED=133, DELIMITER=134; public static final int RULE_singleStatement = 0, RULE_singleExpression = 1, RULE_statement = 2, RULE_query = 3, RULE_queryNoWith = 4, RULE_limitClause = 5, RULE_queryTerm = 6, @@ -67,7 +67,8 @@ class SqlBaseParser extends Parser { RULE_constant = 40, RULE_comparisonOperator = 41, RULE_booleanValue = 42, RULE_interval = 43, RULE_intervalField = 44, RULE_dataType = 45, RULE_qualifiedName = 46, RULE_identifier = 47, RULE_tableIdentifier = 48, RULE_quoteIdentifier = 49, - RULE_unquoteIdentifier = 50, RULE_number = 51, RULE_string = 52, RULE_nonReserved = 53; + RULE_unquoteIdentifier = 50, RULE_number = 51, RULE_string = 52, RULE_whenClause = 53, + RULE_nonReserved = 54; public static final String[] ruleNames = { "singleStatement", "singleExpression", "statement", "query", "queryNoWith", "limitClause", "queryTerm", "orderBy", "querySpecification", "fromClause", @@ -80,47 +81,48 @@ class SqlBaseParser extends Parser { "functionExpression", "functionTemplate", "functionName", "constant", "comparisonOperator", "booleanValue", "interval", "intervalField", "dataType", "qualifiedName", "identifier", "tableIdentifier", "quoteIdentifier", "unquoteIdentifier", - "number", "string", "nonReserved" + "number", "string", "whenClause", "nonReserved" }; private static final String[] _LITERAL_NAMES = { null, "'('", "')'", "','", "':'", "'ALL'", "'ANALYZE'", "'ANALYZED'", - "'AND'", "'ANY'", "'AS'", "'ASC'", "'BETWEEN'", "'BY'", "'CAST'", "'CATALOG'", - "'CATALOGS'", "'COLUMNS'", "'CONVERT'", "'CURRENT_DATE'", "'CURRENT_TIME'", - "'CURRENT_TIMESTAMP'", "'DAY'", "'DAYS'", "'DEBUG'", "'DESC'", "'DESCRIBE'", - "'DISTINCT'", "'ESCAPE'", "'EXECUTABLE'", "'EXISTS'", "'EXPLAIN'", "'EXTRACT'", - "'FALSE'", "'FIRST'", "'FORMAT'", "'FROM'", "'FULL'", "'FUNCTIONS'", "'GRAPHVIZ'", - "'GROUP'", "'HAVING'", "'HOUR'", "'HOURS'", "'IN'", "'INNER'", "'INTERVAL'", - "'IS'", "'JOIN'", "'LAST'", "'LEFT'", "'LIKE'", "'LIMIT'", "'MAPPED'", - "'MATCH'", "'MINUTE'", "'MINUTES'", "'MONTH'", "'MONTHS'", "'NATURAL'", - "'NOT'", "'NULL'", "'NULLS'", "'ON'", "'OPTIMIZED'", "'OR'", "'ORDER'", - "'OUTER'", "'PARSED'", "'PHYSICAL'", "'PLAN'", "'RIGHT'", "'RLIKE'", "'QUERY'", - "'SCHEMAS'", "'SECOND'", "'SECONDS'", "'SELECT'", "'SHOW'", "'SYS'", "'TABLE'", - "'TABLES'", "'TEXT'", "'TRUE'", "'TO'", "'TYPE'", "'TYPES'", "'USING'", - "'VERIFY'", "'WHERE'", "'WITH'", "'YEAR'", "'YEARS'", "'{ESCAPE'", "'{FN'", - "'{LIMIT'", "'{D'", "'{T'", "'{TS'", "'{GUID'", "'}'", "'='", "'<=>'", - null, "'<'", "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", - "'::'", "'||'", "'.'", "'?'" + "'AND'", "'ANY'", "'AS'", "'ASC'", "'BETWEEN'", "'BY'", "'CASE'", "'CAST'", + "'CATALOG'", "'CATALOGS'", "'COLUMNS'", "'CONVERT'", "'CURRENT_DATE'", + "'CURRENT_TIME'", "'CURRENT_TIMESTAMP'", "'DAY'", "'DAYS'", "'DEBUG'", + "'DESC'", "'DESCRIBE'", "'DISTINCT'", "'ELSE'", "'END'", "'ESCAPE'", "'EXECUTABLE'", + "'EXISTS'", "'EXPLAIN'", "'EXTRACT'", "'FALSE'", "'FIRST'", "'FORMAT'", + "'FROM'", "'FULL'", "'FUNCTIONS'", "'GRAPHVIZ'", "'GROUP'", "'HAVING'", + "'HOUR'", "'HOURS'", "'IN'", "'INNER'", "'INTERVAL'", "'IS'", "'JOIN'", + "'LAST'", "'LEFT'", "'LIKE'", "'LIMIT'", "'MAPPED'", "'MATCH'", "'MINUTE'", + "'MINUTES'", "'MONTH'", "'MONTHS'", "'NATURAL'", "'NOT'", "'NULL'", "'NULLS'", + "'ON'", "'OPTIMIZED'", "'OR'", "'ORDER'", "'OUTER'", "'PARSED'", "'PHYSICAL'", + "'PLAN'", "'RIGHT'", "'RLIKE'", "'QUERY'", "'SCHEMAS'", "'SECOND'", "'SECONDS'", + "'SELECT'", "'SHOW'", "'SYS'", "'TABLE'", "'TABLES'", "'TEXT'", "'THEN'", + "'TRUE'", "'TO'", "'TYPE'", "'TYPES'", "'USING'", "'VERIFY'", "'WHEN'", + "'WHERE'", "'WITH'", "'YEAR'", "'YEARS'", "'{ESCAPE'", "'{FN'", "'{LIMIT'", + "'{D'", "'{T'", "'{TS'", "'{GUID'", "'}'", "'='", "'<=>'", null, "'<'", + "'<='", "'>'", "'>='", "'+'", "'-'", "'*'", "'/'", "'%'", "'::'", "'||'", + "'.'", "'?'" }; private static final String[] _SYMBOLIC_NAMES = { null, null, null, null, null, "ALL", "ANALYZE", "ANALYZED", "AND", "ANY", - "AS", "ASC", "BETWEEN", "BY", "CAST", "CATALOG", "CATALOGS", "COLUMNS", + "AS", "ASC", "BETWEEN", "BY", "CASE", "CAST", "CATALOG", "CATALOGS", "COLUMNS", "CONVERT", "CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "DAY", - "DAYS", "DEBUG", "DESC", "DESCRIBE", "DISTINCT", "ESCAPE", "EXECUTABLE", - "EXISTS", "EXPLAIN", "EXTRACT", "FALSE", "FIRST", "FORMAT", "FROM", "FULL", - "FUNCTIONS", "GRAPHVIZ", "GROUP", "HAVING", "HOUR", "HOURS", "IN", "INNER", - "INTERVAL", "IS", "JOIN", "LAST", "LEFT", "LIKE", "LIMIT", "MAPPED", "MATCH", - "MINUTE", "MINUTES", "MONTH", "MONTHS", "NATURAL", "NOT", "NULL", "NULLS", - "ON", "OPTIMIZED", "OR", "ORDER", "OUTER", "PARSED", "PHYSICAL", "PLAN", - "RIGHT", "RLIKE", "QUERY", "SCHEMAS", "SECOND", "SECONDS", "SELECT", "SHOW", - "SYS", "TABLE", "TABLES", "TEXT", "TRUE", "TO", "TYPE", "TYPES", "USING", - "VERIFY", "WHERE", "WITH", "YEAR", "YEARS", "ESCAPE_ESC", "FUNCTION_ESC", - "LIMIT_ESC", "DATE_ESC", "TIME_ESC", "TIMESTAMP_ESC", "GUID_ESC", "ESC_END", - "EQ", "NULLEQ", "NEQ", "LT", "LTE", "GT", "GTE", "PLUS", "MINUS", "ASTERISK", - "SLASH", "PERCENT", "CAST_OP", "CONCAT", "DOT", "PARAM", "STRING", "INTEGER_VALUE", - "DECIMAL_VALUE", "IDENTIFIER", "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", - "QUOTED_IDENTIFIER", "BACKQUOTED_IDENTIFIER", "SIMPLE_COMMENT", "BRACKETED_COMMENT", - "WS", "UNRECOGNIZED", "DELIMITER" + "DAYS", "DEBUG", "DESC", "DESCRIBE", "DISTINCT", "ELSE", "END", "ESCAPE", + "EXECUTABLE", "EXISTS", "EXPLAIN", "EXTRACT", "FALSE", "FIRST", "FORMAT", + "FROM", "FULL", "FUNCTIONS", "GRAPHVIZ", "GROUP", "HAVING", "HOUR", "HOURS", + "IN", "INNER", "INTERVAL", "IS", "JOIN", "LAST", "LEFT", "LIKE", "LIMIT", + "MAPPED", "MATCH", "MINUTE", "MINUTES", "MONTH", "MONTHS", "NATURAL", + "NOT", "NULL", "NULLS", "ON", "OPTIMIZED", "OR", "ORDER", "OUTER", "PARSED", + "PHYSICAL", "PLAN", "RIGHT", "RLIKE", "QUERY", "SCHEMAS", "SECOND", "SECONDS", + "SELECT", "SHOW", "SYS", "TABLE", "TABLES", "TEXT", "THEN", "TRUE", "TO", + "TYPE", "TYPES", "USING", "VERIFY", "WHEN", "WHERE", "WITH", "YEAR", "YEARS", + "ESCAPE_ESC", "FUNCTION_ESC", "LIMIT_ESC", "DATE_ESC", "TIME_ESC", "TIMESTAMP_ESC", + "GUID_ESC", "ESC_END", "EQ", "NULLEQ", "NEQ", "LT", "LTE", "GT", "GTE", + "PLUS", "MINUS", "ASTERISK", "SLASH", "PERCENT", "CAST_OP", "CONCAT", + "DOT", "PARAM", "STRING", "INTEGER_VALUE", "DECIMAL_VALUE", "IDENTIFIER", + "DIGIT_IDENTIFIER", "TABLE_IDENTIFIER", "QUOTED_IDENTIFIER", "BACKQUOTED_IDENTIFIER", + "SIMPLE_COMMENT", "BRACKETED_COMMENT", "WS", "UNRECOGNIZED", "DELIMITER" }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); @@ -201,9 +203,9 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(108); + setState(110); statement(); - setState(109); + setState(111); match(EOF); } } @@ -248,9 +250,9 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(111); + setState(113); expression(); - setState(112); + setState(114); match(EOF); } } @@ -613,14 +615,14 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 4, RULE_statement); int _la; try { - setState(215); + setState(217); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,19,_ctx) ) { case 1: _localctx = new StatementDefaultContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(114); + setState(116); query(); } break; @@ -628,30 +630,30 @@ class SqlBaseParser extends Parser { _localctx = new ExplainContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(115); + setState(117); match(EXPLAIN); - setState(129); + setState(131); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { case 1: { - setState(116); + setState(118); match(T__0); - setState(125); + setState(127); _errHandler.sync(this); _la = _input.LA(1); - while (((((_la - 35)) & ~0x3f) == 0 && ((1L << (_la - 35)) & ((1L << (FORMAT - 35)) | (1L << (PLAN - 35)) | (1L << (VERIFY - 35)))) != 0)) { + while (((((_la - 38)) & ~0x3f) == 0 && ((1L << (_la - 38)) & ((1L << (FORMAT - 38)) | (1L << (PLAN - 38)) | (1L << (VERIFY - 38)))) != 0)) { { - setState(123); + setState(125); switch (_input.LA(1)) { case PLAN: { - setState(117); + setState(119); match(PLAN); - setState(118); + setState(120); ((ExplainContext)_localctx).type = _input.LT(1); _la = _input.LA(1); - if ( !(((((_la - 5)) & ~0x3f) == 0 && ((1L << (_la - 5)) & ((1L << (ALL - 5)) | (1L << (ANALYZED - 5)) | (1L << (EXECUTABLE - 5)) | (1L << (MAPPED - 5)) | (1L << (OPTIMIZED - 5)) | (1L << (PARSED - 5)))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ALL) | (1L << ANALYZED) | (1L << EXECUTABLE) | (1L << MAPPED))) != 0) || _la==OPTIMIZED || _la==PARSED) ) { ((ExplainContext)_localctx).type = (Token)_errHandler.recoverInline(this); } else { consume(); @@ -660,9 +662,9 @@ class SqlBaseParser extends Parser { break; case FORMAT: { - setState(119); + setState(121); match(FORMAT); - setState(120); + setState(122); ((ExplainContext)_localctx).format = _input.LT(1); _la = _input.LA(1); if ( !(_la==GRAPHVIZ || _la==TEXT) ) { @@ -674,9 +676,9 @@ class SqlBaseParser extends Parser { break; case VERIFY: { - setState(121); + setState(123); match(VERIFY); - setState(122); + setState(124); ((ExplainContext)_localctx).verify = booleanValue(); } break; @@ -684,16 +686,16 @@ class SqlBaseParser extends Parser { throw new NoViableAltException(this); } } - setState(127); + setState(129); _errHandler.sync(this); _la = _input.LA(1); } - setState(128); + setState(130); match(T__1); } break; } - setState(131); + setState(133); statement(); } break; @@ -701,27 +703,27 @@ class SqlBaseParser extends Parser { _localctx = new DebugContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(132); + setState(134); match(DEBUG); - setState(144); + setState(146); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) { case 1: { - setState(133); + setState(135); match(T__0); - setState(140); + setState(142); _errHandler.sync(this); _la = _input.LA(1); while (_la==FORMAT || _la==PLAN) { { - setState(138); + setState(140); switch (_input.LA(1)) { case PLAN: { - setState(134); + setState(136); match(PLAN); - setState(135); + setState(137); ((DebugContext)_localctx).type = _input.LT(1); _la = _input.LA(1); if ( !(_la==ANALYZED || _la==OPTIMIZED) ) { @@ -733,9 +735,9 @@ class SqlBaseParser extends Parser { break; case FORMAT: { - setState(136); + setState(138); match(FORMAT); - setState(137); + setState(139); ((DebugContext)_localctx).format = _input.LT(1); _la = _input.LA(1); if ( !(_la==GRAPHVIZ || _la==TEXT) ) { @@ -749,16 +751,16 @@ class SqlBaseParser extends Parser { throw new NoViableAltException(this); } } - setState(142); + setState(144); _errHandler.sync(this); _la = _input.LA(1); } - setState(143); + setState(145); match(T__1); } break; } - setState(146); + setState(148); statement(); } break; @@ -766,15 +768,15 @@ class SqlBaseParser extends Parser { _localctx = new ShowTablesContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(147); + setState(149); match(SHOW); - setState(148); + setState(150); match(TABLES); - setState(151); + setState(153); switch (_input.LA(1)) { case LIKE: { - setState(149); + setState(151); ((ShowTablesContext)_localctx).tableLike = likePattern(); } break; @@ -823,7 +825,7 @@ class SqlBaseParser extends Parser { case QUOTED_IDENTIFIER: case BACKQUOTED_IDENTIFIER: { - setState(150); + setState(152); ((ShowTablesContext)_localctx).tableIdent = tableIdentifier(); } break; @@ -838,22 +840,22 @@ class SqlBaseParser extends Parser { _localctx = new ShowColumnsContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(153); - match(SHOW); - setState(154); - match(COLUMNS); setState(155); + match(SHOW); + setState(156); + match(COLUMNS); + setState(157); _la = _input.LA(1); if ( !(_la==FROM || _la==IN) ) { _errHandler.recoverInline(this); } else { consume(); } - setState(158); + setState(160); switch (_input.LA(1)) { case LIKE: { - setState(156); + setState(158); ((ShowColumnsContext)_localctx).tableLike = likePattern(); } break; @@ -902,7 +904,7 @@ class SqlBaseParser extends Parser { case QUOTED_IDENTIFIER: case BACKQUOTED_IDENTIFIER: { - setState(157); + setState(159); ((ShowColumnsContext)_localctx).tableIdent = tableIdentifier(); } break; @@ -915,18 +917,18 @@ class SqlBaseParser extends Parser { _localctx = new ShowColumnsContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(160); + setState(162); _la = _input.LA(1); if ( !(_la==DESC || _la==DESCRIBE) ) { _errHandler.recoverInline(this); } else { consume(); } - setState(163); + setState(165); switch (_input.LA(1)) { case LIKE: { - setState(161); + setState(163); ((ShowColumnsContext)_localctx).tableLike = likePattern(); } break; @@ -975,7 +977,7 @@ class SqlBaseParser extends Parser { case QUOTED_IDENTIFIER: case BACKQUOTED_IDENTIFIER: { - setState(162); + setState(164); ((ShowColumnsContext)_localctx).tableIdent = tableIdentifier(); } break; @@ -988,15 +990,15 @@ class SqlBaseParser extends Parser { _localctx = new ShowFunctionsContext(_localctx); enterOuterAlt(_localctx, 7); { - setState(165); + setState(167); match(SHOW); - setState(166); - match(FUNCTIONS); setState(168); + match(FUNCTIONS); + setState(170); _la = _input.LA(1); if (_la==LIKE) { { - setState(167); + setState(169); likePattern(); } } @@ -1007,9 +1009,9 @@ class SqlBaseParser extends Parser { _localctx = new ShowSchemasContext(_localctx); enterOuterAlt(_localctx, 8); { - setState(170); + setState(172); match(SHOW); - setState(171); + setState(173); match(SCHEMAS); } break; @@ -1017,58 +1019,58 @@ class SqlBaseParser extends Parser { _localctx = new SysTablesContext(_localctx); enterOuterAlt(_localctx, 9); { - setState(172); + setState(174); match(SYS); - setState(173); + setState(175); match(TABLES); - setState(176); + setState(178); _la = _input.LA(1); if (_la==CATALOG) { { - setState(174); + setState(176); match(CATALOG); - setState(175); + setState(177); ((SysTablesContext)_localctx).clusterLike = likePattern(); } } - setState(180); + setState(182); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,11,_ctx) ) { case 1: { - setState(178); + setState(180); ((SysTablesContext)_localctx).tableLike = likePattern(); } break; case 2: { - setState(179); + setState(181); ((SysTablesContext)_localctx).tableIdent = tableIdentifier(); } break; } - setState(191); + setState(193); _la = _input.LA(1); if (_la==TYPE) { { - setState(182); + setState(184); match(TYPE); - setState(183); + setState(185); string(); - setState(188); + setState(190); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(184); + setState(186); match(T__2); - setState(185); + setState(187); string(); } } - setState(190); + setState(192); _errHandler.sync(this); _la = _input.LA(1); } @@ -1081,28 +1083,28 @@ class SqlBaseParser extends Parser { _localctx = new SysColumnsContext(_localctx); enterOuterAlt(_localctx, 10); { - setState(193); + setState(195); match(SYS); - setState(194); + setState(196); match(COLUMNS); - setState(197); + setState(199); _la = _input.LA(1); if (_la==CATALOG) { { - setState(195); + setState(197); match(CATALOG); - setState(196); + setState(198); ((SysColumnsContext)_localctx).cluster = string(); } } - setState(202); + setState(204); switch (_input.LA(1)) { case TABLE: { - setState(199); + setState(201); match(TABLE); - setState(200); + setState(202); ((SysColumnsContext)_localctx).tableLike = likePattern(); } break; @@ -1151,7 +1153,7 @@ class SqlBaseParser extends Parser { case QUOTED_IDENTIFIER: case BACKQUOTED_IDENTIFIER: { - setState(201); + setState(203); ((SysColumnsContext)_localctx).tableIdent = tableIdentifier(); } break; @@ -1161,11 +1163,11 @@ class SqlBaseParser extends Parser { default: throw new NoViableAltException(this); } - setState(205); + setState(207); _la = _input.LA(1); if (_la==LIKE) { { - setState(204); + setState(206); ((SysColumnsContext)_localctx).columnPattern = likePattern(); } } @@ -1176,19 +1178,19 @@ class SqlBaseParser extends Parser { _localctx = new SysTypesContext(_localctx); enterOuterAlt(_localctx, 11); { - setState(207); + setState(209); match(SYS); - setState(208); + setState(210); match(TYPES); - setState(213); + setState(215); _la = _input.LA(1); - if (((((_la - 108)) & ~0x3f) == 0 && ((1L << (_la - 108)) & ((1L << (PLUS - 108)) | (1L << (MINUS - 108)) | (1L << (INTEGER_VALUE - 108)) | (1L << (DECIMAL_VALUE - 108)))) != 0)) { + if (((((_la - 113)) & ~0x3f) == 0 && ((1L << (_la - 113)) & ((1L << (PLUS - 113)) | (1L << (MINUS - 113)) | (1L << (INTEGER_VALUE - 113)) | (1L << (DECIMAL_VALUE - 113)))) != 0)) { { - setState(210); + setState(212); _la = _input.LA(1); if (_la==PLUS || _la==MINUS) { { - setState(209); + setState(211); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { _errHandler.recoverInline(this); @@ -1198,7 +1200,7 @@ class SqlBaseParser extends Parser { } } - setState(212); + setState(214); ((SysTypesContext)_localctx).type = number(); } } @@ -1255,34 +1257,34 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(226); + setState(228); _la = _input.LA(1); if (_la==WITH) { { - setState(217); + setState(219); match(WITH); - setState(218); + setState(220); namedQuery(); - setState(223); + setState(225); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(219); + setState(221); match(T__2); - setState(220); + setState(222); namedQuery(); } } - setState(225); + setState(227); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(228); + setState(230); queryNoWith(); } } @@ -1338,42 +1340,42 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(230); + setState(232); queryTerm(); - setState(241); + setState(243); _la = _input.LA(1); if (_la==ORDER) { { - setState(231); - match(ORDER); - setState(232); - match(BY); setState(233); + match(ORDER); + setState(234); + match(BY); + setState(235); orderBy(); - setState(238); + setState(240); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(234); + setState(236); match(T__2); - setState(235); + setState(237); orderBy(); } } - setState(240); + setState(242); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(244); + setState(246); _la = _input.LA(1); if (_la==LIMIT || _la==LIMIT_ESC) { { - setState(243); + setState(245); limitClause(); } } @@ -1422,14 +1424,14 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 10, RULE_limitClause); int _la; try { - setState(251); + setState(253); switch (_input.LA(1)) { case LIMIT: enterOuterAlt(_localctx, 1); { - setState(246); + setState(248); match(LIMIT); - setState(247); + setState(249); ((LimitClauseContext)_localctx).limit = _input.LT(1); _la = _input.LA(1); if ( !(_la==ALL || _la==INTEGER_VALUE) ) { @@ -1442,9 +1444,9 @@ class SqlBaseParser extends Parser { case LIMIT_ESC: enterOuterAlt(_localctx, 2); { - setState(248); + setState(250); match(LIMIT_ESC); - setState(249); + setState(251); ((LimitClauseContext)_localctx).limit = _input.LT(1); _la = _input.LA(1); if ( !(_la==ALL || _la==INTEGER_VALUE) ) { @@ -1452,7 +1454,7 @@ class SqlBaseParser extends Parser { } else { consume(); } - setState(250); + setState(252); match(ESC_END); } break; @@ -1525,13 +1527,13 @@ class SqlBaseParser extends Parser { QueryTermContext _localctx = new QueryTermContext(_ctx, getState()); enterRule(_localctx, 12, RULE_queryTerm); try { - setState(258); + setState(260); switch (_input.LA(1)) { case SELECT: _localctx = new QueryPrimaryDefaultContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(253); + setState(255); querySpecification(); } break; @@ -1539,11 +1541,11 @@ class SqlBaseParser extends Parser { _localctx = new SubqueryContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(254); - match(T__0); - setState(255); - queryNoWith(); setState(256); + match(T__0); + setState(257); + queryNoWith(); + setState(258); match(T__1); } break; @@ -1599,13 +1601,13 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(260); - expression(); setState(262); + expression(); + setState(264); _la = _input.LA(1); if (_la==ASC || _la==DESC) { { - setState(261); + setState(263); ((OrderByContext)_localctx).ordering = _input.LT(1); _la = _input.LA(1); if ( !(_la==ASC || _la==DESC) ) { @@ -1616,13 +1618,13 @@ class SqlBaseParser extends Parser { } } - setState(266); + setState(268); _la = _input.LA(1); if (_la==NULLS) { { - setState(264); + setState(266); match(NULLS); - setState(265); + setState(267); ((OrderByContext)_localctx).nullOrdering = _input.LT(1); _la = _input.LA(1); if ( !(_la==FIRST || _la==LAST) ) { @@ -1701,75 +1703,75 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(268); - match(SELECT); setState(270); + match(SELECT); + setState(272); _la = _input.LA(1); if (_la==ALL || _la==DISTINCT) { { - setState(269); + setState(271); setQuantifier(); } } - setState(272); + setState(274); selectItem(); - setState(277); + setState(279); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(273); + setState(275); match(T__2); - setState(274); + setState(276); selectItem(); } } - setState(279); + setState(281); _errHandler.sync(this); _la = _input.LA(1); } - setState(281); + setState(283); _la = _input.LA(1); if (_la==FROM) { { - setState(280); + setState(282); fromClause(); } } - setState(285); + setState(287); _la = _input.LA(1); if (_la==WHERE) { { - setState(283); + setState(285); match(WHERE); - setState(284); + setState(286); ((QuerySpecificationContext)_localctx).where = booleanExpression(0); } } - setState(290); + setState(292); _la = _input.LA(1); if (_la==GROUP) { { - setState(287); - match(GROUP); - setState(288); - match(BY); setState(289); + match(GROUP); + setState(290); + match(BY); + setState(291); groupBy(); } } - setState(294); + setState(296); _la = _input.LA(1); if (_la==HAVING) { { - setState(292); + setState(294); match(HAVING); - setState(293); + setState(295); ((QuerySpecificationContext)_localctx).having = booleanExpression(0); } } @@ -1821,23 +1823,23 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(296); + setState(298); match(FROM); - setState(297); + setState(299); relation(); - setState(302); + setState(304); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(298); + setState(300); match(T__2); - setState(299); + setState(301); relation(); } } - setState(304); + setState(306); _errHandler.sync(this); _la = _input.LA(1); } @@ -1890,30 +1892,30 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(306); + setState(308); _la = _input.LA(1); if (_la==ALL || _la==DISTINCT) { { - setState(305); + setState(307); setQuantifier(); } } - setState(308); + setState(310); groupingElement(); - setState(313); + setState(315); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(309); + setState(311); match(T__2); - setState(310); + setState(312); groupingElement(); } } - setState(315); + setState(317); _errHandler.sync(this); _la = _input.LA(1); } @@ -1968,7 +1970,7 @@ class SqlBaseParser extends Parser { _localctx = new SingleGroupingSetContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(316); + setState(318); groupingExpressions(); } } @@ -2014,47 +2016,47 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 24, RULE_groupingExpressions); int _la; try { - setState(331); + setState(333); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,40,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(318); + setState(320); match(T__0); - setState(327); + setState(329); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << ANALYZE) | (1L << ANALYZED) | (1L << CAST) | (1L << CATALOGS) | (1L << COLUMNS) | (1L << CONVERT) | (1L << CURRENT_DATE) | (1L << CURRENT_TIME) | (1L << CURRENT_TIMESTAMP) | (1L << DAY) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXISTS) | (1L << EXPLAIN) | (1L << EXTRACT) | (1L << FALSE) | (1L << FIRST) | (1L << FORMAT) | (1L << FULL) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << HOUR) | (1L << INTERVAL) | (1L << LAST) | (1L << LEFT) | (1L << LIMIT) | (1L << MAPPED) | (1L << MATCH) | (1L << MINUTE) | (1L << MONTH) | (1L << NOT) | (1L << NULL))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (OPTIMIZED - 64)) | (1L << (PARSED - 64)) | (1L << (PHYSICAL - 64)) | (1L << (PLAN - 64)) | (1L << (RIGHT - 64)) | (1L << (RLIKE - 64)) | (1L << (QUERY - 64)) | (1L << (SCHEMAS - 64)) | (1L << (SECOND - 64)) | (1L << (SHOW - 64)) | (1L << (SYS - 64)) | (1L << (TABLES - 64)) | (1L << (TEXT - 64)) | (1L << (TRUE - 64)) | (1L << (TYPE - 64)) | (1L << (TYPES - 64)) | (1L << (VERIFY - 64)) | (1L << (YEAR - 64)) | (1L << (FUNCTION_ESC - 64)) | (1L << (DATE_ESC - 64)) | (1L << (TIME_ESC - 64)) | (1L << (TIMESTAMP_ESC - 64)) | (1L << (GUID_ESC - 64)) | (1L << (PLUS - 64)) | (1L << (MINUS - 64)) | (1L << (ASTERISK - 64)) | (1L << (PARAM - 64)) | (1L << (STRING - 64)) | (1L << (INTEGER_VALUE - 64)) | (1L << (DECIMAL_VALUE - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { + if (((((_la - 1)) & ~0x3f) == 0 && ((1L << (_la - 1)) & ((1L << (T__0 - 1)) | (1L << (ANALYZE - 1)) | (1L << (ANALYZED - 1)) | (1L << (CASE - 1)) | (1L << (CAST - 1)) | (1L << (CATALOGS - 1)) | (1L << (COLUMNS - 1)) | (1L << (CONVERT - 1)) | (1L << (CURRENT_DATE - 1)) | (1L << (CURRENT_TIME - 1)) | (1L << (CURRENT_TIMESTAMP - 1)) | (1L << (DAY - 1)) | (1L << (DEBUG - 1)) | (1L << (EXECUTABLE - 1)) | (1L << (EXISTS - 1)) | (1L << (EXPLAIN - 1)) | (1L << (EXTRACT - 1)) | (1L << (FALSE - 1)) | (1L << (FIRST - 1)) | (1L << (FORMAT - 1)) | (1L << (FULL - 1)) | (1L << (FUNCTIONS - 1)) | (1L << (GRAPHVIZ - 1)) | (1L << (HOUR - 1)) | (1L << (INTERVAL - 1)) | (1L << (LAST - 1)) | (1L << (LEFT - 1)) | (1L << (LIMIT - 1)) | (1L << (MAPPED - 1)) | (1L << (MATCH - 1)) | (1L << (MINUTE - 1)) | (1L << (MONTH - 1)) | (1L << (NOT - 1)) | (1L << (NULL - 1)))) != 0) || ((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (OPTIMIZED - 67)) | (1L << (PARSED - 67)) | (1L << (PHYSICAL - 67)) | (1L << (PLAN - 67)) | (1L << (RIGHT - 67)) | (1L << (RLIKE - 67)) | (1L << (QUERY - 67)) | (1L << (SCHEMAS - 67)) | (1L << (SECOND - 67)) | (1L << (SHOW - 67)) | (1L << (SYS - 67)) | (1L << (TABLES - 67)) | (1L << (TEXT - 67)) | (1L << (TRUE - 67)) | (1L << (TYPE - 67)) | (1L << (TYPES - 67)) | (1L << (VERIFY - 67)) | (1L << (YEAR - 67)) | (1L << (FUNCTION_ESC - 67)) | (1L << (DATE_ESC - 67)) | (1L << (TIME_ESC - 67)) | (1L << (TIMESTAMP_ESC - 67)) | (1L << (GUID_ESC - 67)) | (1L << (PLUS - 67)) | (1L << (MINUS - 67)) | (1L << (ASTERISK - 67)) | (1L << (PARAM - 67)) | (1L << (STRING - 67)) | (1L << (INTEGER_VALUE - 67)) | (1L << (DECIMAL_VALUE - 67)) | (1L << (IDENTIFIER - 67)) | (1L << (DIGIT_IDENTIFIER - 67)) | (1L << (QUOTED_IDENTIFIER - 67)) | (1L << (BACKQUOTED_IDENTIFIER - 67)))) != 0)) { { - setState(319); + setState(321); expression(); - setState(324); + setState(326); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(320); + setState(322); match(T__2); - setState(321); + setState(323); expression(); } } - setState(326); + setState(328); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(329); + setState(331); match(T__1); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(330); + setState(332); expression(); } break; @@ -2105,15 +2107,15 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(333); - ((NamedQueryContext)_localctx).name = identifier(); - setState(334); - match(AS); setState(335); - match(T__0); + ((NamedQueryContext)_localctx).name = identifier(); setState(336); - queryNoWith(); + match(AS); setState(337); + match(T__0); + setState(338); + queryNoWith(); + setState(339); match(T__1); } } @@ -2157,7 +2159,7 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(339); + setState(341); _la = _input.LA(1); if ( !(_la==ALL || _la==DISTINCT) ) { _errHandler.recoverInline(this); @@ -2220,23 +2222,23 @@ class SqlBaseParser extends Parser { _localctx = new SelectExpressionContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(341); + setState(343); expression(); - setState(346); + setState(348); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,42,_ctx) ) { case 1: { - setState(343); + setState(345); _la = _input.LA(1); if (_la==AS) { { - setState(342); + setState(344); match(AS); } } - setState(345); + setState(347); identifier(); } break; @@ -2290,19 +2292,19 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(348); + setState(350); relationPrimary(); - setState(352); + setState(354); _errHandler.sync(this); _la = _input.LA(1); - while (((((_la - 37)) & ~0x3f) == 0 && ((1L << (_la - 37)) & ((1L << (FULL - 37)) | (1L << (INNER - 37)) | (1L << (JOIN - 37)) | (1L << (LEFT - 37)) | (1L << (NATURAL - 37)) | (1L << (RIGHT - 37)))) != 0)) { + while (((((_la - 40)) & ~0x3f) == 0 && ((1L << (_la - 40)) & ((1L << (FULL - 40)) | (1L << (INNER - 40)) | (1L << (JOIN - 40)) | (1L << (LEFT - 40)) | (1L << (NATURAL - 40)) | (1L << (RIGHT - 40)))) != 0)) { { { - setState(349); + setState(351); joinRelation(); } } - setState(354); + setState(356); _errHandler.sync(this); _la = _input.LA(1); } @@ -2356,7 +2358,7 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 34, RULE_joinRelation); int _la; try { - setState(366); + setState(368); switch (_input.LA(1)) { case FULL: case INNER: @@ -2366,18 +2368,18 @@ class SqlBaseParser extends Parser { enterOuterAlt(_localctx, 1); { { - setState(355); + setState(357); joinType(); } - setState(356); + setState(358); match(JOIN); - setState(357); - ((JoinRelationContext)_localctx).right = relationPrimary(); setState(359); + ((JoinRelationContext)_localctx).right = relationPrimary(); + setState(361); _la = _input.LA(1); if (_la==ON || _la==USING) { { - setState(358); + setState(360); joinCriteria(); } } @@ -2387,13 +2389,13 @@ class SqlBaseParser extends Parser { case NATURAL: enterOuterAlt(_localctx, 2); { - setState(361); - match(NATURAL); - setState(362); - joinType(); setState(363); - match(JOIN); + match(NATURAL); setState(364); + joinType(); + setState(365); + match(JOIN); + setState(366); ((JoinRelationContext)_localctx).right = relationPrimary(); } break; @@ -2442,17 +2444,17 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 36, RULE_joinType); int _la; try { - setState(383); + setState(385); switch (_input.LA(1)) { case INNER: case JOIN: enterOuterAlt(_localctx, 1); { - setState(369); + setState(371); _la = _input.LA(1); if (_la==INNER) { { - setState(368); + setState(370); match(INNER); } } @@ -2462,13 +2464,13 @@ class SqlBaseParser extends Parser { case LEFT: enterOuterAlt(_localctx, 2); { - setState(371); - match(LEFT); setState(373); + match(LEFT); + setState(375); _la = _input.LA(1); if (_la==OUTER) { { - setState(372); + setState(374); match(OUTER); } } @@ -2478,13 +2480,13 @@ class SqlBaseParser extends Parser { case RIGHT: enterOuterAlt(_localctx, 3); { - setState(375); - match(RIGHT); setState(377); + match(RIGHT); + setState(379); _la = _input.LA(1); if (_la==OUTER) { { - setState(376); + setState(378); match(OUTER); } } @@ -2494,13 +2496,13 @@ class SqlBaseParser extends Parser { case FULL: enterOuterAlt(_localctx, 4); { - setState(379); - match(FULL); setState(381); + match(FULL); + setState(383); _la = _input.LA(1); if (_la==OUTER) { { - setState(380); + setState(382); match(OUTER); } } @@ -2558,43 +2560,43 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 38, RULE_joinCriteria); int _la; try { - setState(399); + setState(401); switch (_input.LA(1)) { case ON: enterOuterAlt(_localctx, 1); { - setState(385); + setState(387); match(ON); - setState(386); + setState(388); booleanExpression(0); } break; case USING: enterOuterAlt(_localctx, 2); { - setState(387); - match(USING); - setState(388); - match(T__0); setState(389); + match(USING); + setState(390); + match(T__0); + setState(391); identifier(); - setState(394); + setState(396); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(390); + setState(392); match(T__2); - setState(391); + setState(393); identifier(); } } - setState(396); + setState(398); _errHandler.sync(this); _la = _input.LA(1); } - setState(397); + setState(399); match(T__1); } break; @@ -2699,30 +2701,30 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 40, RULE_relationPrimary); int _la; try { - setState(426); + setState(428); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,59,_ctx) ) { case 1: _localctx = new TableNameContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(401); + setState(403); tableIdentifier(); - setState(406); + setState(408); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,54,_ctx) ) { case 1: { - setState(403); + setState(405); _la = _input.LA(1); if (_la==AS) { { - setState(402); + setState(404); match(AS); } } - setState(405); + setState(407); qualifiedName(); } break; @@ -2733,27 +2735,27 @@ class SqlBaseParser extends Parser { _localctx = new AliasedQueryContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(408); - match(T__0); - setState(409); - queryNoWith(); setState(410); + match(T__0); + setState(411); + queryNoWith(); + setState(412); match(T__1); - setState(415); + setState(417); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,56,_ctx) ) { case 1: { - setState(412); + setState(414); _la = _input.LA(1); if (_la==AS) { { - setState(411); + setState(413); match(AS); } } - setState(414); + setState(416); qualifiedName(); } break; @@ -2764,27 +2766,27 @@ class SqlBaseParser extends Parser { _localctx = new AliasedRelationContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(417); - match(T__0); - setState(418); - relation(); setState(419); + match(T__0); + setState(420); + relation(); + setState(421); match(T__1); - setState(424); + setState(426); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,58,_ctx) ) { case 1: { - setState(421); + setState(423); _la = _input.LA(1); if (_la==AS) { { - setState(420); + setState(422); match(AS); } } - setState(423); + setState(425); qualifiedName(); } break; @@ -2833,7 +2835,7 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(428); + setState(430); booleanExpression(0); } } @@ -3041,7 +3043,7 @@ class SqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(461); + setState(463); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,60,_ctx) ) { case 1: @@ -3050,9 +3052,9 @@ class SqlBaseParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(431); + setState(433); match(NOT); - setState(432); + setState(434); booleanExpression(8); } break; @@ -3061,13 +3063,13 @@ class SqlBaseParser extends Parser { _localctx = new ExistsContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(433); - match(EXISTS); - setState(434); - match(T__0); setState(435); - query(); + match(EXISTS); setState(436); + match(T__0); + setState(437); + query(); + setState(438); match(T__1); } break; @@ -3076,15 +3078,15 @@ class SqlBaseParser extends Parser { _localctx = new StringQueryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(438); - match(QUERY); - setState(439); - match(T__0); setState(440); - ((StringQueryContext)_localctx).queryString = string(); + match(QUERY); setState(441); - matchQueryOptions(); + match(T__0); setState(442); + ((StringQueryContext)_localctx).queryString = string(); + setState(443); + matchQueryOptions(); + setState(444); match(T__1); } break; @@ -3093,19 +3095,19 @@ class SqlBaseParser extends Parser { _localctx = new MatchQueryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(444); - match(MATCH); - setState(445); - match(T__0); setState(446); - ((MatchQueryContext)_localctx).singleField = qualifiedName(); + match(MATCH); setState(447); - match(T__2); + match(T__0); setState(448); - ((MatchQueryContext)_localctx).queryString = string(); + ((MatchQueryContext)_localctx).singleField = qualifiedName(); setState(449); - matchQueryOptions(); + match(T__2); setState(450); + ((MatchQueryContext)_localctx).queryString = string(); + setState(451); + matchQueryOptions(); + setState(452); match(T__1); } break; @@ -3114,19 +3116,19 @@ class SqlBaseParser extends Parser { _localctx = new MultiMatchQueryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(452); - match(MATCH); - setState(453); - match(T__0); setState(454); - ((MultiMatchQueryContext)_localctx).multiFields = string(); + match(MATCH); setState(455); - match(T__2); + match(T__0); setState(456); - ((MultiMatchQueryContext)_localctx).queryString = string(); + ((MultiMatchQueryContext)_localctx).multiFields = string(); setState(457); - matchQueryOptions(); + match(T__2); setState(458); + ((MultiMatchQueryContext)_localctx).queryString = string(); + setState(459); + matchQueryOptions(); + setState(460); match(T__1); } break; @@ -3135,13 +3137,13 @@ class SqlBaseParser extends Parser { _localctx = new BooleanDefaultContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(460); + setState(462); predicated(); } break; } _ctx.stop = _input.LT(-1); - setState(471); + setState(473); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,62,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -3149,7 +3151,7 @@ class SqlBaseParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(469); + setState(471); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,61,_ctx) ) { case 1: @@ -3157,11 +3159,11 @@ class SqlBaseParser extends Parser { _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); ((LogicalBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression); - setState(463); - if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); - setState(464); - ((LogicalBinaryContext)_localctx).operator = match(AND); setState(465); + if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); + setState(466); + ((LogicalBinaryContext)_localctx).operator = match(AND); + setState(467); ((LogicalBinaryContext)_localctx).right = booleanExpression(3); } break; @@ -3170,18 +3172,18 @@ class SqlBaseParser extends Parser { _localctx = new LogicalBinaryContext(new BooleanExpressionContext(_parentctx, _parentState)); ((LogicalBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_booleanExpression); - setState(466); - if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(467); - ((LogicalBinaryContext)_localctx).operator = match(OR); setState(468); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(469); + ((LogicalBinaryContext)_localctx).operator = match(OR); + setState(470); ((LogicalBinaryContext)_localctx).right = booleanExpression(2); } break; } } } - setState(473); + setState(475); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,62,_ctx); } @@ -3231,19 +3233,19 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(478); + setState(480); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(474); + setState(476); match(T__2); - setState(475); + setState(477); string(); } } - setState(480); + setState(482); _errHandler.sync(this); _la = _input.LA(1); } @@ -3292,14 +3294,14 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(481); - valueExpression(0); setState(483); + valueExpression(0); + setState(485); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,64,_ctx) ) { case 1: { - setState(482); + setState(484); predicate(); } break; @@ -3369,142 +3371,142 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 50, RULE_predicate); int _la; try { - setState(531); + setState(533); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,72,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(486); + setState(488); _la = _input.LA(1); if (_la==NOT) { { - setState(485); + setState(487); match(NOT); } } - setState(488); - ((PredicateContext)_localctx).kind = match(BETWEEN); - setState(489); - ((PredicateContext)_localctx).lower = valueExpression(0); setState(490); - match(AND); + ((PredicateContext)_localctx).kind = match(BETWEEN); setState(491); + ((PredicateContext)_localctx).lower = valueExpression(0); + setState(492); + match(AND); + setState(493); ((PredicateContext)_localctx).upper = valueExpression(0); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(494); + setState(496); _la = _input.LA(1); if (_la==NOT) { { - setState(493); + setState(495); match(NOT); } } - setState(496); - ((PredicateContext)_localctx).kind = match(IN); - setState(497); - match(T__0); setState(498); + ((PredicateContext)_localctx).kind = match(IN); + setState(499); + match(T__0); + setState(500); valueExpression(0); - setState(503); + setState(505); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(499); + setState(501); match(T__2); - setState(500); + setState(502); valueExpression(0); } } - setState(505); + setState(507); _errHandler.sync(this); _la = _input.LA(1); } - setState(506); + setState(508); match(T__1); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(509); + setState(511); _la = _input.LA(1); if (_la==NOT) { { - setState(508); + setState(510); match(NOT); } } - setState(511); - ((PredicateContext)_localctx).kind = match(IN); - setState(512); - match(T__0); setState(513); - query(); + ((PredicateContext)_localctx).kind = match(IN); setState(514); + match(T__0); + setState(515); + query(); + setState(516); match(T__1); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(517); + setState(519); _la = _input.LA(1); if (_la==NOT) { { - setState(516); + setState(518); match(NOT); } } - setState(519); + setState(521); ((PredicateContext)_localctx).kind = match(LIKE); - setState(520); + setState(522); pattern(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(522); + setState(524); _la = _input.LA(1); if (_la==NOT) { { - setState(521); + setState(523); match(NOT); } } - setState(524); + setState(526); ((PredicateContext)_localctx).kind = match(RLIKE); - setState(525); + setState(527); ((PredicateContext)_localctx).regex = string(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(526); - match(IS); setState(528); + match(IS); + setState(530); _la = _input.LA(1); if (_la==NOT) { { - setState(527); + setState(529); match(NOT); } } - setState(530); + setState(532); ((PredicateContext)_localctx).kind = match(NULL); } break; @@ -3551,9 +3553,9 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(533); + setState(535); match(LIKE); - setState(534); + setState(536); pattern(); } } @@ -3601,14 +3603,14 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(536); - ((PatternContext)_localctx).value = string(); setState(538); + ((PatternContext)_localctx).value = string(); + setState(540); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,73,_ctx) ) { case 1: { - setState(537); + setState(539); patternEscape(); } break; @@ -3656,25 +3658,25 @@ class SqlBaseParser extends Parser { PatternEscapeContext _localctx = new PatternEscapeContext(_ctx, getState()); enterRule(_localctx, 56, RULE_patternEscape); try { - setState(546); + setState(548); switch (_input.LA(1)) { case ESCAPE: enterOuterAlt(_localctx, 1); { - setState(540); + setState(542); match(ESCAPE); - setState(541); + setState(543); ((PatternEscapeContext)_localctx).escape = string(); } break; case ESCAPE_ESC: enterOuterAlt(_localctx, 2); { - setState(542); - match(ESCAPE_ESC); - setState(543); - ((PatternEscapeContext)_localctx).escape = string(); setState(544); + match(ESCAPE_ESC); + setState(545); + ((PatternEscapeContext)_localctx).escape = string(); + setState(546); match(ESC_END); } break; @@ -3819,11 +3821,12 @@ class SqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(552); + setState(554); switch (_input.LA(1)) { case T__0: case ANALYZE: case ANALYZED: + case CASE: case CAST: case CATALOGS: case COLUMNS: @@ -3888,7 +3891,7 @@ class SqlBaseParser extends Parser { _ctx = _localctx; _prevctx = _localctx; - setState(549); + setState(551); primaryExpression(0); } break; @@ -3898,7 +3901,7 @@ class SqlBaseParser extends Parser { _localctx = new ArithmeticUnaryContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(550); + setState(552); ((ArithmeticUnaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { @@ -3906,7 +3909,7 @@ class SqlBaseParser extends Parser { } else { consume(); } - setState(551); + setState(553); valueExpression(4); } break; @@ -3914,7 +3917,7 @@ class SqlBaseParser extends Parser { throw new NoViableAltException(this); } _ctx.stop = _input.LT(-1); - setState(566); + setState(568); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,77,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -3922,7 +3925,7 @@ class SqlBaseParser extends Parser { if ( _parseListeners!=null ) triggerExitRuleEvent(); _prevctx = _localctx; { - setState(564); + setState(566); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,76,_ctx) ) { case 1: @@ -3930,17 +3933,17 @@ class SqlBaseParser extends Parser { _localctx = new ArithmeticBinaryContext(new ValueExpressionContext(_parentctx, _parentState)); ((ArithmeticBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_valueExpression); - setState(554); + setState(556); if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); - setState(555); + setState(557); ((ArithmeticBinaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); - if ( !(((((_la - 110)) & ~0x3f) == 0 && ((1L << (_la - 110)) & ((1L << (ASTERISK - 110)) | (1L << (SLASH - 110)) | (1L << (PERCENT - 110)))) != 0)) ) { + if ( !(((((_la - 115)) & ~0x3f) == 0 && ((1L << (_la - 115)) & ((1L << (ASTERISK - 115)) | (1L << (SLASH - 115)) | (1L << (PERCENT - 115)))) != 0)) ) { ((ArithmeticBinaryContext)_localctx).operator = (Token)_errHandler.recoverInline(this); } else { consume(); } - setState(556); + setState(558); ((ArithmeticBinaryContext)_localctx).right = valueExpression(4); } break; @@ -3949,9 +3952,9 @@ class SqlBaseParser extends Parser { _localctx = new ArithmeticBinaryContext(new ValueExpressionContext(_parentctx, _parentState)); ((ArithmeticBinaryContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_valueExpression); - setState(557); + setState(559); if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); - setState(558); + setState(560); ((ArithmeticBinaryContext)_localctx).operator = _input.LT(1); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { @@ -3959,7 +3962,7 @@ class SqlBaseParser extends Parser { } else { consume(); } - setState(559); + setState(561); ((ArithmeticBinaryContext)_localctx).right = valueExpression(3); } break; @@ -3968,18 +3971,18 @@ class SqlBaseParser extends Parser { _localctx = new ComparisonContext(new ValueExpressionContext(_parentctx, _parentState)); ((ComparisonContext)_localctx).left = _prevctx; pushNewRecursionContext(_localctx, _startState, RULE_valueExpression); - setState(560); - if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); - setState(561); - comparisonOperator(); setState(562); + if (!(precpred(_ctx, 1))) throw new FailedPredicateException(this, "precpred(_ctx, 1)"); + setState(563); + comparisonOperator(); + setState(564); ((ComparisonContext)_localctx).right = valueExpression(2); } break; } } } - setState(568); + setState(570); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,77,_ctx); } @@ -4203,6 +4206,39 @@ class SqlBaseParser extends Parser { else return visitor.visitChildren(this); } } + public static class CaseContext extends PrimaryExpressionContext { + public BooleanExpressionContext operand; + public BooleanExpressionContext elseClause; + public TerminalNode CASE() { return getToken(SqlBaseParser.CASE, 0); } + public TerminalNode END() { return getToken(SqlBaseParser.END, 0); } + public List whenClause() { + return getRuleContexts(WhenClauseContext.class); + } + public WhenClauseContext whenClause(int i) { + return getRuleContext(WhenClauseContext.class,i); + } + public TerminalNode ELSE() { return getToken(SqlBaseParser.ELSE, 0); } + public List booleanExpression() { + return getRuleContexts(BooleanExpressionContext.class); + } + public BooleanExpressionContext booleanExpression(int i) { + return getRuleContext(BooleanExpressionContext.class,i); + } + public CaseContext(PrimaryExpressionContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SqlBaseListener ) ((SqlBaseListener)listener).enterCase(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SqlBaseListener ) ((SqlBaseListener)listener).exitCase(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof SqlBaseVisitor ) return ((SqlBaseVisitor)visitor).visitCase(this); + else return visitor.visitChildren(this); + } + } public final PrimaryExpressionContext primaryExpression() throws RecognitionException { return primaryExpression(0); @@ -4220,16 +4256,16 @@ class SqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(590); + setState(607); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,79,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,82,_ctx) ) { case 1: { _localctx = new CastContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(570); + setState(572); castExpression(); } break; @@ -4238,7 +4274,7 @@ class SqlBaseParser extends Parser { _localctx = new ExtractContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(571); + setState(573); extractExpression(); } break; @@ -4247,7 +4283,7 @@ class SqlBaseParser extends Parser { _localctx = new CurrentDateTimeFunctionContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(572); + setState(574); builtinDateTimeFunction(); } break; @@ -4256,7 +4292,7 @@ class SqlBaseParser extends Parser { _localctx = new ConstantDefaultContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(573); + setState(575); constant(); } break; @@ -4265,18 +4301,18 @@ class SqlBaseParser extends Parser { _localctx = new StarContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(577); + setState(579); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << CATALOGS) | (1L << COLUMNS) | (1L << CURRENT_DATE) | (1L << CURRENT_TIME) | (1L << CURRENT_TIMESTAMP) | (1L << DAY) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FIRST) | (1L << FORMAT) | (1L << FULL) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << HOUR) | (1L << INTERVAL) | (1L << LAST) | (1L << LIMIT) | (1L << MAPPED) | (1L << MINUTE) | (1L << MONTH))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (OPTIMIZED - 64)) | (1L << (PARSED - 64)) | (1L << (PHYSICAL - 64)) | (1L << (PLAN - 64)) | (1L << (RLIKE - 64)) | (1L << (QUERY - 64)) | (1L << (SCHEMAS - 64)) | (1L << (SECOND - 64)) | (1L << (SHOW - 64)) | (1L << (SYS - 64)) | (1L << (TABLES - 64)) | (1L << (TEXT - 64)) | (1L << (TYPE - 64)) | (1L << (TYPES - 64)) | (1L << (VERIFY - 64)) | (1L << (YEAR - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << CATALOGS) | (1L << COLUMNS) | (1L << CURRENT_DATE) | (1L << CURRENT_TIME) | (1L << CURRENT_TIMESTAMP) | (1L << DAY) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FIRST) | (1L << FORMAT) | (1L << FULL) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << HOUR) | (1L << INTERVAL) | (1L << LAST) | (1L << LIMIT) | (1L << MAPPED) | (1L << MINUTE) | (1L << MONTH))) != 0) || ((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (OPTIMIZED - 67)) | (1L << (PARSED - 67)) | (1L << (PHYSICAL - 67)) | (1L << (PLAN - 67)) | (1L << (RLIKE - 67)) | (1L << (QUERY - 67)) | (1L << (SCHEMAS - 67)) | (1L << (SECOND - 67)) | (1L << (SHOW - 67)) | (1L << (SYS - 67)) | (1L << (TABLES - 67)) | (1L << (TEXT - 67)) | (1L << (TYPE - 67)) | (1L << (TYPES - 67)) | (1L << (VERIFY - 67)) | (1L << (YEAR - 67)) | (1L << (IDENTIFIER - 67)) | (1L << (DIGIT_IDENTIFIER - 67)) | (1L << (QUOTED_IDENTIFIER - 67)) | (1L << (BACKQUOTED_IDENTIFIER - 67)))) != 0)) { { - setState(574); + setState(576); qualifiedName(); - setState(575); + setState(577); match(DOT); } } - setState(579); + setState(581); match(ASTERISK); } break; @@ -4285,7 +4321,7 @@ class SqlBaseParser extends Parser { _localctx = new FunctionContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(580); + setState(582); functionExpression(); } break; @@ -4294,11 +4330,11 @@ class SqlBaseParser extends Parser { _localctx = new SubqueryExpressionContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(581); - match(T__0); - setState(582); - query(); setState(583); + match(T__0); + setState(584); + query(); + setState(585); match(T__1); } break; @@ -4307,7 +4343,7 @@ class SqlBaseParser extends Parser { _localctx = new DereferenceContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(585); + setState(587); qualifiedName(); } break; @@ -4316,19 +4352,64 @@ class SqlBaseParser extends Parser { _localctx = new ParenthesizedExpressionContext(_localctx); _ctx = _localctx; _prevctx = _localctx; - setState(586); - match(T__0); - setState(587); - expression(); setState(588); + match(T__0); + setState(589); + expression(); + setState(590); match(T__1); } break; + case 10: + { + _localctx = new CaseContext(_localctx); + _ctx = _localctx; + _prevctx = _localctx; + setState(592); + match(CASE); + setState(594); + _la = _input.LA(1); + if (((((_la - 1)) & ~0x3f) == 0 && ((1L << (_la - 1)) & ((1L << (T__0 - 1)) | (1L << (ANALYZE - 1)) | (1L << (ANALYZED - 1)) | (1L << (CASE - 1)) | (1L << (CAST - 1)) | (1L << (CATALOGS - 1)) | (1L << (COLUMNS - 1)) | (1L << (CONVERT - 1)) | (1L << (CURRENT_DATE - 1)) | (1L << (CURRENT_TIME - 1)) | (1L << (CURRENT_TIMESTAMP - 1)) | (1L << (DAY - 1)) | (1L << (DEBUG - 1)) | (1L << (EXECUTABLE - 1)) | (1L << (EXISTS - 1)) | (1L << (EXPLAIN - 1)) | (1L << (EXTRACT - 1)) | (1L << (FALSE - 1)) | (1L << (FIRST - 1)) | (1L << (FORMAT - 1)) | (1L << (FULL - 1)) | (1L << (FUNCTIONS - 1)) | (1L << (GRAPHVIZ - 1)) | (1L << (HOUR - 1)) | (1L << (INTERVAL - 1)) | (1L << (LAST - 1)) | (1L << (LEFT - 1)) | (1L << (LIMIT - 1)) | (1L << (MAPPED - 1)) | (1L << (MATCH - 1)) | (1L << (MINUTE - 1)) | (1L << (MONTH - 1)) | (1L << (NOT - 1)) | (1L << (NULL - 1)))) != 0) || ((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (OPTIMIZED - 67)) | (1L << (PARSED - 67)) | (1L << (PHYSICAL - 67)) | (1L << (PLAN - 67)) | (1L << (RIGHT - 67)) | (1L << (RLIKE - 67)) | (1L << (QUERY - 67)) | (1L << (SCHEMAS - 67)) | (1L << (SECOND - 67)) | (1L << (SHOW - 67)) | (1L << (SYS - 67)) | (1L << (TABLES - 67)) | (1L << (TEXT - 67)) | (1L << (TRUE - 67)) | (1L << (TYPE - 67)) | (1L << (TYPES - 67)) | (1L << (VERIFY - 67)) | (1L << (YEAR - 67)) | (1L << (FUNCTION_ESC - 67)) | (1L << (DATE_ESC - 67)) | (1L << (TIME_ESC - 67)) | (1L << (TIMESTAMP_ESC - 67)) | (1L << (GUID_ESC - 67)) | (1L << (PLUS - 67)) | (1L << (MINUS - 67)) | (1L << (ASTERISK - 67)) | (1L << (PARAM - 67)) | (1L << (STRING - 67)) | (1L << (INTEGER_VALUE - 67)) | (1L << (DECIMAL_VALUE - 67)) | (1L << (IDENTIFIER - 67)) | (1L << (DIGIT_IDENTIFIER - 67)) | (1L << (QUOTED_IDENTIFIER - 67)) | (1L << (BACKQUOTED_IDENTIFIER - 67)))) != 0)) { + { + setState(593); + ((CaseContext)_localctx).operand = booleanExpression(0); + } + } + + setState(597); + _errHandler.sync(this); + _la = _input.LA(1); + do { + { + { + setState(596); + whenClause(); + } + } + setState(599); + _errHandler.sync(this); + _la = _input.LA(1); + } while ( _la==WHEN ); + setState(603); + _la = _input.LA(1); + if (_la==ELSE) { + { + setState(601); + match(ELSE); + setState(602); + ((CaseContext)_localctx).elseClause = booleanExpression(0); + } + } + + setState(605); + match(END); + } + break; } _ctx.stop = _input.LT(-1); - setState(597); + setState(614); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,80,_ctx); + _alt = getInterpreter().adaptivePredict(_input,83,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { if ( _parseListeners!=null ) triggerExitRuleEvent(); @@ -4337,18 +4418,18 @@ class SqlBaseParser extends Parser { { _localctx = new CastOperatorExpressionContext(new PrimaryExpressionContext(_parentctx, _parentState)); pushNewRecursionContext(_localctx, _startState, RULE_primaryExpression); - setState(592); - if (!(precpred(_ctx, 9))) throw new FailedPredicateException(this, "precpred(_ctx, 9)"); - setState(593); + setState(609); + if (!(precpred(_ctx, 10))) throw new FailedPredicateException(this, "precpred(_ctx, 10)"); + setState(610); match(CAST_OP); - setState(594); + setState(611); dataType(); } } } - setState(599); + setState(616); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,80,_ctx); + _alt = getInterpreter().adaptivePredict(_input,83,_ctx); } } } @@ -4391,26 +4472,26 @@ class SqlBaseParser extends Parser { BuiltinDateTimeFunctionContext _localctx = new BuiltinDateTimeFunctionContext(_ctx, getState()); enterRule(_localctx, 62, RULE_builtinDateTimeFunction); try { - setState(603); + setState(620); switch (_input.LA(1)) { case CURRENT_TIMESTAMP: enterOuterAlt(_localctx, 1); { - setState(600); + setState(617); ((BuiltinDateTimeFunctionContext)_localctx).name = match(CURRENT_TIMESTAMP); } break; case CURRENT_DATE: enterOuterAlt(_localctx, 2); { - setState(601); + setState(618); ((BuiltinDateTimeFunctionContext)_localctx).name = match(CURRENT_DATE); } break; case CURRENT_TIME: enterOuterAlt(_localctx, 3); { - setState(602); + setState(619); ((BuiltinDateTimeFunctionContext)_localctx).name = match(CURRENT_TIME); } break; @@ -4461,42 +4542,42 @@ class SqlBaseParser extends Parser { CastExpressionContext _localctx = new CastExpressionContext(_ctx, getState()); enterRule(_localctx, 64, RULE_castExpression); try { - setState(615); + setState(632); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,82,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,85,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(605); + setState(622); castTemplate(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(606); + setState(623); match(FUNCTION_ESC); - setState(607); + setState(624); castTemplate(); - setState(608); + setState(625); match(ESC_END); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(610); + setState(627); convertTemplate(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(611); + setState(628); match(FUNCTION_ESC); - setState(612); + setState(629); convertTemplate(); - setState(613); + setState(630); match(ESC_END); } break; @@ -4547,17 +4628,17 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(617); + setState(634); match(CAST); - setState(618); + setState(635); match(T__0); - setState(619); + setState(636); expression(); - setState(620); + setState(637); match(AS); - setState(621); + setState(638); dataType(); - setState(622); + setState(639); match(T__1); } } @@ -4605,17 +4686,17 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(624); + setState(641); match(CONVERT); - setState(625); + setState(642); match(T__0); - setState(626); + setState(643); expression(); - setState(627); + setState(644); match(T__2); - setState(628); + setState(645); dataType(); - setState(629); + setState(646); match(T__1); } } @@ -4659,23 +4740,23 @@ class SqlBaseParser extends Parser { ExtractExpressionContext _localctx = new ExtractExpressionContext(_ctx, getState()); enterRule(_localctx, 70, RULE_extractExpression); try { - setState(636); + setState(653); switch (_input.LA(1)) { case EXTRACT: enterOuterAlt(_localctx, 1); { - setState(631); + setState(648); extractTemplate(); } break; case FUNCTION_ESC: enterOuterAlt(_localctx, 2); { - setState(632); + setState(649); match(FUNCTION_ESC); - setState(633); + setState(650); extractTemplate(); - setState(634); + setState(651); match(ESC_END); } break; @@ -4729,17 +4810,17 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(638); + setState(655); match(EXTRACT); - setState(639); + setState(656); match(T__0); - setState(640); + setState(657); ((ExtractTemplateContext)_localctx).field = identifier(); - setState(641); + setState(658); match(FROM); - setState(642); + setState(659); valueExpression(0); - setState(643); + setState(660); match(T__1); } } @@ -4782,7 +4863,7 @@ class SqlBaseParser extends Parser { FunctionExpressionContext _localctx = new FunctionExpressionContext(_ctx, getState()); enterRule(_localctx, 74, RULE_functionExpression); try { - setState(650); + setState(667); switch (_input.LA(1)) { case ANALYZE: case ANALYZED: @@ -4831,18 +4912,18 @@ class SqlBaseParser extends Parser { case BACKQUOTED_IDENTIFIER: enterOuterAlt(_localctx, 1); { - setState(645); + setState(662); functionTemplate(); } break; case FUNCTION_ESC: enterOuterAlt(_localctx, 2); { - setState(646); + setState(663); match(FUNCTION_ESC); - setState(647); + setState(664); functionTemplate(); - setState(648); + setState(665); match(ESC_END); } break; @@ -4900,45 +4981,45 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(652); + setState(669); functionName(); - setState(653); + setState(670); match(T__0); - setState(665); + setState(682); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__0) | (1L << ALL) | (1L << ANALYZE) | (1L << ANALYZED) | (1L << CAST) | (1L << CATALOGS) | (1L << COLUMNS) | (1L << CONVERT) | (1L << CURRENT_DATE) | (1L << CURRENT_TIME) | (1L << CURRENT_TIMESTAMP) | (1L << DAY) | (1L << DEBUG) | (1L << DISTINCT) | (1L << EXECUTABLE) | (1L << EXISTS) | (1L << EXPLAIN) | (1L << EXTRACT) | (1L << FALSE) | (1L << FIRST) | (1L << FORMAT) | (1L << FULL) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << HOUR) | (1L << INTERVAL) | (1L << LAST) | (1L << LEFT) | (1L << LIMIT) | (1L << MAPPED) | (1L << MATCH) | (1L << MINUTE) | (1L << MONTH) | (1L << NOT) | (1L << NULL))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (OPTIMIZED - 64)) | (1L << (PARSED - 64)) | (1L << (PHYSICAL - 64)) | (1L << (PLAN - 64)) | (1L << (RIGHT - 64)) | (1L << (RLIKE - 64)) | (1L << (QUERY - 64)) | (1L << (SCHEMAS - 64)) | (1L << (SECOND - 64)) | (1L << (SHOW - 64)) | (1L << (SYS - 64)) | (1L << (TABLES - 64)) | (1L << (TEXT - 64)) | (1L << (TRUE - 64)) | (1L << (TYPE - 64)) | (1L << (TYPES - 64)) | (1L << (VERIFY - 64)) | (1L << (YEAR - 64)) | (1L << (FUNCTION_ESC - 64)) | (1L << (DATE_ESC - 64)) | (1L << (TIME_ESC - 64)) | (1L << (TIMESTAMP_ESC - 64)) | (1L << (GUID_ESC - 64)) | (1L << (PLUS - 64)) | (1L << (MINUS - 64)) | (1L << (ASTERISK - 64)) | (1L << (PARAM - 64)) | (1L << (STRING - 64)) | (1L << (INTEGER_VALUE - 64)) | (1L << (DECIMAL_VALUE - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { + if (((((_la - 1)) & ~0x3f) == 0 && ((1L << (_la - 1)) & ((1L << (T__0 - 1)) | (1L << (ALL - 1)) | (1L << (ANALYZE - 1)) | (1L << (ANALYZED - 1)) | (1L << (CASE - 1)) | (1L << (CAST - 1)) | (1L << (CATALOGS - 1)) | (1L << (COLUMNS - 1)) | (1L << (CONVERT - 1)) | (1L << (CURRENT_DATE - 1)) | (1L << (CURRENT_TIME - 1)) | (1L << (CURRENT_TIMESTAMP - 1)) | (1L << (DAY - 1)) | (1L << (DEBUG - 1)) | (1L << (DISTINCT - 1)) | (1L << (EXECUTABLE - 1)) | (1L << (EXISTS - 1)) | (1L << (EXPLAIN - 1)) | (1L << (EXTRACT - 1)) | (1L << (FALSE - 1)) | (1L << (FIRST - 1)) | (1L << (FORMAT - 1)) | (1L << (FULL - 1)) | (1L << (FUNCTIONS - 1)) | (1L << (GRAPHVIZ - 1)) | (1L << (HOUR - 1)) | (1L << (INTERVAL - 1)) | (1L << (LAST - 1)) | (1L << (LEFT - 1)) | (1L << (LIMIT - 1)) | (1L << (MAPPED - 1)) | (1L << (MATCH - 1)) | (1L << (MINUTE - 1)) | (1L << (MONTH - 1)) | (1L << (NOT - 1)) | (1L << (NULL - 1)))) != 0) || ((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (OPTIMIZED - 67)) | (1L << (PARSED - 67)) | (1L << (PHYSICAL - 67)) | (1L << (PLAN - 67)) | (1L << (RIGHT - 67)) | (1L << (RLIKE - 67)) | (1L << (QUERY - 67)) | (1L << (SCHEMAS - 67)) | (1L << (SECOND - 67)) | (1L << (SHOW - 67)) | (1L << (SYS - 67)) | (1L << (TABLES - 67)) | (1L << (TEXT - 67)) | (1L << (TRUE - 67)) | (1L << (TYPE - 67)) | (1L << (TYPES - 67)) | (1L << (VERIFY - 67)) | (1L << (YEAR - 67)) | (1L << (FUNCTION_ESC - 67)) | (1L << (DATE_ESC - 67)) | (1L << (TIME_ESC - 67)) | (1L << (TIMESTAMP_ESC - 67)) | (1L << (GUID_ESC - 67)) | (1L << (PLUS - 67)) | (1L << (MINUS - 67)) | (1L << (ASTERISK - 67)) | (1L << (PARAM - 67)) | (1L << (STRING - 67)) | (1L << (INTEGER_VALUE - 67)) | (1L << (DECIMAL_VALUE - 67)) | (1L << (IDENTIFIER - 67)) | (1L << (DIGIT_IDENTIFIER - 67)) | (1L << (QUOTED_IDENTIFIER - 67)) | (1L << (BACKQUOTED_IDENTIFIER - 67)))) != 0)) { { - setState(655); + setState(672); _la = _input.LA(1); if (_la==ALL || _la==DISTINCT) { { - setState(654); + setState(671); setQuantifier(); } } - setState(657); + setState(674); expression(); - setState(662); + setState(679); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__2) { { { - setState(658); + setState(675); match(T__2); - setState(659); + setState(676); expression(); } } - setState(664); + setState(681); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(667); + setState(684); match(T__1); } } @@ -4982,19 +5063,19 @@ class SqlBaseParser extends Parser { FunctionNameContext _localctx = new FunctionNameContext(_ctx, getState()); enterRule(_localctx, 78, RULE_functionName); try { - setState(672); + setState(689); switch (_input.LA(1)) { case LEFT: enterOuterAlt(_localctx, 1); { - setState(669); + setState(686); match(LEFT); } break; case RIGHT: enterOuterAlt(_localctx, 2); { - setState(670); + setState(687); match(RIGHT); } break; @@ -5043,7 +5124,7 @@ class SqlBaseParser extends Parser { case BACKQUOTED_IDENTIFIER: enterOuterAlt(_localctx, 3); { - setState(671); + setState(688); identifier(); } break; @@ -5274,13 +5355,13 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 80, RULE_constant); try { int _alt; - setState(700); + setState(717); switch (_input.LA(1)) { case NULL: _localctx = new NullLiteralContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(674); + setState(691); match(NULL); } break; @@ -5288,7 +5369,7 @@ class SqlBaseParser extends Parser { _localctx = new IntervalLiteralContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(675); + setState(692); interval(); } break; @@ -5297,7 +5378,7 @@ class SqlBaseParser extends Parser { _localctx = new NumericLiteralContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(676); + setState(693); number(); } break; @@ -5306,7 +5387,7 @@ class SqlBaseParser extends Parser { _localctx = new BooleanLiteralContext(_localctx); enterOuterAlt(_localctx, 4); { - setState(677); + setState(694); booleanValue(); } break; @@ -5314,7 +5395,7 @@ class SqlBaseParser extends Parser { _localctx = new StringLiteralContext(_localctx); enterOuterAlt(_localctx, 5); { - setState(679); + setState(696); _errHandler.sync(this); _alt = 1; do { @@ -5322,7 +5403,7 @@ class SqlBaseParser extends Parser { case 1: { { - setState(678); + setState(695); match(STRING); } } @@ -5330,9 +5411,9 @@ class SqlBaseParser extends Parser { default: throw new NoViableAltException(this); } - setState(681); + setState(698); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,89,_ctx); + _alt = getInterpreter().adaptivePredict(_input,92,_ctx); } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); } break; @@ -5340,7 +5421,7 @@ class SqlBaseParser extends Parser { _localctx = new ParamLiteralContext(_localctx); enterOuterAlt(_localctx, 6); { - setState(683); + setState(700); match(PARAM); } break; @@ -5348,11 +5429,11 @@ class SqlBaseParser extends Parser { _localctx = new DateEscapedLiteralContext(_localctx); enterOuterAlt(_localctx, 7); { - setState(684); + setState(701); match(DATE_ESC); - setState(685); + setState(702); string(); - setState(686); + setState(703); match(ESC_END); } break; @@ -5360,11 +5441,11 @@ class SqlBaseParser extends Parser { _localctx = new TimeEscapedLiteralContext(_localctx); enterOuterAlt(_localctx, 8); { - setState(688); + setState(705); match(TIME_ESC); - setState(689); + setState(706); string(); - setState(690); + setState(707); match(ESC_END); } break; @@ -5372,11 +5453,11 @@ class SqlBaseParser extends Parser { _localctx = new TimestampEscapedLiteralContext(_localctx); enterOuterAlt(_localctx, 9); { - setState(692); + setState(709); match(TIMESTAMP_ESC); - setState(693); + setState(710); string(); - setState(694); + setState(711); match(ESC_END); } break; @@ -5384,11 +5465,11 @@ class SqlBaseParser extends Parser { _localctx = new GuidEscapedLiteralContext(_localctx); enterOuterAlt(_localctx, 10); { - setState(696); + setState(713); match(GUID_ESC); - setState(697); + setState(714); string(); - setState(698); + setState(715); match(ESC_END); } break; @@ -5441,9 +5522,9 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(702); + setState(719); _la = _input.LA(1); - if ( !(((((_la - 101)) & ~0x3f) == 0 && ((1L << (_la - 101)) & ((1L << (EQ - 101)) | (1L << (NULLEQ - 101)) | (1L << (NEQ - 101)) | (1L << (LT - 101)) | (1L << (LTE - 101)) | (1L << (GT - 101)) | (1L << (GTE - 101)))) != 0)) ) { + if ( !(((((_la - 106)) & ~0x3f) == 0 && ((1L << (_la - 106)) & ((1L << (EQ - 106)) | (1L << (NULLEQ - 106)) | (1L << (NEQ - 106)) | (1L << (LT - 106)) | (1L << (LTE - 106)) | (1L << (GT - 106)) | (1L << (GTE - 106)))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -5490,7 +5571,7 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(704); + setState(721); _la = _input.LA(1); if ( !(_la==FALSE || _la==TRUE) ) { _errHandler.recoverInline(this); @@ -5558,13 +5639,13 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(706); + setState(723); match(INTERVAL); - setState(708); + setState(725); _la = _input.LA(1); if (_la==PLUS || _la==MINUS) { { - setState(707); + setState(724); ((IntervalContext)_localctx).sign = _input.LT(1); _la = _input.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { @@ -5575,35 +5656,35 @@ class SqlBaseParser extends Parser { } } - setState(712); + setState(729); switch (_input.LA(1)) { case INTEGER_VALUE: case DECIMAL_VALUE: { - setState(710); + setState(727); ((IntervalContext)_localctx).valueNumeric = number(); } break; case PARAM: case STRING: { - setState(711); + setState(728); ((IntervalContext)_localctx).valuePattern = string(); } break; default: throw new NoViableAltException(this); } - setState(714); + setState(731); ((IntervalContext)_localctx).leading = intervalField(); - setState(717); + setState(734); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,93,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,96,_ctx) ) { case 1: { - setState(715); + setState(732); match(TO); - setState(716); + setState(733); ((IntervalContext)_localctx).trailing = intervalField(); } break; @@ -5660,9 +5741,9 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(719); + setState(736); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << DAY) | (1L << DAYS) | (1L << HOUR) | (1L << HOURS) | (1L << MINUTE) | (1L << MINUTES) | (1L << MONTH) | (1L << MONTHS))) != 0) || ((((_la - 75)) & ~0x3f) == 0 && ((1L << (_la - 75)) & ((1L << (SECOND - 75)) | (1L << (SECONDS - 75)) | (1L << (YEAR - 75)) | (1L << (YEARS - 75)))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << DAY) | (1L << DAYS) | (1L << HOUR) | (1L << HOURS) | (1L << MINUTE) | (1L << MINUTES) | (1L << MONTH) | (1L << MONTHS))) != 0) || ((((_la - 78)) & ~0x3f) == 0 && ((1L << (_la - 78)) & ((1L << (SECOND - 78)) | (1L << (SECONDS - 78)) | (1L << (YEAR - 78)) | (1L << (YEARS - 78)))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -5718,7 +5799,7 @@ class SqlBaseParser extends Parser { _localctx = new PrimitiveDataTypeContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(721); + setState(738); identifier(); } } @@ -5770,25 +5851,25 @@ class SqlBaseParser extends Parser { int _alt; enterOuterAlt(_localctx, 1); { - setState(728); + setState(745); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,94,_ctx); + _alt = getInterpreter().adaptivePredict(_input,97,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(723); + setState(740); identifier(); - setState(724); + setState(741); match(DOT); } } } - setState(730); + setState(747); _errHandler.sync(this); - _alt = getInterpreter().adaptivePredict(_input,94,_ctx); + _alt = getInterpreter().adaptivePredict(_input,97,_ctx); } - setState(731); + setState(748); identifier(); } } @@ -5833,13 +5914,13 @@ class SqlBaseParser extends Parser { IdentifierContext _localctx = new IdentifierContext(_ctx, getState()); enterRule(_localctx, 94, RULE_identifier); try { - setState(735); + setState(752); switch (_input.LA(1)) { case QUOTED_IDENTIFIER: case BACKQUOTED_IDENTIFIER: enterOuterAlt(_localctx, 1); { - setState(733); + setState(750); quoteIdentifier(); } break; @@ -5886,7 +5967,7 @@ class SqlBaseParser extends Parser { case DIGIT_IDENTIFIER: enterOuterAlt(_localctx, 2); { - setState(734); + setState(751); unquoteIdentifier(); } break; @@ -5939,43 +6020,43 @@ class SqlBaseParser extends Parser { enterRule(_localctx, 96, RULE_tableIdentifier); int _la; try { - setState(749); + setState(766); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,98,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,101,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(740); + setState(757); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << CATALOGS) | (1L << COLUMNS) | (1L << CURRENT_DATE) | (1L << CURRENT_TIME) | (1L << CURRENT_TIMESTAMP) | (1L << DAY) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FIRST) | (1L << FORMAT) | (1L << FULL) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << HOUR) | (1L << INTERVAL) | (1L << LAST) | (1L << LIMIT) | (1L << MAPPED) | (1L << MINUTE) | (1L << MONTH))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (OPTIMIZED - 64)) | (1L << (PARSED - 64)) | (1L << (PHYSICAL - 64)) | (1L << (PLAN - 64)) | (1L << (RLIKE - 64)) | (1L << (QUERY - 64)) | (1L << (SCHEMAS - 64)) | (1L << (SECOND - 64)) | (1L << (SHOW - 64)) | (1L << (SYS - 64)) | (1L << (TABLES - 64)) | (1L << (TEXT - 64)) | (1L << (TYPE - 64)) | (1L << (TYPES - 64)) | (1L << (VERIFY - 64)) | (1L << (YEAR - 64)) | (1L << (IDENTIFIER - 64)) | (1L << (DIGIT_IDENTIFIER - 64)) | (1L << (QUOTED_IDENTIFIER - 64)) | (1L << (BACKQUOTED_IDENTIFIER - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << CATALOGS) | (1L << COLUMNS) | (1L << CURRENT_DATE) | (1L << CURRENT_TIME) | (1L << CURRENT_TIMESTAMP) | (1L << DAY) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FIRST) | (1L << FORMAT) | (1L << FULL) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << HOUR) | (1L << INTERVAL) | (1L << LAST) | (1L << LIMIT) | (1L << MAPPED) | (1L << MINUTE) | (1L << MONTH))) != 0) || ((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (OPTIMIZED - 67)) | (1L << (PARSED - 67)) | (1L << (PHYSICAL - 67)) | (1L << (PLAN - 67)) | (1L << (RLIKE - 67)) | (1L << (QUERY - 67)) | (1L << (SCHEMAS - 67)) | (1L << (SECOND - 67)) | (1L << (SHOW - 67)) | (1L << (SYS - 67)) | (1L << (TABLES - 67)) | (1L << (TEXT - 67)) | (1L << (TYPE - 67)) | (1L << (TYPES - 67)) | (1L << (VERIFY - 67)) | (1L << (YEAR - 67)) | (1L << (IDENTIFIER - 67)) | (1L << (DIGIT_IDENTIFIER - 67)) | (1L << (QUOTED_IDENTIFIER - 67)) | (1L << (BACKQUOTED_IDENTIFIER - 67)))) != 0)) { { - setState(737); + setState(754); ((TableIdentifierContext)_localctx).catalog = identifier(); - setState(738); + setState(755); match(T__3); } } - setState(742); + setState(759); match(TABLE_IDENTIFIER); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(746); + setState(763); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,97,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,100,_ctx) ) { case 1: { - setState(743); + setState(760); ((TableIdentifierContext)_localctx).catalog = identifier(); - setState(744); + setState(761); match(T__3); } break; } - setState(748); + setState(765); ((TableIdentifierContext)_localctx).name = identifier(); } break; @@ -6042,13 +6123,13 @@ class SqlBaseParser extends Parser { QuoteIdentifierContext _localctx = new QuoteIdentifierContext(_ctx, getState()); enterRule(_localctx, 98, RULE_quoteIdentifier); try { - setState(753); + setState(770); switch (_input.LA(1)) { case QUOTED_IDENTIFIER: _localctx = new QuotedIdentifierContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(751); + setState(768); match(QUOTED_IDENTIFIER); } break; @@ -6056,7 +6137,7 @@ class SqlBaseParser extends Parser { _localctx = new BackQuotedIdentifierContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(752); + setState(769); match(BACKQUOTED_IDENTIFIER); } break; @@ -6128,13 +6209,13 @@ class SqlBaseParser extends Parser { UnquoteIdentifierContext _localctx = new UnquoteIdentifierContext(_ctx, getState()); enterRule(_localctx, 100, RULE_unquoteIdentifier); try { - setState(758); + setState(775); switch (_input.LA(1)) { case IDENTIFIER: _localctx = new UnquotedIdentifierContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(755); + setState(772); match(IDENTIFIER); } break; @@ -6180,7 +6261,7 @@ class SqlBaseParser extends Parser { _localctx = new UnquotedIdentifierContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(756); + setState(773); nonReserved(); } break; @@ -6188,7 +6269,7 @@ class SqlBaseParser extends Parser { _localctx = new DigitIdentifierContext(_localctx); enterOuterAlt(_localctx, 3); { - setState(757); + setState(774); match(DIGIT_IDENTIFIER); } break; @@ -6257,13 +6338,13 @@ class SqlBaseParser extends Parser { NumberContext _localctx = new NumberContext(_ctx, getState()); enterRule(_localctx, 102, RULE_number); try { - setState(762); + setState(779); switch (_input.LA(1)) { case DECIMAL_VALUE: _localctx = new DecimalLiteralContext(_localctx); enterOuterAlt(_localctx, 1); { - setState(760); + setState(777); match(DECIMAL_VALUE); } break; @@ -6271,7 +6352,7 @@ class SqlBaseParser extends Parser { _localctx = new IntegerLiteralContext(_localctx); enterOuterAlt(_localctx, 2); { - setState(761); + setState(778); match(INTEGER_VALUE); } break; @@ -6319,7 +6400,7 @@ class SqlBaseParser extends Parser { try { enterOuterAlt(_localctx, 1); { - setState(764); + setState(781); _la = _input.LA(1); if ( !(_la==PARAM || _la==STRING) ) { _errHandler.recoverInline(this); @@ -6339,6 +6420,63 @@ class SqlBaseParser extends Parser { return _localctx; } + public static class WhenClauseContext extends ParserRuleContext { + public ExpressionContext condition; + public ExpressionContext result; + public TerminalNode WHEN() { return getToken(SqlBaseParser.WHEN, 0); } + public TerminalNode THEN() { return getToken(SqlBaseParser.THEN, 0); } + public List expression() { + return getRuleContexts(ExpressionContext.class); + } + public ExpressionContext expression(int i) { + return getRuleContext(ExpressionContext.class,i); + } + public WhenClauseContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_whenClause; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof SqlBaseListener ) ((SqlBaseListener)listener).enterWhenClause(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof SqlBaseListener ) ((SqlBaseListener)listener).exitWhenClause(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof SqlBaseVisitor ) return ((SqlBaseVisitor)visitor).visitWhenClause(this); + else return visitor.visitChildren(this); + } + } + + public final WhenClauseContext whenClause() throws RecognitionException { + WhenClauseContext _localctx = new WhenClauseContext(_ctx, getState()); + enterRule(_localctx, 106, RULE_whenClause); + try { + enterOuterAlt(_localctx, 1); + { + setState(783); + match(WHEN); + setState(784); + ((WhenClauseContext)_localctx).condition = expression(); + setState(785); + match(THEN); + setState(786); + ((WhenClauseContext)_localctx).result = expression(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + public static class NonReservedContext extends ParserRuleContext { public TerminalNode ANALYZE() { return getToken(SqlBaseParser.ANALYZE, 0); } public TerminalNode ANALYZED() { return getToken(SqlBaseParser.ANALYZED, 0); } @@ -6400,14 +6538,14 @@ class SqlBaseParser extends Parser { public final NonReservedContext nonReserved() throws RecognitionException { NonReservedContext _localctx = new NonReservedContext(_ctx, getState()); - enterRule(_localctx, 106, RULE_nonReserved); + enterRule(_localctx, 108, RULE_nonReserved); int _la; try { enterOuterAlt(_localctx, 1); { - setState(766); + setState(788); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << CATALOGS) | (1L << COLUMNS) | (1L << CURRENT_DATE) | (1L << CURRENT_TIME) | (1L << CURRENT_TIMESTAMP) | (1L << DAY) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FIRST) | (1L << FORMAT) | (1L << FULL) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << HOUR) | (1L << INTERVAL) | (1L << LAST) | (1L << LIMIT) | (1L << MAPPED) | (1L << MINUTE) | (1L << MONTH))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (OPTIMIZED - 64)) | (1L << (PARSED - 64)) | (1L << (PHYSICAL - 64)) | (1L << (PLAN - 64)) | (1L << (RLIKE - 64)) | (1L << (QUERY - 64)) | (1L << (SCHEMAS - 64)) | (1L << (SECOND - 64)) | (1L << (SHOW - 64)) | (1L << (SYS - 64)) | (1L << (TABLES - 64)) | (1L << (TEXT - 64)) | (1L << (TYPE - 64)) | (1L << (TYPES - 64)) | (1L << (VERIFY - 64)) | (1L << (YEAR - 64)))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << ANALYZE) | (1L << ANALYZED) | (1L << CATALOGS) | (1L << COLUMNS) | (1L << CURRENT_DATE) | (1L << CURRENT_TIME) | (1L << CURRENT_TIMESTAMP) | (1L << DAY) | (1L << DEBUG) | (1L << EXECUTABLE) | (1L << EXPLAIN) | (1L << FIRST) | (1L << FORMAT) | (1L << FULL) | (1L << FUNCTIONS) | (1L << GRAPHVIZ) | (1L << HOUR) | (1L << INTERVAL) | (1L << LAST) | (1L << LIMIT) | (1L << MAPPED) | (1L << MINUTE) | (1L << MONTH))) != 0) || ((((_la - 67)) & ~0x3f) == 0 && ((1L << (_la - 67)) & ((1L << (OPTIMIZED - 67)) | (1L << (PARSED - 67)) | (1L << (PHYSICAL - 67)) | (1L << (PLAN - 67)) | (1L << (RLIKE - 67)) | (1L << (QUERY - 67)) | (1L << (SCHEMAS - 67)) | (1L << (SECOND - 67)) | (1L << (SHOW - 67)) | (1L << (SYS - 67)) | (1L << (TABLES - 67)) | (1L << (TEXT - 67)) | (1L << (TYPE - 67)) | (1L << (TYPES - 67)) | (1L << (VERIFY - 67)) | (1L << (YEAR - 67)))) != 0)) ) { _errHandler.recoverInline(this); } else { consume(); @@ -6459,317 +6597,328 @@ class SqlBaseParser extends Parser { private boolean primaryExpression_sempred(PrimaryExpressionContext _localctx, int predIndex) { switch (predIndex) { case 5: - return precpred(_ctx, 9); + return precpred(_ctx, 10); } return true; } public static final String _serializedATN = - "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\u0083\u0303\4\2\t"+ + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3\u0088\u0319\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\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\31"+ "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ "\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+ ",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+ - "\64\4\65\t\65\4\66\t\66\4\67\t\67\3\2\3\2\3\2\3\3\3\3\3\3\3\4\3\4\3\4"+ - "\3\4\3\4\3\4\3\4\3\4\3\4\7\4~\n\4\f\4\16\4\u0081\13\4\3\4\5\4\u0084\n"+ - "\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4\u008d\n\4\f\4\16\4\u0090\13\4\3\4\5"+ - "\4\u0093\n\4\3\4\3\4\3\4\3\4\3\4\5\4\u009a\n\4\3\4\3\4\3\4\3\4\3\4\5\4"+ - "\u00a1\n\4\3\4\3\4\3\4\5\4\u00a6\n\4\3\4\3\4\3\4\5\4\u00ab\n\4\3\4\3\4"+ - "\3\4\3\4\3\4\3\4\5\4\u00b3\n\4\3\4\3\4\5\4\u00b7\n\4\3\4\3\4\3\4\3\4\7"+ - "\4\u00bd\n\4\f\4\16\4\u00c0\13\4\5\4\u00c2\n\4\3\4\3\4\3\4\3\4\5\4\u00c8"+ - "\n\4\3\4\3\4\3\4\5\4\u00cd\n\4\3\4\5\4\u00d0\n\4\3\4\3\4\3\4\5\4\u00d5"+ - "\n\4\3\4\5\4\u00d8\n\4\5\4\u00da\n\4\3\5\3\5\3\5\3\5\7\5\u00e0\n\5\f\5"+ - "\16\5\u00e3\13\5\5\5\u00e5\n\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\7\6\u00ef"+ - "\n\6\f\6\16\6\u00f2\13\6\5\6\u00f4\n\6\3\6\5\6\u00f7\n\6\3\7\3\7\3\7\3"+ - "\7\3\7\5\7\u00fe\n\7\3\b\3\b\3\b\3\b\3\b\5\b\u0105\n\b\3\t\3\t\5\t\u0109"+ - "\n\t\3\t\3\t\5\t\u010d\n\t\3\n\3\n\5\n\u0111\n\n\3\n\3\n\3\n\7\n\u0116"+ - "\n\n\f\n\16\n\u0119\13\n\3\n\5\n\u011c\n\n\3\n\3\n\5\n\u0120\n\n\3\n\3"+ - "\n\3\n\5\n\u0125\n\n\3\n\3\n\5\n\u0129\n\n\3\13\3\13\3\13\3\13\7\13\u012f"+ - "\n\13\f\13\16\13\u0132\13\13\3\f\5\f\u0135\n\f\3\f\3\f\3\f\7\f\u013a\n"+ - "\f\f\f\16\f\u013d\13\f\3\r\3\r\3\16\3\16\3\16\3\16\7\16\u0145\n\16\f\16"+ - "\16\16\u0148\13\16\5\16\u014a\n\16\3\16\3\16\5\16\u014e\n\16\3\17\3\17"+ - "\3\17\3\17\3\17\3\17\3\20\3\20\3\21\3\21\5\21\u015a\n\21\3\21\5\21\u015d"+ - "\n\21\3\22\3\22\7\22\u0161\n\22\f\22\16\22\u0164\13\22\3\23\3\23\3\23"+ - "\3\23\5\23\u016a\n\23\3\23\3\23\3\23\3\23\3\23\5\23\u0171\n\23\3\24\5"+ - "\24\u0174\n\24\3\24\3\24\5\24\u0178\n\24\3\24\3\24\5\24\u017c\n\24\3\24"+ - "\3\24\5\24\u0180\n\24\5\24\u0182\n\24\3\25\3\25\3\25\3\25\3\25\3\25\3"+ - "\25\7\25\u018b\n\25\f\25\16\25\u018e\13\25\3\25\3\25\5\25\u0192\n\25\3"+ - "\26\3\26\5\26\u0196\n\26\3\26\5\26\u0199\n\26\3\26\3\26\3\26\3\26\5\26"+ - "\u019f\n\26\3\26\5\26\u01a2\n\26\3\26\3\26\3\26\3\26\5\26\u01a8\n\26\3"+ - "\26\5\26\u01ab\n\26\5\26\u01ad\n\26\3\27\3\27\3\30\3\30\3\30\3\30\3\30"+ + "\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\3\2\3\2\3\2\3\3\3\3\3\3\3\4\3"+ + "\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4\u0080\n\4\f\4\16\4\u0083\13\4\3\4\5"+ + "\4\u0086\n\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\7\4\u008f\n\4\f\4\16\4\u0092"+ + "\13\4\3\4\5\4\u0095\n\4\3\4\3\4\3\4\3\4\3\4\5\4\u009c\n\4\3\4\3\4\3\4"+ + "\3\4\3\4\5\4\u00a3\n\4\3\4\3\4\3\4\5\4\u00a8\n\4\3\4\3\4\3\4\5\4\u00ad"+ + "\n\4\3\4\3\4\3\4\3\4\3\4\3\4\5\4\u00b5\n\4\3\4\3\4\5\4\u00b9\n\4\3\4\3"+ + "\4\3\4\3\4\7\4\u00bf\n\4\f\4\16\4\u00c2\13\4\5\4\u00c4\n\4\3\4\3\4\3\4"+ + "\3\4\5\4\u00ca\n\4\3\4\3\4\3\4\5\4\u00cf\n\4\3\4\5\4\u00d2\n\4\3\4\3\4"+ + "\3\4\5\4\u00d7\n\4\3\4\5\4\u00da\n\4\5\4\u00dc\n\4\3\5\3\5\3\5\3\5\7\5"+ + "\u00e2\n\5\f\5\16\5\u00e5\13\5\5\5\u00e7\n\5\3\5\3\5\3\6\3\6\3\6\3\6\3"+ + "\6\3\6\7\6\u00f1\n\6\f\6\16\6\u00f4\13\6\5\6\u00f6\n\6\3\6\5\6\u00f9\n"+ + "\6\3\7\3\7\3\7\3\7\3\7\5\7\u0100\n\7\3\b\3\b\3\b\3\b\3\b\5\b\u0107\n\b"+ + "\3\t\3\t\5\t\u010b\n\t\3\t\3\t\5\t\u010f\n\t\3\n\3\n\5\n\u0113\n\n\3\n"+ + "\3\n\3\n\7\n\u0118\n\n\f\n\16\n\u011b\13\n\3\n\5\n\u011e\n\n\3\n\3\n\5"+ + "\n\u0122\n\n\3\n\3\n\3\n\5\n\u0127\n\n\3\n\3\n\5\n\u012b\n\n\3\13\3\13"+ + "\3\13\3\13\7\13\u0131\n\13\f\13\16\13\u0134\13\13\3\f\5\f\u0137\n\f\3"+ + "\f\3\f\3\f\7\f\u013c\n\f\f\f\16\f\u013f\13\f\3\r\3\r\3\16\3\16\3\16\3"+ + "\16\7\16\u0147\n\16\f\16\16\16\u014a\13\16\5\16\u014c\n\16\3\16\3\16\5"+ + "\16\u0150\n\16\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\21\3\21\5\21"+ + "\u015c\n\21\3\21\5\21\u015f\n\21\3\22\3\22\7\22\u0163\n\22\f\22\16\22"+ + "\u0166\13\22\3\23\3\23\3\23\3\23\5\23\u016c\n\23\3\23\3\23\3\23\3\23\3"+ + "\23\5\23\u0173\n\23\3\24\5\24\u0176\n\24\3\24\3\24\5\24\u017a\n\24\3\24"+ + "\3\24\5\24\u017e\n\24\3\24\3\24\5\24\u0182\n\24\5\24\u0184\n\24\3\25\3"+ + "\25\3\25\3\25\3\25\3\25\3\25\7\25\u018d\n\25\f\25\16\25\u0190\13\25\3"+ + "\25\3\25\5\25\u0194\n\25\3\26\3\26\5\26\u0198\n\26\3\26\5\26\u019b\n\26"+ + "\3\26\3\26\3\26\3\26\5\26\u01a1\n\26\3\26\5\26\u01a4\n\26\3\26\3\26\3"+ + "\26\3\26\5\26\u01aa\n\26\3\26\5\26\u01ad\n\26\5\26\u01af\n\26\3\27\3\27"+ "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+ - "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\5\30\u01d0"+ - "\n\30\3\30\3\30\3\30\3\30\3\30\3\30\7\30\u01d8\n\30\f\30\16\30\u01db\13"+ - "\30\3\31\3\31\7\31\u01df\n\31\f\31\16\31\u01e2\13\31\3\32\3\32\5\32\u01e6"+ - "\n\32\3\33\5\33\u01e9\n\33\3\33\3\33\3\33\3\33\3\33\3\33\5\33\u01f1\n"+ - "\33\3\33\3\33\3\33\3\33\3\33\7\33\u01f8\n\33\f\33\16\33\u01fb\13\33\3"+ - "\33\3\33\3\33\5\33\u0200\n\33\3\33\3\33\3\33\3\33\3\33\3\33\5\33\u0208"+ - "\n\33\3\33\3\33\3\33\5\33\u020d\n\33\3\33\3\33\3\33\3\33\5\33\u0213\n"+ - "\33\3\33\5\33\u0216\n\33\3\34\3\34\3\34\3\35\3\35\5\35\u021d\n\35\3\36"+ - "\3\36\3\36\3\36\3\36\3\36\5\36\u0225\n\36\3\37\3\37\3\37\3\37\5\37\u022b"+ - "\n\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37\7\37\u0237\n\37"+ - "\f\37\16\37\u023a\13\37\3 \3 \3 \3 \3 \3 \3 \3 \5 \u0244\n \3 \3 \3 \3"+ - " \3 \3 \3 \3 \3 \3 \3 \5 \u0251\n \3 \3 \3 \7 \u0256\n \f \16 \u0259\13"+ - " \3!\3!\3!\5!\u025e\n!\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3\"\5\"\u026a"+ - "\n\"\3#\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\5%\u027f"+ - "\n%\3&\3&\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\5\'\u028d\n\'\3(\3(\3(\5"+ - "(\u0292\n(\3(\3(\3(\7(\u0297\n(\f(\16(\u029a\13(\5(\u029c\n(\3(\3(\3)"+ - "\3)\3)\5)\u02a3\n)\3*\3*\3*\3*\3*\6*\u02aa\n*\r*\16*\u02ab\3*\3*\3*\3"+ - "*\3*\3*\3*\3*\3*\3*\3*\3*\3*\3*\3*\3*\3*\5*\u02bf\n*\3+\3+\3,\3,\3-\3"+ - "-\5-\u02c7\n-\3-\3-\5-\u02cb\n-\3-\3-\3-\5-\u02d0\n-\3.\3.\3/\3/\3\60"+ - "\3\60\3\60\7\60\u02d9\n\60\f\60\16\60\u02dc\13\60\3\60\3\60\3\61\3\61"+ - "\5\61\u02e2\n\61\3\62\3\62\3\62\5\62\u02e7\n\62\3\62\3\62\3\62\3\62\5"+ - "\62\u02ed\n\62\3\62\5\62\u02f0\n\62\3\63\3\63\5\63\u02f4\n\63\3\64\3\64"+ - "\3\64\5\64\u02f9\n\64\3\65\3\65\5\65\u02fd\n\65\3\66\3\66\3\67\3\67\3"+ - "\67\2\5.<>8\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\66"+ - "8:<>@BDFHJLNPRTVXZ\\^`bdfhjl\2\22\b\2\7\7\t\t\37\37\67\67BBFF\4\2))TT"+ - "\4\2\t\tBB\4\2&&..\3\2\33\34\3\2no\4\2\7\7xx\4\2\r\r\33\33\4\2$$\63\63"+ - "\4\2\7\7\35\35\3\2pr\3\2gm\4\2##UU\7\2\30\31,-9\u0250\3\2\2\2@\u025d"+ - "\3\2\2\2B\u0269\3\2\2\2D\u026b\3\2\2\2F\u0272\3\2\2\2H\u027e\3\2\2\2J"+ - "\u0280\3\2\2\2L\u028c\3\2\2\2N\u028e\3\2\2\2P\u02a2\3\2\2\2R\u02be\3\2"+ - "\2\2T\u02c0\3\2\2\2V\u02c2\3\2\2\2X\u02c4\3\2\2\2Z\u02d1\3\2\2\2\\\u02d3"+ - "\3\2\2\2^\u02da\3\2\2\2`\u02e1\3\2\2\2b\u02ef\3\2\2\2d\u02f3\3\2\2\2f"+ - "\u02f8\3\2\2\2h\u02fc\3\2\2\2j\u02fe\3\2\2\2l\u0300\3\2\2\2no\5\6\4\2"+ - "op\7\2\2\3p\3\3\2\2\2qr\5,\27\2rs\7\2\2\3s\5\3\2\2\2t\u00da\5\b\5\2u\u0083"+ - "\7!\2\2v\177\7\3\2\2wx\7H\2\2x~\t\2\2\2yz\7%\2\2z~\t\3\2\2{|\7Z\2\2|~"+ - "\5V,\2}w\3\2\2\2}y\3\2\2\2}{\3\2\2\2~\u0081\3\2\2\2\177}\3\2\2\2\177\u0080"+ - "\3\2\2\2\u0080\u0082\3\2\2\2\u0081\177\3\2\2\2\u0082\u0084\7\4\2\2\u0083"+ - "v\3\2\2\2\u0083\u0084\3\2\2\2\u0084\u0085\3\2\2\2\u0085\u00da\5\6\4\2"+ - "\u0086\u0092\7\32\2\2\u0087\u008e\7\3\2\2\u0088\u0089\7H\2\2\u0089\u008d"+ - "\t\4\2\2\u008a\u008b\7%\2\2\u008b\u008d\t\3\2\2\u008c\u0088\3\2\2\2\u008c"+ - "\u008a\3\2\2\2\u008d\u0090\3\2\2\2\u008e\u008c\3\2\2\2\u008e\u008f\3\2"+ - "\2\2\u008f\u0091\3\2\2\2\u0090\u008e\3\2\2\2\u0091\u0093\7\4\2\2\u0092"+ - "\u0087\3\2\2\2\u0092\u0093\3\2\2\2\u0093\u0094\3\2\2\2\u0094\u00da\5\6"+ - "\4\2\u0095\u0096\7P\2\2\u0096\u0099\7S\2\2\u0097\u009a\5\66\34\2\u0098"+ - "\u009a\5b\62\2\u0099\u0097\3\2\2\2\u0099\u0098\3\2\2\2\u0099\u009a\3\2"+ - "\2\2\u009a\u00da\3\2\2\2\u009b\u009c\7P\2\2\u009c\u009d\7\23\2\2\u009d"+ - "\u00a0\t\5\2\2\u009e\u00a1\5\66\34\2\u009f\u00a1\5b\62\2\u00a0\u009e\3"+ - "\2\2\2\u00a0\u009f\3\2\2\2\u00a1\u00da\3\2\2\2\u00a2\u00a5\t\6\2\2\u00a3"+ - "\u00a6\5\66\34\2\u00a4\u00a6\5b\62\2\u00a5\u00a3\3\2\2\2\u00a5\u00a4\3"+ - "\2\2\2\u00a6\u00da\3\2\2\2\u00a7\u00a8\7P\2\2\u00a8\u00aa\7(\2\2\u00a9"+ - "\u00ab\5\66\34\2\u00aa\u00a9\3\2\2\2\u00aa\u00ab\3\2\2\2\u00ab\u00da\3"+ - "\2\2\2\u00ac\u00ad\7P\2\2\u00ad\u00da\7L\2\2\u00ae\u00af\7Q\2\2\u00af"+ - "\u00b2\7S\2\2\u00b0\u00b1\7\21\2\2\u00b1\u00b3\5\66\34\2\u00b2\u00b0\3"+ - "\2\2\2\u00b2\u00b3\3\2\2\2\u00b3\u00b6\3\2\2\2\u00b4\u00b7\5\66\34\2\u00b5"+ - "\u00b7\5b\62\2\u00b6\u00b4\3\2\2\2\u00b6\u00b5\3\2\2\2\u00b6\u00b7\3\2"+ - "\2\2\u00b7\u00c1\3\2\2\2\u00b8\u00b9\7W\2\2\u00b9\u00be\5j\66\2\u00ba"+ - "\u00bb\7\5\2\2\u00bb\u00bd\5j\66\2\u00bc\u00ba\3\2\2\2\u00bd\u00c0\3\2"+ - "\2\2\u00be\u00bc\3\2\2\2\u00be\u00bf\3\2\2\2\u00bf\u00c2\3\2\2\2\u00c0"+ - "\u00be\3\2\2\2\u00c1\u00b8\3\2\2\2\u00c1\u00c2\3\2\2\2\u00c2\u00da\3\2"+ - "\2\2\u00c3\u00c4\7Q\2\2\u00c4\u00c7\7\23\2\2\u00c5\u00c6\7\21\2\2\u00c6"+ - "\u00c8\5j\66\2\u00c7\u00c5\3\2\2\2\u00c7\u00c8\3\2\2\2\u00c8\u00cc\3\2"+ - "\2\2\u00c9\u00ca\7R\2\2\u00ca\u00cd\5\66\34\2\u00cb\u00cd\5b\62\2\u00cc"+ - "\u00c9\3\2\2\2\u00cc\u00cb\3\2\2\2\u00cc\u00cd\3\2\2\2\u00cd\u00cf\3\2"+ - "\2\2\u00ce\u00d0\5\66\34\2\u00cf\u00ce\3\2\2\2\u00cf\u00d0\3\2\2\2\u00d0"+ - "\u00da\3\2\2\2\u00d1\u00d2\7Q\2\2\u00d2\u00d7\7X\2\2\u00d3\u00d5\t\7\2"+ - "\2\u00d4\u00d3\3\2\2\2\u00d4\u00d5\3\2\2\2\u00d5\u00d6\3\2\2\2\u00d6\u00d8"+ - "\5h\65\2\u00d7\u00d4\3\2\2\2\u00d7\u00d8\3\2\2\2\u00d8\u00da\3\2\2\2\u00d9"+ - "t\3\2\2\2\u00d9u\3\2\2\2\u00d9\u0086\3\2\2\2\u00d9\u0095\3\2\2\2\u00d9"+ - "\u009b\3\2\2\2\u00d9\u00a2\3\2\2\2\u00d9\u00a7\3\2\2\2\u00d9\u00ac\3\2"+ - "\2\2\u00d9\u00ae\3\2\2\2\u00d9\u00c3\3\2\2\2\u00d9\u00d1\3\2\2\2\u00da"+ - "\7\3\2\2\2\u00db\u00dc\7\\\2\2\u00dc\u00e1\5\34\17\2\u00dd\u00de\7\5\2"+ - "\2\u00de\u00e0\5\34\17\2\u00df\u00dd\3\2\2\2\u00e0\u00e3\3\2\2\2\u00e1"+ - "\u00df\3\2\2\2\u00e1\u00e2\3\2\2\2\u00e2\u00e5\3\2\2\2\u00e3\u00e1\3\2"+ - "\2\2\u00e4\u00db\3\2\2\2\u00e4\u00e5\3\2\2\2\u00e5\u00e6\3\2\2\2\u00e6"+ - "\u00e7\5\n\6\2\u00e7\t\3\2\2\2\u00e8\u00f3\5\16\b\2\u00e9\u00ea\7D\2\2"+ - "\u00ea\u00eb\7\17\2\2\u00eb\u00f0\5\20\t\2\u00ec\u00ed\7\5\2\2\u00ed\u00ef"+ - "\5\20\t\2\u00ee\u00ec\3\2\2\2\u00ef\u00f2\3\2\2\2\u00f0\u00ee\3\2\2\2"+ - "\u00f0\u00f1\3\2\2\2\u00f1\u00f4\3\2\2\2\u00f2\u00f0\3\2\2\2\u00f3\u00e9"+ - "\3\2\2\2\u00f3\u00f4\3\2\2\2\u00f4\u00f6\3\2\2\2\u00f5\u00f7\5\f\7\2\u00f6"+ - "\u00f5\3\2\2\2\u00f6\u00f7\3\2\2\2\u00f7\13\3\2\2\2\u00f8\u00f9\7\66\2"+ - "\2\u00f9\u00fe\t\b\2\2\u00fa\u00fb\7a\2\2\u00fb\u00fc\t\b\2\2\u00fc\u00fe"+ - "\7f\2\2\u00fd\u00f8\3\2\2\2\u00fd\u00fa\3\2\2\2\u00fe\r\3\2\2\2\u00ff"+ - "\u0105\5\22\n\2\u0100\u0101\7\3\2\2\u0101\u0102\5\n\6\2\u0102\u0103\7"+ - "\4\2\2\u0103\u0105\3\2\2\2\u0104\u00ff\3\2\2\2\u0104\u0100\3\2\2\2\u0105"+ - "\17\3\2\2\2\u0106\u0108\5,\27\2\u0107\u0109\t\t\2\2\u0108\u0107\3\2\2"+ - "\2\u0108\u0109\3\2\2\2\u0109\u010c\3\2\2\2\u010a\u010b\7@\2\2\u010b\u010d"+ - "\t\n\2\2\u010c\u010a\3\2\2\2\u010c\u010d\3\2\2\2\u010d\21\3\2\2\2\u010e"+ - "\u0110\7O\2\2\u010f\u0111\5\36\20\2\u0110\u010f\3\2\2\2\u0110\u0111\3"+ - "\2\2\2\u0111\u0112\3\2\2\2\u0112\u0117\5 \21\2\u0113\u0114\7\5\2\2\u0114"+ - "\u0116\5 \21\2\u0115\u0113\3\2\2\2\u0116\u0119\3\2\2\2\u0117\u0115\3\2"+ - "\2\2\u0117\u0118\3\2\2\2\u0118\u011b\3\2\2\2\u0119\u0117\3\2\2\2\u011a"+ - "\u011c\5\24\13\2\u011b\u011a\3\2\2\2\u011b\u011c\3\2\2\2\u011c\u011f\3"+ - "\2\2\2\u011d\u011e\7[\2\2\u011e\u0120\5.\30\2\u011f\u011d\3\2\2\2\u011f"+ - "\u0120\3\2\2\2\u0120\u0124\3\2\2\2\u0121\u0122\7*\2\2\u0122\u0123\7\17"+ - "\2\2\u0123\u0125\5\26\f\2\u0124\u0121\3\2\2\2\u0124\u0125\3\2\2\2\u0125"+ - "\u0128\3\2\2\2\u0126\u0127\7+\2\2\u0127\u0129\5.\30\2\u0128\u0126\3\2"+ - "\2\2\u0128\u0129\3\2\2\2\u0129\23\3\2\2\2\u012a\u012b\7&\2\2\u012b\u0130"+ - "\5\"\22\2\u012c\u012d\7\5\2\2\u012d\u012f\5\"\22\2\u012e\u012c\3\2\2\2"+ - "\u012f\u0132\3\2\2\2\u0130\u012e\3\2\2\2\u0130\u0131\3\2\2\2\u0131\25"+ - "\3\2\2\2\u0132\u0130\3\2\2\2\u0133\u0135\5\36\20\2\u0134\u0133\3\2\2\2"+ - "\u0134\u0135\3\2\2\2\u0135\u0136\3\2\2\2\u0136\u013b\5\30\r\2\u0137\u0138"+ - "\7\5\2\2\u0138\u013a\5\30\r\2\u0139\u0137\3\2\2\2\u013a\u013d\3\2\2\2"+ - "\u013b\u0139\3\2\2\2\u013b\u013c\3\2\2\2\u013c\27\3\2\2\2\u013d\u013b"+ - "\3\2\2\2\u013e\u013f\5\32\16\2\u013f\31\3\2\2\2\u0140\u0149\7\3\2\2\u0141"+ - "\u0146\5,\27\2\u0142\u0143\7\5\2\2\u0143\u0145\5,\27\2\u0144\u0142\3\2"+ - "\2\2\u0145\u0148\3\2\2\2\u0146\u0144\3\2\2\2\u0146\u0147\3\2\2\2\u0147"+ - "\u014a\3\2\2\2\u0148\u0146\3\2\2\2\u0149\u0141\3\2\2\2\u0149\u014a\3\2"+ - "\2\2\u014a\u014b\3\2\2\2\u014b\u014e\7\4\2\2\u014c\u014e\5,\27\2\u014d"+ - "\u0140\3\2\2\2\u014d\u014c\3\2\2\2\u014e\33\3\2\2\2\u014f\u0150\5`\61"+ - "\2\u0150\u0151\7\f\2\2\u0151\u0152\7\3\2\2\u0152\u0153\5\n\6\2\u0153\u0154"+ - "\7\4\2\2\u0154\35\3\2\2\2\u0155\u0156\t\13\2\2\u0156\37\3\2\2\2\u0157"+ - "\u015c\5,\27\2\u0158\u015a\7\f\2\2\u0159\u0158\3\2\2\2\u0159\u015a\3\2"+ - "\2\2\u015a\u015b\3\2\2\2\u015b\u015d\5`\61\2\u015c\u0159\3\2\2\2\u015c"+ - "\u015d\3\2\2\2\u015d!\3\2\2\2\u015e\u0162\5*\26\2\u015f\u0161\5$\23\2"+ - "\u0160\u015f\3\2\2\2\u0161\u0164\3\2\2\2\u0162\u0160\3\2\2\2\u0162\u0163"+ - "\3\2\2\2\u0163#\3\2\2\2\u0164\u0162\3\2\2\2\u0165\u0166\5&\24\2\u0166"+ - "\u0167\7\62\2\2\u0167\u0169\5*\26\2\u0168\u016a\5(\25\2\u0169\u0168\3"+ - "\2\2\2\u0169\u016a\3\2\2\2\u016a\u0171\3\2\2\2\u016b\u016c\7=\2\2\u016c"+ - "\u016d\5&\24\2\u016d\u016e\7\62\2\2\u016e\u016f\5*\26\2\u016f\u0171\3"+ - "\2\2\2\u0170\u0165\3\2\2\2\u0170\u016b\3\2\2\2\u0171%\3\2\2\2\u0172\u0174"+ - "\7/\2\2\u0173\u0172\3\2\2\2\u0173\u0174\3\2\2\2\u0174\u0182\3\2\2\2\u0175"+ - "\u0177\7\64\2\2\u0176\u0178\7E\2\2\u0177\u0176\3\2\2\2\u0177\u0178\3\2"+ - "\2\2\u0178\u0182\3\2\2\2\u0179\u017b\7I\2\2\u017a\u017c\7E\2\2\u017b\u017a"+ - "\3\2\2\2\u017b\u017c\3\2\2\2\u017c\u0182\3\2\2\2\u017d\u017f\7\'\2\2\u017e"+ - "\u0180\7E\2\2\u017f\u017e\3\2\2\2\u017f\u0180\3\2\2\2\u0180\u0182\3\2"+ - "\2\2\u0181\u0173\3\2\2\2\u0181\u0175\3\2\2\2\u0181\u0179\3\2\2\2\u0181"+ - "\u017d\3\2\2\2\u0182\'\3\2\2\2\u0183\u0184\7A\2\2\u0184\u0192\5.\30\2"+ - "\u0185\u0186\7Y\2\2\u0186\u0187\7\3\2\2\u0187\u018c\5`\61\2\u0188\u0189"+ - "\7\5\2\2\u0189\u018b\5`\61\2\u018a\u0188\3\2\2\2\u018b\u018e\3\2\2\2\u018c"+ - "\u018a\3\2\2\2\u018c\u018d\3\2\2\2\u018d\u018f\3\2\2\2\u018e\u018c\3\2"+ - "\2\2\u018f\u0190\7\4\2\2\u0190\u0192\3\2\2\2\u0191\u0183\3\2\2\2\u0191"+ - "\u0185\3\2\2\2\u0192)\3\2\2\2\u0193\u0198\5b\62\2\u0194\u0196\7\f\2\2"+ - "\u0195\u0194\3\2\2\2\u0195\u0196\3\2\2\2\u0196\u0197\3\2\2\2\u0197\u0199"+ - "\5^\60\2\u0198\u0195\3\2\2\2\u0198\u0199\3\2\2\2\u0199\u01ad\3\2\2\2\u019a"+ - "\u019b\7\3\2\2\u019b\u019c\5\n\6\2\u019c\u01a1\7\4\2\2\u019d\u019f\7\f"+ - "\2\2\u019e\u019d\3\2\2\2\u019e\u019f\3\2\2\2\u019f\u01a0\3\2\2\2\u01a0"+ - "\u01a2\5^\60\2\u01a1\u019e\3\2\2\2\u01a1\u01a2\3\2\2\2\u01a2\u01ad\3\2"+ - "\2\2\u01a3\u01a4\7\3\2\2\u01a4\u01a5\5\"\22\2\u01a5\u01aa\7\4\2\2\u01a6"+ - "\u01a8\7\f\2\2\u01a7\u01a6\3\2\2\2\u01a7\u01a8\3\2\2\2\u01a8\u01a9\3\2"+ - "\2\2\u01a9\u01ab\5^\60\2\u01aa\u01a7\3\2\2\2\u01aa\u01ab\3\2\2\2\u01ab"+ - "\u01ad\3\2\2\2\u01ac\u0193\3\2\2\2\u01ac\u019a\3\2\2\2\u01ac\u01a3\3\2"+ - "\2\2\u01ad+\3\2\2\2\u01ae\u01af\5.\30\2\u01af-\3\2\2\2\u01b0\u01b1\b\30"+ - "\1\2\u01b1\u01b2\7>\2\2\u01b2\u01d0\5.\30\n\u01b3\u01b4\7 \2\2\u01b4\u01b5"+ - "\7\3\2\2\u01b5\u01b6\5\b\5\2\u01b6\u01b7\7\4\2\2\u01b7\u01d0\3\2\2\2\u01b8"+ - "\u01b9\7K\2\2\u01b9\u01ba\7\3\2\2\u01ba\u01bb\5j\66\2\u01bb\u01bc\5\60"+ - "\31\2\u01bc\u01bd\7\4\2\2\u01bd\u01d0\3\2\2\2\u01be\u01bf\78\2\2\u01bf"+ - "\u01c0\7\3\2\2\u01c0\u01c1\5^\60\2\u01c1\u01c2\7\5\2\2\u01c2\u01c3\5j"+ - "\66\2\u01c3\u01c4\5\60\31\2\u01c4\u01c5\7\4\2\2\u01c5\u01d0\3\2\2\2\u01c6"+ - "\u01c7\78\2\2\u01c7\u01c8\7\3\2\2\u01c8\u01c9\5j\66\2\u01c9\u01ca\7\5"+ - "\2\2\u01ca\u01cb\5j\66\2\u01cb\u01cc\5\60\31\2\u01cc\u01cd\7\4\2\2\u01cd"+ - "\u01d0\3\2\2\2\u01ce\u01d0\5\62\32\2\u01cf\u01b0\3\2\2\2\u01cf\u01b3\3"+ - "\2\2\2\u01cf\u01b8\3\2\2\2\u01cf\u01be\3\2\2\2\u01cf\u01c6\3\2\2\2\u01cf"+ - "\u01ce\3\2\2\2\u01d0\u01d9\3\2\2\2\u01d1\u01d2\f\4\2\2\u01d2\u01d3\7\n"+ - "\2\2\u01d3\u01d8\5.\30\5\u01d4\u01d5\f\3\2\2\u01d5\u01d6\7C\2\2\u01d6"+ - "\u01d8\5.\30\4\u01d7\u01d1\3\2\2\2\u01d7\u01d4\3\2\2\2\u01d8\u01db\3\2"+ - "\2\2\u01d9\u01d7\3\2\2\2\u01d9\u01da\3\2\2\2\u01da/\3\2\2\2\u01db\u01d9"+ - "\3\2\2\2\u01dc\u01dd\7\5\2\2\u01dd\u01df\5j\66\2\u01de\u01dc\3\2\2\2\u01df"+ - "\u01e2\3\2\2\2\u01e0\u01de\3\2\2\2\u01e0\u01e1\3\2\2\2\u01e1\61\3\2\2"+ - "\2\u01e2\u01e0\3\2\2\2\u01e3\u01e5\5<\37\2\u01e4\u01e6\5\64\33\2\u01e5"+ - "\u01e4\3\2\2\2\u01e5\u01e6\3\2\2\2\u01e6\63\3\2\2\2\u01e7\u01e9\7>\2\2"+ - "\u01e8\u01e7\3\2\2\2\u01e8\u01e9\3\2\2\2\u01e9\u01ea\3\2\2\2\u01ea\u01eb"+ - "\7\16\2\2\u01eb\u01ec\5<\37\2\u01ec\u01ed\7\n\2\2\u01ed\u01ee\5<\37\2"+ - "\u01ee\u0216\3\2\2\2\u01ef\u01f1\7>\2\2\u01f0\u01ef\3\2\2\2\u01f0\u01f1"+ - "\3\2\2\2\u01f1\u01f2\3\2\2\2\u01f2\u01f3\7.\2\2\u01f3\u01f4\7\3\2\2\u01f4"+ - "\u01f9\5<\37\2\u01f5\u01f6\7\5\2\2\u01f6\u01f8\5<\37\2\u01f7\u01f5\3\2"+ - "\2\2\u01f8\u01fb\3\2\2\2\u01f9\u01f7\3\2\2\2\u01f9\u01fa\3\2\2\2\u01fa"+ - "\u01fc\3\2\2\2\u01fb\u01f9\3\2\2\2\u01fc\u01fd\7\4\2\2\u01fd\u0216\3\2"+ - "\2\2\u01fe\u0200\7>\2\2\u01ff\u01fe\3\2\2\2\u01ff\u0200\3\2\2\2\u0200"+ - "\u0201\3\2\2\2\u0201\u0202\7.\2\2\u0202\u0203\7\3\2\2\u0203\u0204\5\b"+ - "\5\2\u0204\u0205\7\4\2\2\u0205\u0216\3\2\2\2\u0206\u0208\7>\2\2\u0207"+ - "\u0206\3\2\2\2\u0207\u0208\3\2\2\2\u0208\u0209\3\2\2\2\u0209\u020a\7\65"+ - "\2\2\u020a\u0216\58\35\2\u020b\u020d\7>\2\2\u020c\u020b\3\2\2\2\u020c"+ - "\u020d\3\2\2\2\u020d\u020e\3\2\2\2\u020e\u020f\7J\2\2\u020f\u0216\5j\66"+ - "\2\u0210\u0212\7\61\2\2\u0211\u0213\7>\2\2\u0212\u0211\3\2\2\2\u0212\u0213"+ - "\3\2\2\2\u0213\u0214\3\2\2\2\u0214\u0216\7?\2\2\u0215\u01e8\3\2\2\2\u0215"+ - "\u01f0\3\2\2\2\u0215\u01ff\3\2\2\2\u0215\u0207\3\2\2\2\u0215\u020c\3\2"+ - "\2\2\u0215\u0210\3\2\2\2\u0216\65\3\2\2\2\u0217\u0218\7\65\2\2\u0218\u0219"+ - "\58\35\2\u0219\67\3\2\2\2\u021a\u021c\5j\66\2\u021b\u021d\5:\36\2\u021c"+ - "\u021b\3\2\2\2\u021c\u021d\3\2\2\2\u021d9\3\2\2\2\u021e\u021f\7\36\2\2"+ - "\u021f\u0225\5j\66\2\u0220\u0221\7_\2\2\u0221\u0222\5j\66\2\u0222\u0223"+ - "\7f\2\2\u0223\u0225\3\2\2\2\u0224\u021e\3\2\2\2\u0224\u0220\3\2\2\2\u0225"+ - ";\3\2\2\2\u0226\u0227\b\37\1\2\u0227\u022b\5> \2\u0228\u0229\t\7\2\2\u0229"+ - "\u022b\5<\37\6\u022a\u0226\3\2\2\2\u022a\u0228\3\2\2\2\u022b\u0238\3\2"+ - "\2\2\u022c\u022d\f\5\2\2\u022d\u022e\t\f\2\2\u022e\u0237\5<\37\6\u022f"+ - "\u0230\f\4\2\2\u0230\u0231\t\7\2\2\u0231\u0237\5<\37\5\u0232\u0233\f\3"+ - "\2\2\u0233\u0234\5T+\2\u0234\u0235\5<\37\4\u0235\u0237\3\2\2\2\u0236\u022c"+ - "\3\2\2\2\u0236\u022f\3\2\2\2\u0236\u0232\3\2\2\2\u0237\u023a\3\2\2\2\u0238"+ - "\u0236\3\2\2\2\u0238\u0239\3\2\2\2\u0239=\3\2\2\2\u023a\u0238\3\2\2\2"+ - "\u023b\u023c\b \1\2\u023c\u0251\5B\"\2\u023d\u0251\5H%\2\u023e\u0251\5"+ - "@!\2\u023f\u0251\5R*\2\u0240\u0241\5^\60\2\u0241\u0242\7u\2\2\u0242\u0244"+ - "\3\2\2\2\u0243\u0240\3\2\2\2\u0243\u0244\3\2\2\2\u0244\u0245\3\2\2\2\u0245"+ - "\u0251\7p\2\2\u0246\u0251\5L\'\2\u0247\u0248\7\3\2\2\u0248\u0249\5\b\5"+ - "\2\u0249\u024a\7\4\2\2\u024a\u0251\3\2\2\2\u024b\u0251\5^\60\2\u024c\u024d"+ - "\7\3\2\2\u024d\u024e\5,\27\2\u024e\u024f\7\4\2\2\u024f\u0251\3\2\2\2\u0250"+ - "\u023b\3\2\2\2\u0250\u023d\3\2\2\2\u0250\u023e\3\2\2\2\u0250\u023f\3\2"+ - "\2\2\u0250\u0243\3\2\2\2\u0250\u0246\3\2\2\2\u0250\u0247\3\2\2\2\u0250"+ - "\u024b\3\2\2\2\u0250\u024c\3\2\2\2\u0251\u0257\3\2\2\2\u0252\u0253\f\13"+ - "\2\2\u0253\u0254\7s\2\2\u0254\u0256\5\\/\2\u0255\u0252\3\2\2\2\u0256\u0259"+ - "\3\2\2\2\u0257\u0255\3\2\2\2\u0257\u0258\3\2\2\2\u0258?\3\2\2\2\u0259"+ - "\u0257\3\2\2\2\u025a\u025e\7\27\2\2\u025b\u025e\7\25\2\2\u025c\u025e\7"+ - "\26\2\2\u025d\u025a\3\2\2\2\u025d\u025b\3\2\2\2\u025d\u025c\3\2\2\2\u025e"+ - "A\3\2\2\2\u025f\u026a\5D#\2\u0260\u0261\7`\2\2\u0261\u0262\5D#\2\u0262"+ - "\u0263\7f\2\2\u0263\u026a\3\2\2\2\u0264\u026a\5F$\2\u0265\u0266\7`\2\2"+ - "\u0266\u0267\5F$\2\u0267\u0268\7f\2\2\u0268\u026a\3\2\2\2\u0269\u025f"+ - "\3\2\2\2\u0269\u0260\3\2\2\2\u0269\u0264\3\2\2\2\u0269\u0265\3\2\2\2\u026a"+ - "C\3\2\2\2\u026b\u026c\7\20\2\2\u026c\u026d\7\3\2\2\u026d\u026e\5,\27\2"+ - "\u026e\u026f\7\f\2\2\u026f\u0270\5\\/\2\u0270\u0271\7\4\2\2\u0271E\3\2"+ - "\2\2\u0272\u0273\7\24\2\2\u0273\u0274\7\3\2\2\u0274\u0275\5,\27\2\u0275"+ - "\u0276\7\5\2\2\u0276\u0277\5\\/\2\u0277\u0278\7\4\2\2\u0278G\3\2\2\2\u0279"+ - "\u027f\5J&\2\u027a\u027b\7`\2\2\u027b\u027c\5J&\2\u027c\u027d\7f\2\2\u027d"+ - "\u027f\3\2\2\2\u027e\u0279\3\2\2\2\u027e\u027a\3\2\2\2\u027fI\3\2\2\2"+ - "\u0280\u0281\7\"\2\2\u0281\u0282\7\3\2\2\u0282\u0283\5`\61\2\u0283\u0284"+ - "\7&\2\2\u0284\u0285\5<\37\2\u0285\u0286\7\4\2\2\u0286K\3\2\2\2\u0287\u028d"+ - "\5N(\2\u0288\u0289\7`\2\2\u0289\u028a\5N(\2\u028a\u028b\7f\2\2\u028b\u028d"+ - "\3\2\2\2\u028c\u0287\3\2\2\2\u028c\u0288\3\2\2\2\u028dM\3\2\2\2\u028e"+ - "\u028f\5P)\2\u028f\u029b\7\3\2\2\u0290\u0292\5\36\20\2\u0291\u0290\3\2"+ - "\2\2\u0291\u0292\3\2\2\2\u0292\u0293\3\2\2\2\u0293\u0298\5,\27\2\u0294"+ - "\u0295\7\5\2\2\u0295\u0297\5,\27\2\u0296\u0294\3\2\2\2\u0297\u029a\3\2"+ - "\2\2\u0298\u0296\3\2\2\2\u0298\u0299\3\2\2\2\u0299\u029c\3\2\2\2\u029a"+ - "\u0298\3\2\2\2\u029b\u0291\3\2\2\2\u029b\u029c\3\2\2\2\u029c\u029d\3\2"+ - "\2\2\u029d\u029e\7\4\2\2\u029eO\3\2\2\2\u029f\u02a3\7\64\2\2\u02a0\u02a3"+ - "\7I\2\2\u02a1\u02a3\5`\61\2\u02a2\u029f\3\2\2\2\u02a2\u02a0\3\2\2\2\u02a2"+ - "\u02a1\3\2\2\2\u02a3Q\3\2\2\2\u02a4\u02bf\7?\2\2\u02a5\u02bf\5X-\2\u02a6"+ - "\u02bf\5h\65\2\u02a7\u02bf\5V,\2\u02a8\u02aa\7w\2\2\u02a9\u02a8\3\2\2"+ - "\2\u02aa\u02ab\3\2\2\2\u02ab\u02a9\3\2\2\2\u02ab\u02ac\3\2\2\2\u02ac\u02bf"+ - "\3\2\2\2\u02ad\u02bf\7v\2\2\u02ae\u02af\7b\2\2\u02af\u02b0\5j\66\2\u02b0"+ - "\u02b1\7f\2\2\u02b1\u02bf\3\2\2\2\u02b2\u02b3\7c\2\2\u02b3\u02b4\5j\66"+ - "\2\u02b4\u02b5\7f\2\2\u02b5\u02bf\3\2\2\2\u02b6\u02b7\7d\2\2\u02b7\u02b8"+ - "\5j\66\2\u02b8\u02b9\7f\2\2\u02b9\u02bf\3\2\2\2\u02ba\u02bb\7e\2\2\u02bb"+ - "\u02bc\5j\66\2\u02bc\u02bd\7f\2\2\u02bd\u02bf\3\2\2\2\u02be\u02a4\3\2"+ - "\2\2\u02be\u02a5\3\2\2\2\u02be\u02a6\3\2\2\2\u02be\u02a7\3\2\2\2\u02be"+ - "\u02a9\3\2\2\2\u02be\u02ad\3\2\2\2\u02be\u02ae\3\2\2\2\u02be\u02b2\3\2"+ - "\2\2\u02be\u02b6\3\2\2\2\u02be\u02ba\3\2\2\2\u02bfS\3\2\2\2\u02c0\u02c1"+ - "\t\r\2\2\u02c1U\3\2\2\2\u02c2\u02c3\t\16\2\2\u02c3W\3\2\2\2\u02c4\u02c6"+ - "\7\60\2\2\u02c5\u02c7\t\7\2\2\u02c6\u02c5\3\2\2\2\u02c6\u02c7\3\2\2\2"+ - "\u02c7\u02ca\3\2\2\2\u02c8\u02cb\5h\65\2\u02c9\u02cb\5j\66\2\u02ca\u02c8"+ - "\3\2\2\2\u02ca\u02c9\3\2\2\2\u02cb\u02cc\3\2\2\2\u02cc\u02cf\5Z.\2\u02cd"+ - "\u02ce\7V\2\2\u02ce\u02d0\5Z.\2\u02cf\u02cd\3\2\2\2\u02cf\u02d0\3\2\2"+ - "\2\u02d0Y\3\2\2\2\u02d1\u02d2\t\17\2\2\u02d2[\3\2\2\2\u02d3\u02d4\5`\61"+ - "\2\u02d4]\3\2\2\2\u02d5\u02d6\5`\61\2\u02d6\u02d7\7u\2\2\u02d7\u02d9\3"+ - "\2\2\2\u02d8\u02d5\3\2\2\2\u02d9\u02dc\3\2\2\2\u02da\u02d8\3\2\2\2\u02da"+ - "\u02db\3\2\2\2\u02db\u02dd\3\2\2\2\u02dc\u02da\3\2\2\2\u02dd\u02de\5`"+ - "\61\2\u02de_\3\2\2\2\u02df\u02e2\5d\63\2\u02e0\u02e2\5f\64\2\u02e1\u02df"+ - "\3\2\2\2\u02e1\u02e0\3\2\2\2\u02e2a\3\2\2\2\u02e3\u02e4\5`\61\2\u02e4"+ - "\u02e5\7\6\2\2\u02e5\u02e7\3\2\2\2\u02e6\u02e3\3\2\2\2\u02e6\u02e7\3\2"+ - "\2\2\u02e7\u02e8\3\2\2\2\u02e8\u02f0\7|\2\2\u02e9\u02ea\5`\61\2\u02ea"+ - "\u02eb\7\6\2\2\u02eb\u02ed\3\2\2\2\u02ec\u02e9\3\2\2\2\u02ec\u02ed\3\2"+ - "\2\2\u02ed\u02ee\3\2\2\2\u02ee\u02f0\5`\61\2\u02ef\u02e6\3\2\2\2\u02ef"+ - "\u02ec\3\2\2\2\u02f0c\3\2\2\2\u02f1\u02f4\7}\2\2\u02f2\u02f4\7~\2\2\u02f3"+ - "\u02f1\3\2\2\2\u02f3\u02f2\3\2\2\2\u02f4e\3\2\2\2\u02f5\u02f9\7z\2\2\u02f6"+ - "\u02f9\5l\67\2\u02f7\u02f9\7{\2\2\u02f8\u02f5\3\2\2\2\u02f8\u02f6\3\2"+ - "\2\2\u02f8\u02f7\3\2\2\2\u02f9g\3\2\2\2\u02fa\u02fd\7y\2\2\u02fb\u02fd"+ - "\7x\2\2\u02fc\u02fa\3\2\2\2\u02fc\u02fb\3\2\2\2\u02fdi\3\2\2\2\u02fe\u02ff"+ - "\t\20\2\2\u02ffk\3\2\2\2\u0300\u0301\t\21\2\2\u0301m\3\2\2\2h}\177\u0083"+ - "\u008c\u008e\u0092\u0099\u00a0\u00a5\u00aa\u00b2\u00b6\u00be\u00c1\u00c7"+ - "\u00cc\u00cf\u00d4\u00d7\u00d9\u00e1\u00e4\u00f0\u00f3\u00f6\u00fd\u0104"+ - "\u0108\u010c\u0110\u0117\u011b\u011f\u0124\u0128\u0130\u0134\u013b\u0146"+ - "\u0149\u014d\u0159\u015c\u0162\u0169\u0170\u0173\u0177\u017b\u017f\u0181"+ - "\u018c\u0191\u0195\u0198\u019e\u01a1\u01a7\u01aa\u01ac\u01cf\u01d7\u01d9"+ - "\u01e0\u01e5\u01e8\u01f0\u01f9\u01ff\u0207\u020c\u0212\u0215\u021c\u0224"+ - "\u022a\u0236\u0238\u0243\u0250\u0257\u025d\u0269\u027e\u028c\u0291\u0298"+ - "\u029b\u02a2\u02ab\u02be\u02c6\u02ca\u02cf\u02da\u02e1\u02e6\u02ec\u02ef"+ - "\u02f3\u02f8\u02fc"; + "\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+ + "\3\30\3\30\3\30\5\30\u01d2\n\30\3\30\3\30\3\30\3\30\3\30\3\30\7\30\u01da"+ + "\n\30\f\30\16\30\u01dd\13\30\3\31\3\31\7\31\u01e1\n\31\f\31\16\31\u01e4"+ + "\13\31\3\32\3\32\5\32\u01e8\n\32\3\33\5\33\u01eb\n\33\3\33\3\33\3\33\3"+ + "\33\3\33\3\33\5\33\u01f3\n\33\3\33\3\33\3\33\3\33\3\33\7\33\u01fa\n\33"+ + "\f\33\16\33\u01fd\13\33\3\33\3\33\3\33\5\33\u0202\n\33\3\33\3\33\3\33"+ + "\3\33\3\33\3\33\5\33\u020a\n\33\3\33\3\33\3\33\5\33\u020f\n\33\3\33\3"+ + "\33\3\33\3\33\5\33\u0215\n\33\3\33\5\33\u0218\n\33\3\34\3\34\3\34\3\35"+ + "\3\35\5\35\u021f\n\35\3\36\3\36\3\36\3\36\3\36\3\36\5\36\u0227\n\36\3"+ + "\37\3\37\3\37\3\37\5\37\u022d\n\37\3\37\3\37\3\37\3\37\3\37\3\37\3\37"+ + "\3\37\3\37\3\37\7\37\u0239\n\37\f\37\16\37\u023c\13\37\3 \3 \3 \3 \3 "+ + "\3 \3 \3 \5 \u0246\n \3 \3 \3 \3 \3 \3 \3 \3 \3 \3 \3 \3 \3 \5 \u0255"+ + "\n \3 \6 \u0258\n \r \16 \u0259\3 \3 \5 \u025e\n \3 \3 \5 \u0262\n \3"+ + " \3 \3 \7 \u0267\n \f \16 \u026a\13 \3!\3!\3!\5!\u026f\n!\3\"\3\"\3\""+ + "\3\"\3\"\3\"\3\"\3\"\3\"\3\"\5\"\u027b\n\"\3#\3#\3#\3#\3#\3#\3#\3$\3$"+ + "\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\5%\u0290\n%\3&\3&\3&\3&\3&\3&\3&\3\'\3"+ + "\'\3\'\3\'\3\'\5\'\u029e\n\'\3(\3(\3(\5(\u02a3\n(\3(\3(\3(\7(\u02a8\n"+ + "(\f(\16(\u02ab\13(\5(\u02ad\n(\3(\3(\3)\3)\3)\5)\u02b4\n)\3*\3*\3*\3*"+ + "\3*\6*\u02bb\n*\r*\16*\u02bc\3*\3*\3*\3*\3*\3*\3*\3*\3*\3*\3*\3*\3*\3"+ + "*\3*\3*\3*\5*\u02d0\n*\3+\3+\3,\3,\3-\3-\5-\u02d8\n-\3-\3-\5-\u02dc\n"+ + "-\3-\3-\3-\5-\u02e1\n-\3.\3.\3/\3/\3\60\3\60\3\60\7\60\u02ea\n\60\f\60"+ + "\16\60\u02ed\13\60\3\60\3\60\3\61\3\61\5\61\u02f3\n\61\3\62\3\62\3\62"+ + "\5\62\u02f8\n\62\3\62\3\62\3\62\3\62\5\62\u02fe\n\62\3\62\5\62\u0301\n"+ + "\62\3\63\3\63\5\63\u0305\n\63\3\64\3\64\3\64\5\64\u030a\n\64\3\65\3\65"+ + "\5\65\u030e\n\65\3\66\3\66\3\67\3\67\3\67\3\67\3\67\38\38\38\2\5.<>9\2"+ + "\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJL"+ + "NPRTVXZ\\^`bdfhjln\2\22\b\2\7\7\t\t\"\"::EEII\4\2,,WW\4\2\t\tEE\4\2))"+ + "\61\61\3\2\34\35\3\2st\4\2\7\7}}\4\2\r\r\34\34\4\2\'\'\66\66\4\2\7\7\36"+ + "\36\3\2uw\3\2lr\4\2&&YY\7\2\31\32/\60>EEIKMPSTVW[\\^^bb\u0378\2p\3\2\2"+ + "\2\4s\3\2\2\2\6\u00db\3\2\2\2\b\u00e6\3\2\2\2\n\u00ea\3\2\2\2\f\u00ff"+ + "\3\2\2\2\16\u0106\3\2\2\2\20\u0108\3\2\2\2\22\u0110\3\2\2\2\24\u012c\3"+ + "\2\2\2\26\u0136\3\2\2\2\30\u0140\3\2\2\2\32\u014f\3\2\2\2\34\u0151\3\2"+ + "\2\2\36\u0157\3\2\2\2 \u0159\3\2\2\2\"\u0160\3\2\2\2$\u0172\3\2\2\2&\u0183"+ + "\3\2\2\2(\u0193\3\2\2\2*\u01ae\3\2\2\2,\u01b0\3\2\2\2.\u01d1\3\2\2\2\60"+ + "\u01e2\3\2\2\2\62\u01e5\3\2\2\2\64\u0217\3\2\2\2\66\u0219\3\2\2\28\u021c"+ + "\3\2\2\2:\u0226\3\2\2\2<\u022c\3\2\2\2>\u0261\3\2\2\2@\u026e\3\2\2\2B"+ + "\u027a\3\2\2\2D\u027c\3\2\2\2F\u0283\3\2\2\2H\u028f\3\2\2\2J\u0291\3\2"+ + "\2\2L\u029d\3\2\2\2N\u029f\3\2\2\2P\u02b3\3\2\2\2R\u02cf\3\2\2\2T\u02d1"+ + "\3\2\2\2V\u02d3\3\2\2\2X\u02d5\3\2\2\2Z\u02e2\3\2\2\2\\\u02e4\3\2\2\2"+ + "^\u02eb\3\2\2\2`\u02f2\3\2\2\2b\u0300\3\2\2\2d\u0304\3\2\2\2f\u0309\3"+ + "\2\2\2h\u030d\3\2\2\2j\u030f\3\2\2\2l\u0311\3\2\2\2n\u0316\3\2\2\2pq\5"+ + "\6\4\2qr\7\2\2\3r\3\3\2\2\2st\5,\27\2tu\7\2\2\3u\5\3\2\2\2v\u00dc\5\b"+ + "\5\2w\u0085\7$\2\2x\u0081\7\3\2\2yz\7K\2\2z\u0080\t\2\2\2{|\7(\2\2|\u0080"+ + "\t\3\2\2}~\7^\2\2~\u0080\5V,\2\177y\3\2\2\2\177{\3\2\2\2\177}\3\2\2\2"+ + "\u0080\u0083\3\2\2\2\u0081\177\3\2\2\2\u0081\u0082\3\2\2\2\u0082\u0084"+ + "\3\2\2\2\u0083\u0081\3\2\2\2\u0084\u0086\7\4\2\2\u0085x\3\2\2\2\u0085"+ + "\u0086\3\2\2\2\u0086\u0087\3\2\2\2\u0087\u00dc\5\6\4\2\u0088\u0094\7\33"+ + "\2\2\u0089\u0090\7\3\2\2\u008a\u008b\7K\2\2\u008b\u008f\t\4\2\2\u008c"+ + "\u008d\7(\2\2\u008d\u008f\t\3\2\2\u008e\u008a\3\2\2\2\u008e\u008c\3\2"+ + "\2\2\u008f\u0092\3\2\2\2\u0090\u008e\3\2\2\2\u0090\u0091\3\2\2\2\u0091"+ + "\u0093\3\2\2\2\u0092\u0090\3\2\2\2\u0093\u0095\7\4\2\2\u0094\u0089\3\2"+ + "\2\2\u0094\u0095\3\2\2\2\u0095\u0096\3\2\2\2\u0096\u00dc\5\6\4\2\u0097"+ + "\u0098\7S\2\2\u0098\u009b\7V\2\2\u0099\u009c\5\66\34\2\u009a\u009c\5b"+ + "\62\2\u009b\u0099\3\2\2\2\u009b\u009a\3\2\2\2\u009b\u009c\3\2\2\2\u009c"+ + "\u00dc\3\2\2\2\u009d\u009e\7S\2\2\u009e\u009f\7\24\2\2\u009f\u00a2\t\5"+ + "\2\2\u00a0\u00a3\5\66\34\2\u00a1\u00a3\5b\62\2\u00a2\u00a0\3\2\2\2\u00a2"+ + "\u00a1\3\2\2\2\u00a3\u00dc\3\2\2\2\u00a4\u00a7\t\6\2\2\u00a5\u00a8\5\66"+ + "\34\2\u00a6\u00a8\5b\62\2\u00a7\u00a5\3\2\2\2\u00a7\u00a6\3\2\2\2\u00a8"+ + "\u00dc\3\2\2\2\u00a9\u00aa\7S\2\2\u00aa\u00ac\7+\2\2\u00ab\u00ad\5\66"+ + "\34\2\u00ac\u00ab\3\2\2\2\u00ac\u00ad\3\2\2\2\u00ad\u00dc\3\2\2\2\u00ae"+ + "\u00af\7S\2\2\u00af\u00dc\7O\2\2\u00b0\u00b1\7T\2\2\u00b1\u00b4\7V\2\2"+ + "\u00b2\u00b3\7\22\2\2\u00b3\u00b5\5\66\34\2\u00b4\u00b2\3\2\2\2\u00b4"+ + "\u00b5\3\2\2\2\u00b5\u00b8\3\2\2\2\u00b6\u00b9\5\66\34\2\u00b7\u00b9\5"+ + "b\62\2\u00b8\u00b6\3\2\2\2\u00b8\u00b7\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b9"+ + "\u00c3\3\2\2\2\u00ba\u00bb\7[\2\2\u00bb\u00c0\5j\66\2\u00bc\u00bd\7\5"+ + "\2\2\u00bd\u00bf\5j\66\2\u00be\u00bc\3\2\2\2\u00bf\u00c2\3\2\2\2\u00c0"+ + "\u00be\3\2\2\2\u00c0\u00c1\3\2\2\2\u00c1\u00c4\3\2\2\2\u00c2\u00c0\3\2"+ + "\2\2\u00c3\u00ba\3\2\2\2\u00c3\u00c4\3\2\2\2\u00c4\u00dc\3\2\2\2\u00c5"+ + "\u00c6\7T\2\2\u00c6\u00c9\7\24\2\2\u00c7\u00c8\7\22\2\2\u00c8\u00ca\5"+ + "j\66\2\u00c9\u00c7\3\2\2\2\u00c9\u00ca\3\2\2\2\u00ca\u00ce\3\2\2\2\u00cb"+ + "\u00cc\7U\2\2\u00cc\u00cf\5\66\34\2\u00cd\u00cf\5b\62\2\u00ce\u00cb\3"+ + "\2\2\2\u00ce\u00cd\3\2\2\2\u00ce\u00cf\3\2\2\2\u00cf\u00d1\3\2\2\2\u00d0"+ + "\u00d2\5\66\34\2\u00d1\u00d0\3\2\2\2\u00d1\u00d2\3\2\2\2\u00d2\u00dc\3"+ + "\2\2\2\u00d3\u00d4\7T\2\2\u00d4\u00d9\7\\\2\2\u00d5\u00d7\t\7\2\2\u00d6"+ + "\u00d5\3\2\2\2\u00d6\u00d7\3\2\2\2\u00d7\u00d8\3\2\2\2\u00d8\u00da\5h"+ + "\65\2\u00d9\u00d6\3\2\2\2\u00d9\u00da\3\2\2\2\u00da\u00dc\3\2\2\2\u00db"+ + "v\3\2\2\2\u00dbw\3\2\2\2\u00db\u0088\3\2\2\2\u00db\u0097\3\2\2\2\u00db"+ + "\u009d\3\2\2\2\u00db\u00a4\3\2\2\2\u00db\u00a9\3\2\2\2\u00db\u00ae\3\2"+ + "\2\2\u00db\u00b0\3\2\2\2\u00db\u00c5\3\2\2\2\u00db\u00d3\3\2\2\2\u00dc"+ + "\7\3\2\2\2\u00dd\u00de\7a\2\2\u00de\u00e3\5\34\17\2\u00df\u00e0\7\5\2"+ + "\2\u00e0\u00e2\5\34\17\2\u00e1\u00df\3\2\2\2\u00e2\u00e5\3\2\2\2\u00e3"+ + "\u00e1\3\2\2\2\u00e3\u00e4\3\2\2\2\u00e4\u00e7\3\2\2\2\u00e5\u00e3\3\2"+ + "\2\2\u00e6\u00dd\3\2\2\2\u00e6\u00e7\3\2\2\2\u00e7\u00e8\3\2\2\2\u00e8"+ + "\u00e9\5\n\6\2\u00e9\t\3\2\2\2\u00ea\u00f5\5\16\b\2\u00eb\u00ec\7G\2\2"+ + "\u00ec\u00ed\7\17\2\2\u00ed\u00f2\5\20\t\2\u00ee\u00ef\7\5\2\2\u00ef\u00f1"+ + "\5\20\t\2\u00f0\u00ee\3\2\2\2\u00f1\u00f4\3\2\2\2\u00f2\u00f0\3\2\2\2"+ + "\u00f2\u00f3\3\2\2\2\u00f3\u00f6\3\2\2\2\u00f4\u00f2\3\2\2\2\u00f5\u00eb"+ + "\3\2\2\2\u00f5\u00f6\3\2\2\2\u00f6\u00f8\3\2\2\2\u00f7\u00f9\5\f\7\2\u00f8"+ + "\u00f7\3\2\2\2\u00f8\u00f9\3\2\2\2\u00f9\13\3\2\2\2\u00fa\u00fb\79\2\2"+ + "\u00fb\u0100\t\b\2\2\u00fc\u00fd\7f\2\2\u00fd\u00fe\t\b\2\2\u00fe\u0100"+ + "\7k\2\2\u00ff\u00fa\3\2\2\2\u00ff\u00fc\3\2\2\2\u0100\r\3\2\2\2\u0101"+ + "\u0107\5\22\n\2\u0102\u0103\7\3\2\2\u0103\u0104\5\n\6\2\u0104\u0105\7"+ + "\4\2\2\u0105\u0107\3\2\2\2\u0106\u0101\3\2\2\2\u0106\u0102\3\2\2\2\u0107"+ + "\17\3\2\2\2\u0108\u010a\5,\27\2\u0109\u010b\t\t\2\2\u010a\u0109\3\2\2"+ + "\2\u010a\u010b\3\2\2\2\u010b\u010e\3\2\2\2\u010c\u010d\7C\2\2\u010d\u010f"+ + "\t\n\2\2\u010e\u010c\3\2\2\2\u010e\u010f\3\2\2\2\u010f\21\3\2\2\2\u0110"+ + "\u0112\7R\2\2\u0111\u0113\5\36\20\2\u0112\u0111\3\2\2\2\u0112\u0113\3"+ + "\2\2\2\u0113\u0114\3\2\2\2\u0114\u0119\5 \21\2\u0115\u0116\7\5\2\2\u0116"+ + "\u0118\5 \21\2\u0117\u0115\3\2\2\2\u0118\u011b\3\2\2\2\u0119\u0117\3\2"+ + "\2\2\u0119\u011a\3\2\2\2\u011a\u011d\3\2\2\2\u011b\u0119\3\2\2\2\u011c"+ + "\u011e\5\24\13\2\u011d\u011c\3\2\2\2\u011d\u011e\3\2\2\2\u011e\u0121\3"+ + "\2\2\2\u011f\u0120\7`\2\2\u0120\u0122\5.\30\2\u0121\u011f\3\2\2\2\u0121"+ + "\u0122\3\2\2\2\u0122\u0126\3\2\2\2\u0123\u0124\7-\2\2\u0124\u0125\7\17"+ + "\2\2\u0125\u0127\5\26\f\2\u0126\u0123\3\2\2\2\u0126\u0127\3\2\2\2\u0127"+ + "\u012a\3\2\2\2\u0128\u0129\7.\2\2\u0129\u012b\5.\30\2\u012a\u0128\3\2"+ + "\2\2\u012a\u012b\3\2\2\2\u012b\23\3\2\2\2\u012c\u012d\7)\2\2\u012d\u0132"+ + "\5\"\22\2\u012e\u012f\7\5\2\2\u012f\u0131\5\"\22\2\u0130\u012e\3\2\2\2"+ + "\u0131\u0134\3\2\2\2\u0132\u0130\3\2\2\2\u0132\u0133\3\2\2\2\u0133\25"+ + "\3\2\2\2\u0134\u0132\3\2\2\2\u0135\u0137\5\36\20\2\u0136\u0135\3\2\2\2"+ + "\u0136\u0137\3\2\2\2\u0137\u0138\3\2\2\2\u0138\u013d\5\30\r\2\u0139\u013a"+ + "\7\5\2\2\u013a\u013c\5\30\r\2\u013b\u0139\3\2\2\2\u013c\u013f\3\2\2\2"+ + "\u013d\u013b\3\2\2\2\u013d\u013e\3\2\2\2\u013e\27\3\2\2\2\u013f\u013d"+ + "\3\2\2\2\u0140\u0141\5\32\16\2\u0141\31\3\2\2\2\u0142\u014b\7\3\2\2\u0143"+ + "\u0148\5,\27\2\u0144\u0145\7\5\2\2\u0145\u0147\5,\27\2\u0146\u0144\3\2"+ + "\2\2\u0147\u014a\3\2\2\2\u0148\u0146\3\2\2\2\u0148\u0149\3\2\2\2\u0149"+ + "\u014c\3\2\2\2\u014a\u0148\3\2\2\2\u014b\u0143\3\2\2\2\u014b\u014c\3\2"+ + "\2\2\u014c\u014d\3\2\2\2\u014d\u0150\7\4\2\2\u014e\u0150\5,\27\2\u014f"+ + "\u0142\3\2\2\2\u014f\u014e\3\2\2\2\u0150\33\3\2\2\2\u0151\u0152\5`\61"+ + "\2\u0152\u0153\7\f\2\2\u0153\u0154\7\3\2\2\u0154\u0155\5\n\6\2\u0155\u0156"+ + "\7\4\2\2\u0156\35\3\2\2\2\u0157\u0158\t\13\2\2\u0158\37\3\2\2\2\u0159"+ + "\u015e\5,\27\2\u015a\u015c\7\f\2\2\u015b\u015a\3\2\2\2\u015b\u015c\3\2"+ + "\2\2\u015c\u015d\3\2\2\2\u015d\u015f\5`\61\2\u015e\u015b\3\2\2\2\u015e"+ + "\u015f\3\2\2\2\u015f!\3\2\2\2\u0160\u0164\5*\26\2\u0161\u0163\5$\23\2"+ + "\u0162\u0161\3\2\2\2\u0163\u0166\3\2\2\2\u0164\u0162\3\2\2\2\u0164\u0165"+ + "\3\2\2\2\u0165#\3\2\2\2\u0166\u0164\3\2\2\2\u0167\u0168\5&\24\2\u0168"+ + "\u0169\7\65\2\2\u0169\u016b\5*\26\2\u016a\u016c\5(\25\2\u016b\u016a\3"+ + "\2\2\2\u016b\u016c\3\2\2\2\u016c\u0173\3\2\2\2\u016d\u016e\7@\2\2\u016e"+ + "\u016f\5&\24\2\u016f\u0170\7\65\2\2\u0170\u0171\5*\26\2\u0171\u0173\3"+ + "\2\2\2\u0172\u0167\3\2\2\2\u0172\u016d\3\2\2\2\u0173%\3\2\2\2\u0174\u0176"+ + "\7\62\2\2\u0175\u0174\3\2\2\2\u0175\u0176\3\2\2\2\u0176\u0184\3\2\2\2"+ + "\u0177\u0179\7\67\2\2\u0178\u017a\7H\2\2\u0179\u0178\3\2\2\2\u0179\u017a"+ + "\3\2\2\2\u017a\u0184\3\2\2\2\u017b\u017d\7L\2\2\u017c\u017e\7H\2\2\u017d"+ + "\u017c\3\2\2\2\u017d\u017e\3\2\2\2\u017e\u0184\3\2\2\2\u017f\u0181\7*"+ + "\2\2\u0180\u0182\7H\2\2\u0181\u0180\3\2\2\2\u0181\u0182\3\2\2\2\u0182"+ + "\u0184\3\2\2\2\u0183\u0175\3\2\2\2\u0183\u0177\3\2\2\2\u0183\u017b\3\2"+ + "\2\2\u0183\u017f\3\2\2\2\u0184\'\3\2\2\2\u0185\u0186\7D\2\2\u0186\u0194"+ + "\5.\30\2\u0187\u0188\7]\2\2\u0188\u0189\7\3\2\2\u0189\u018e\5`\61\2\u018a"+ + "\u018b\7\5\2\2\u018b\u018d\5`\61\2\u018c\u018a\3\2\2\2\u018d\u0190\3\2"+ + "\2\2\u018e\u018c\3\2\2\2\u018e\u018f\3\2\2\2\u018f\u0191\3\2\2\2\u0190"+ + "\u018e\3\2\2\2\u0191\u0192\7\4\2\2\u0192\u0194\3\2\2\2\u0193\u0185\3\2"+ + "\2\2\u0193\u0187\3\2\2\2\u0194)\3\2\2\2\u0195\u019a\5b\62\2\u0196\u0198"+ + "\7\f\2\2\u0197\u0196\3\2\2\2\u0197\u0198\3\2\2\2\u0198\u0199\3\2\2\2\u0199"+ + "\u019b\5^\60\2\u019a\u0197\3\2\2\2\u019a\u019b\3\2\2\2\u019b\u01af\3\2"+ + "\2\2\u019c\u019d\7\3\2\2\u019d\u019e\5\n\6\2\u019e\u01a3\7\4\2\2\u019f"+ + "\u01a1\7\f\2\2\u01a0\u019f\3\2\2\2\u01a0\u01a1\3\2\2\2\u01a1\u01a2\3\2"+ + "\2\2\u01a2\u01a4\5^\60\2\u01a3\u01a0\3\2\2\2\u01a3\u01a4\3\2\2\2\u01a4"+ + "\u01af\3\2\2\2\u01a5\u01a6\7\3\2\2\u01a6\u01a7\5\"\22\2\u01a7\u01ac\7"+ + "\4\2\2\u01a8\u01aa\7\f\2\2\u01a9\u01a8\3\2\2\2\u01a9\u01aa\3\2\2\2\u01aa"+ + "\u01ab\3\2\2\2\u01ab\u01ad\5^\60\2\u01ac\u01a9\3\2\2\2\u01ac\u01ad\3\2"+ + "\2\2\u01ad\u01af\3\2\2\2\u01ae\u0195\3\2\2\2\u01ae\u019c\3\2\2\2\u01ae"+ + "\u01a5\3\2\2\2\u01af+\3\2\2\2\u01b0\u01b1\5.\30\2\u01b1-\3\2\2\2\u01b2"+ + "\u01b3\b\30\1\2\u01b3\u01b4\7A\2\2\u01b4\u01d2\5.\30\n\u01b5\u01b6\7#"+ + "\2\2\u01b6\u01b7\7\3\2\2\u01b7\u01b8\5\b\5\2\u01b8\u01b9\7\4\2\2\u01b9"+ + "\u01d2\3\2\2\2\u01ba\u01bb\7N\2\2\u01bb\u01bc\7\3\2\2\u01bc\u01bd\5j\66"+ + "\2\u01bd\u01be\5\60\31\2\u01be\u01bf\7\4\2\2\u01bf\u01d2\3\2\2\2\u01c0"+ + "\u01c1\7;\2\2\u01c1\u01c2\7\3\2\2\u01c2\u01c3\5^\60\2\u01c3\u01c4\7\5"+ + "\2\2\u01c4\u01c5\5j\66\2\u01c5\u01c6\5\60\31\2\u01c6\u01c7\7\4\2\2\u01c7"+ + "\u01d2\3\2\2\2\u01c8\u01c9\7;\2\2\u01c9\u01ca\7\3\2\2\u01ca\u01cb\5j\66"+ + "\2\u01cb\u01cc\7\5\2\2\u01cc\u01cd\5j\66\2\u01cd\u01ce\5\60\31\2\u01ce"+ + "\u01cf\7\4\2\2\u01cf\u01d2\3\2\2\2\u01d0\u01d2\5\62\32\2\u01d1\u01b2\3"+ + "\2\2\2\u01d1\u01b5\3\2\2\2\u01d1\u01ba\3\2\2\2\u01d1\u01c0\3\2\2\2\u01d1"+ + "\u01c8\3\2\2\2\u01d1\u01d0\3\2\2\2\u01d2\u01db\3\2\2\2\u01d3\u01d4\f\4"+ + "\2\2\u01d4\u01d5\7\n\2\2\u01d5\u01da\5.\30\5\u01d6\u01d7\f\3\2\2\u01d7"+ + "\u01d8\7F\2\2\u01d8\u01da\5.\30\4\u01d9\u01d3\3\2\2\2\u01d9\u01d6\3\2"+ + "\2\2\u01da\u01dd\3\2\2\2\u01db\u01d9\3\2\2\2\u01db\u01dc\3\2\2\2\u01dc"+ + "/\3\2\2\2\u01dd\u01db\3\2\2\2\u01de\u01df\7\5\2\2\u01df\u01e1\5j\66\2"+ + "\u01e0\u01de\3\2\2\2\u01e1\u01e4\3\2\2\2\u01e2\u01e0\3\2\2\2\u01e2\u01e3"+ + "\3\2\2\2\u01e3\61\3\2\2\2\u01e4\u01e2\3\2\2\2\u01e5\u01e7\5<\37\2\u01e6"+ + "\u01e8\5\64\33\2\u01e7\u01e6\3\2\2\2\u01e7\u01e8\3\2\2\2\u01e8\63\3\2"+ + "\2\2\u01e9\u01eb\7A\2\2\u01ea\u01e9\3\2\2\2\u01ea\u01eb\3\2\2\2\u01eb"+ + "\u01ec\3\2\2\2\u01ec\u01ed\7\16\2\2\u01ed\u01ee\5<\37\2\u01ee\u01ef\7"+ + "\n\2\2\u01ef\u01f0\5<\37\2\u01f0\u0218\3\2\2\2\u01f1\u01f3\7A\2\2\u01f2"+ + "\u01f1\3\2\2\2\u01f2\u01f3\3\2\2\2\u01f3\u01f4\3\2\2\2\u01f4\u01f5\7\61"+ + "\2\2\u01f5\u01f6\7\3\2\2\u01f6\u01fb\5<\37\2\u01f7\u01f8\7\5\2\2\u01f8"+ + "\u01fa\5<\37\2\u01f9\u01f7\3\2\2\2\u01fa\u01fd\3\2\2\2\u01fb\u01f9\3\2"+ + "\2\2\u01fb\u01fc\3\2\2\2\u01fc\u01fe\3\2\2\2\u01fd\u01fb\3\2\2\2\u01fe"+ + "\u01ff\7\4\2\2\u01ff\u0218\3\2\2\2\u0200\u0202\7A\2\2\u0201\u0200\3\2"+ + "\2\2\u0201\u0202\3\2\2\2\u0202\u0203\3\2\2\2\u0203\u0204\7\61\2\2\u0204"+ + "\u0205\7\3\2\2\u0205\u0206\5\b\5\2\u0206\u0207\7\4\2\2\u0207\u0218\3\2"+ + "\2\2\u0208\u020a\7A\2\2\u0209\u0208\3\2\2\2\u0209\u020a\3\2\2\2\u020a"+ + "\u020b\3\2\2\2\u020b\u020c\78\2\2\u020c\u0218\58\35\2\u020d\u020f\7A\2"+ + "\2\u020e\u020d\3\2\2\2\u020e\u020f\3\2\2\2\u020f\u0210\3\2\2\2\u0210\u0211"+ + "\7M\2\2\u0211\u0218\5j\66\2\u0212\u0214\7\64\2\2\u0213\u0215\7A\2\2\u0214"+ + "\u0213\3\2\2\2\u0214\u0215\3\2\2\2\u0215\u0216\3\2\2\2\u0216\u0218\7B"+ + "\2\2\u0217\u01ea\3\2\2\2\u0217\u01f2\3\2\2\2\u0217\u0201\3\2\2\2\u0217"+ + "\u0209\3\2\2\2\u0217\u020e\3\2\2\2\u0217\u0212\3\2\2\2\u0218\65\3\2\2"+ + "\2\u0219\u021a\78\2\2\u021a\u021b\58\35\2\u021b\67\3\2\2\2\u021c\u021e"+ + "\5j\66\2\u021d\u021f\5:\36\2\u021e\u021d\3\2\2\2\u021e\u021f\3\2\2\2\u021f"+ + "9\3\2\2\2\u0220\u0221\7!\2\2\u0221\u0227\5j\66\2\u0222\u0223\7d\2\2\u0223"+ + "\u0224\5j\66\2\u0224\u0225\7k\2\2\u0225\u0227\3\2\2\2\u0226\u0220\3\2"+ + "\2\2\u0226\u0222\3\2\2\2\u0227;\3\2\2\2\u0228\u0229\b\37\1\2\u0229\u022d"+ + "\5> \2\u022a\u022b\t\7\2\2\u022b\u022d\5<\37\6\u022c\u0228\3\2\2\2\u022c"+ + "\u022a\3\2\2\2\u022d\u023a\3\2\2\2\u022e\u022f\f\5\2\2\u022f\u0230\t\f"+ + "\2\2\u0230\u0239\5<\37\6\u0231\u0232\f\4\2\2\u0232\u0233\t\7\2\2\u0233"+ + "\u0239\5<\37\5\u0234\u0235\f\3\2\2\u0235\u0236\5T+\2\u0236\u0237\5<\37"+ + "\4\u0237\u0239\3\2\2\2\u0238\u022e\3\2\2\2\u0238\u0231\3\2\2\2\u0238\u0234"+ + "\3\2\2\2\u0239\u023c\3\2\2\2\u023a\u0238\3\2\2\2\u023a\u023b\3\2\2\2\u023b"+ + "=\3\2\2\2\u023c\u023a\3\2\2\2\u023d\u023e\b \1\2\u023e\u0262\5B\"\2\u023f"+ + "\u0262\5H%\2\u0240\u0262\5@!\2\u0241\u0262\5R*\2\u0242\u0243\5^\60\2\u0243"+ + "\u0244\7z\2\2\u0244\u0246\3\2\2\2\u0245\u0242\3\2\2\2\u0245\u0246\3\2"+ + "\2\2\u0246\u0247\3\2\2\2\u0247\u0262\7u\2\2\u0248\u0262\5L\'\2\u0249\u024a"+ + "\7\3\2\2\u024a\u024b\5\b\5\2\u024b\u024c\7\4\2\2\u024c\u0262\3\2\2\2\u024d"+ + "\u0262\5^\60\2\u024e\u024f\7\3\2\2\u024f\u0250\5,\27\2\u0250\u0251\7\4"+ + "\2\2\u0251\u0262\3\2\2\2\u0252\u0254\7\20\2\2\u0253\u0255\5.\30\2\u0254"+ + "\u0253\3\2\2\2\u0254\u0255\3\2\2\2\u0255\u0257\3\2\2\2\u0256\u0258\5l"+ + "\67\2\u0257\u0256\3\2\2\2\u0258\u0259\3\2\2\2\u0259\u0257\3\2\2\2\u0259"+ + "\u025a\3\2\2\2\u025a\u025d\3\2\2\2\u025b\u025c\7\37\2\2\u025c\u025e\5"+ + ".\30\2\u025d\u025b\3\2\2\2\u025d\u025e\3\2\2\2\u025e\u025f\3\2\2\2\u025f"+ + "\u0260\7 \2\2\u0260\u0262\3\2\2\2\u0261\u023d\3\2\2\2\u0261\u023f\3\2"+ + "\2\2\u0261\u0240\3\2\2\2\u0261\u0241\3\2\2\2\u0261\u0245\3\2\2\2\u0261"+ + "\u0248\3\2\2\2\u0261\u0249\3\2\2\2\u0261\u024d\3\2\2\2\u0261\u024e\3\2"+ + "\2\2\u0261\u0252\3\2\2\2\u0262\u0268\3\2\2\2\u0263\u0264\f\f\2\2\u0264"+ + "\u0265\7x\2\2\u0265\u0267\5\\/\2\u0266\u0263\3\2\2\2\u0267\u026a\3\2\2"+ + "\2\u0268\u0266\3\2\2\2\u0268\u0269\3\2\2\2\u0269?\3\2\2\2\u026a\u0268"+ + "\3\2\2\2\u026b\u026f\7\30\2\2\u026c\u026f\7\26\2\2\u026d\u026f\7\27\2"+ + "\2\u026e\u026b\3\2\2\2\u026e\u026c\3\2\2\2\u026e\u026d\3\2\2\2\u026fA"+ + "\3\2\2\2\u0270\u027b\5D#\2\u0271\u0272\7e\2\2\u0272\u0273\5D#\2\u0273"+ + "\u0274\7k\2\2\u0274\u027b\3\2\2\2\u0275\u027b\5F$\2\u0276\u0277\7e\2\2"+ + "\u0277\u0278\5F$\2\u0278\u0279\7k\2\2\u0279\u027b\3\2\2\2\u027a\u0270"+ + "\3\2\2\2\u027a\u0271\3\2\2\2\u027a\u0275\3\2\2\2\u027a\u0276\3\2\2\2\u027b"+ + "C\3\2\2\2\u027c\u027d\7\21\2\2\u027d\u027e\7\3\2\2\u027e\u027f\5,\27\2"+ + "\u027f\u0280\7\f\2\2\u0280\u0281\5\\/\2\u0281\u0282\7\4\2\2\u0282E\3\2"+ + "\2\2\u0283\u0284\7\25\2\2\u0284\u0285\7\3\2\2\u0285\u0286\5,\27\2\u0286"+ + "\u0287\7\5\2\2\u0287\u0288\5\\/\2\u0288\u0289\7\4\2\2\u0289G\3\2\2\2\u028a"+ + "\u0290\5J&\2\u028b\u028c\7e\2\2\u028c\u028d\5J&\2\u028d\u028e\7k\2\2\u028e"+ + "\u0290\3\2\2\2\u028f\u028a\3\2\2\2\u028f\u028b\3\2\2\2\u0290I\3\2\2\2"+ + "\u0291\u0292\7%\2\2\u0292\u0293\7\3\2\2\u0293\u0294\5`\61\2\u0294\u0295"+ + "\7)\2\2\u0295\u0296\5<\37\2\u0296\u0297\7\4\2\2\u0297K\3\2\2\2\u0298\u029e"+ + "\5N(\2\u0299\u029a\7e\2\2\u029a\u029b\5N(\2\u029b\u029c\7k\2\2\u029c\u029e"+ + "\3\2\2\2\u029d\u0298\3\2\2\2\u029d\u0299\3\2\2\2\u029eM\3\2\2\2\u029f"+ + "\u02a0\5P)\2\u02a0\u02ac\7\3\2\2\u02a1\u02a3\5\36\20\2\u02a2\u02a1\3\2"+ + "\2\2\u02a2\u02a3\3\2\2\2\u02a3\u02a4\3\2\2\2\u02a4\u02a9\5,\27\2\u02a5"+ + "\u02a6\7\5\2\2\u02a6\u02a8\5,\27\2\u02a7\u02a5\3\2\2\2\u02a8\u02ab\3\2"+ + "\2\2\u02a9\u02a7\3\2\2\2\u02a9\u02aa\3\2\2\2\u02aa\u02ad\3\2\2\2\u02ab"+ + "\u02a9\3\2\2\2\u02ac\u02a2\3\2\2\2\u02ac\u02ad\3\2\2\2\u02ad\u02ae\3\2"+ + "\2\2\u02ae\u02af\7\4\2\2\u02afO\3\2\2\2\u02b0\u02b4\7\67\2\2\u02b1\u02b4"+ + "\7L\2\2\u02b2\u02b4\5`\61\2\u02b3\u02b0\3\2\2\2\u02b3\u02b1\3\2\2\2\u02b3"+ + "\u02b2\3\2\2\2\u02b4Q\3\2\2\2\u02b5\u02d0\7B\2\2\u02b6\u02d0\5X-\2\u02b7"+ + "\u02d0\5h\65\2\u02b8\u02d0\5V,\2\u02b9\u02bb\7|\2\2\u02ba\u02b9\3\2\2"+ + "\2\u02bb\u02bc\3\2\2\2\u02bc\u02ba\3\2\2\2\u02bc\u02bd\3\2\2\2\u02bd\u02d0"+ + "\3\2\2\2\u02be\u02d0\7{\2\2\u02bf\u02c0\7g\2\2\u02c0\u02c1\5j\66\2\u02c1"+ + "\u02c2\7k\2\2\u02c2\u02d0\3\2\2\2\u02c3\u02c4\7h\2\2\u02c4\u02c5\5j\66"+ + "\2\u02c5\u02c6\7k\2\2\u02c6\u02d0\3\2\2\2\u02c7\u02c8\7i\2\2\u02c8\u02c9"+ + "\5j\66\2\u02c9\u02ca\7k\2\2\u02ca\u02d0\3\2\2\2\u02cb\u02cc\7j\2\2\u02cc"+ + "\u02cd\5j\66\2\u02cd\u02ce\7k\2\2\u02ce\u02d0\3\2\2\2\u02cf\u02b5\3\2"+ + "\2\2\u02cf\u02b6\3\2\2\2\u02cf\u02b7\3\2\2\2\u02cf\u02b8\3\2\2\2\u02cf"+ + "\u02ba\3\2\2\2\u02cf\u02be\3\2\2\2\u02cf\u02bf\3\2\2\2\u02cf\u02c3\3\2"+ + "\2\2\u02cf\u02c7\3\2\2\2\u02cf\u02cb\3\2\2\2\u02d0S\3\2\2\2\u02d1\u02d2"+ + "\t\r\2\2\u02d2U\3\2\2\2\u02d3\u02d4\t\16\2\2\u02d4W\3\2\2\2\u02d5\u02d7"+ + "\7\63\2\2\u02d6\u02d8\t\7\2\2\u02d7\u02d6\3\2\2\2\u02d7\u02d8\3\2\2\2"+ + "\u02d8\u02db\3\2\2\2\u02d9\u02dc\5h\65\2\u02da\u02dc\5j\66\2\u02db\u02d9"+ + "\3\2\2\2\u02db\u02da\3\2\2\2\u02dc\u02dd\3\2\2\2\u02dd\u02e0\5Z.\2\u02de"+ + "\u02df\7Z\2\2\u02df\u02e1\5Z.\2\u02e0\u02de\3\2\2\2\u02e0\u02e1\3\2\2"+ + "\2\u02e1Y\3\2\2\2\u02e2\u02e3\t\17\2\2\u02e3[\3\2\2\2\u02e4\u02e5\5`\61"+ + "\2\u02e5]\3\2\2\2\u02e6\u02e7\5`\61\2\u02e7\u02e8\7z\2\2\u02e8\u02ea\3"+ + "\2\2\2\u02e9\u02e6\3\2\2\2\u02ea\u02ed\3\2\2\2\u02eb\u02e9\3\2\2\2\u02eb"+ + "\u02ec\3\2\2\2\u02ec\u02ee\3\2\2\2\u02ed\u02eb\3\2\2\2\u02ee\u02ef\5`"+ + "\61\2\u02ef_\3\2\2\2\u02f0\u02f3\5d\63\2\u02f1\u02f3\5f\64\2\u02f2\u02f0"+ + "\3\2\2\2\u02f2\u02f1\3\2\2\2\u02f3a\3\2\2\2\u02f4\u02f5\5`\61\2\u02f5"+ + "\u02f6\7\6\2\2\u02f6\u02f8\3\2\2\2\u02f7\u02f4\3\2\2\2\u02f7\u02f8\3\2"+ + "\2\2\u02f8\u02f9\3\2\2\2\u02f9\u0301\7\u0081\2\2\u02fa\u02fb\5`\61\2\u02fb"+ + "\u02fc\7\6\2\2\u02fc\u02fe\3\2\2\2\u02fd\u02fa\3\2\2\2\u02fd\u02fe\3\2"+ + "\2\2\u02fe\u02ff\3\2\2\2\u02ff\u0301\5`\61\2\u0300\u02f7\3\2\2\2\u0300"+ + "\u02fd\3\2\2\2\u0301c\3\2\2\2\u0302\u0305\7\u0082\2\2\u0303\u0305\7\u0083"+ + "\2\2\u0304\u0302\3\2\2\2\u0304\u0303\3\2\2\2\u0305e\3\2\2\2\u0306\u030a"+ + "\7\177\2\2\u0307\u030a\5n8\2\u0308\u030a\7\u0080\2\2\u0309\u0306\3\2\2"+ + "\2\u0309\u0307\3\2\2\2\u0309\u0308\3\2\2\2\u030ag\3\2\2\2\u030b\u030e"+ + "\7~\2\2\u030c\u030e\7}\2\2\u030d\u030b\3\2\2\2\u030d\u030c\3\2\2\2\u030e"+ + "i\3\2\2\2\u030f\u0310\t\20\2\2\u0310k\3\2\2\2\u0311\u0312\7_\2\2\u0312"+ + "\u0313\5,\27\2\u0313\u0314\7X\2\2\u0314\u0315\5,\27\2\u0315m\3\2\2\2\u0316"+ + "\u0317\t\21\2\2\u0317o\3\2\2\2k\177\u0081\u0085\u008e\u0090\u0094\u009b"+ + "\u00a2\u00a7\u00ac\u00b4\u00b8\u00c0\u00c3\u00c9\u00ce\u00d1\u00d6\u00d9"+ + "\u00db\u00e3\u00e6\u00f2\u00f5\u00f8\u00ff\u0106\u010a\u010e\u0112\u0119"+ + "\u011d\u0121\u0126\u012a\u0132\u0136\u013d\u0148\u014b\u014f\u015b\u015e"+ + "\u0164\u016b\u0172\u0175\u0179\u017d\u0181\u0183\u018e\u0193\u0197\u019a"+ + "\u01a0\u01a3\u01a9\u01ac\u01ae\u01d1\u01d9\u01db\u01e2\u01e7\u01ea\u01f2"+ + "\u01fb\u0201\u0209\u020e\u0214\u0217\u021e\u0226\u022c\u0238\u023a\u0245"+ + "\u0254\u0259\u025d\u0261\u0268\u026e\u027a\u028f\u029d\u02a2\u02a9\u02ac"+ + "\u02b3\u02bc\u02cf\u02d7\u02db\u02e0\u02eb\u02f2\u02f7\u02fd\u0300\u0304"+ + "\u0309\u030d"; public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); static { diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseVisitor.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseVisitor.java index 56310aa66eb..7f44a1593c2 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseVisitor.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/parser/SqlBaseVisitor.java @@ -414,6 +414,13 @@ interface SqlBaseVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitSubqueryExpression(SqlBaseParser.SubqueryExpressionContext ctx); + /** + * Visit a parse tree produced by the {@code case} + * labeled alternative in {@link SqlBaseParser#primaryExpression}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitCase(SqlBaseParser.CaseContext ctx); /** * Visit a parse tree produced by {@link SqlBaseParser#builtinDateTimeFunction}. * @param ctx the parse tree @@ -635,6 +642,12 @@ interface SqlBaseVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitString(SqlBaseParser.StringContext ctx); + /** + * Visit a parse tree produced by {@link SqlBaseParser#whenClause}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitWhenClause(SqlBaseParser.WhenClauseContext ctx); /** * Visit a parse tree produced by {@link SqlBaseParser#nonReserved}. * @param ctx the parse tree diff --git a/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt b/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt index 56b91138944..4ac4632572c 100644 --- a/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt +++ b/x-pack/plugin/sql/src/main/resources/org/elasticsearch/xpack/sql/plugin/sql_whitelist.txt @@ -47,8 +47,9 @@ class org.elasticsearch.xpack.sql.expression.function.scalar.whitelist.InternalS Boolean isNotNull(Object) # -# Null +# Conditional # + def caseFunction(java.util.List) def coalesce(java.util.List) def greatest(java.util.List) def least(java.util.List) diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java index c2310aa331e..24e993a2d83 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/analyzer/VerifierErrorMessagesTests.java @@ -598,6 +598,26 @@ public class VerifierErrorMessagesTests extends ESTestCase { error("SELECT 1 = 1 OR " + arbirtraryArgsFunction + "(null, 3, '4') > 1")); } + public void testCaseWithNonBooleanConditionExpression() { + assertEquals("1:8: condition of [WHEN abs(int) THEN 'foo'] must be [boolean], found value [abs(int)] type [integer]", + error("SELECT CASE WHEN int = 1 THEN 'one' WHEN abs(int) THEN 'foo' END FROM test")); + } + + public void testCaseWithDifferentResultDataTypes() { + assertEquals("1:8: result of [WHEN int > 10 THEN 10] must be [keyword], found value [10] type [integer]", + error("SELECT CASE WHEN int > 20 THEN 'foo' WHEN int > 10 THEN 10 ELSE 'bar' END FROM test")); + } + + public void testCaseWithDifferentResultAndDefaultValueDataTypes() { + assertEquals("1:8: ELSE clause of [date] must be [keyword], found value [date] type [datetime]", + error("SELECT CASE WHEN int > 20 THEN 'foo' ELSE date END FROM test")); + } + + public void testCaseWithDifferentResultAndDefaultValueDataTypesAndNullTypesSkipped() { + assertEquals("1:8: ELSE clause of [date] must be [keyword], found value [date] type [datetime]", + error("SELECT CASE WHEN int > 20 THEN null WHEN int > 10 THEN null WHEN int > 5 THEN 'foo' ELSE date END FROM test")); + } + public void testAggsInWhere() { assertEquals("1:33: Cannot use WHERE filtering on aggregate function [MAX(int)], use HAVING instead", error("SELECT MAX(int) FROM test WHERE MAX(int) > 10 GROUP BY bool")); diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/CaseTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/CaseTests.java new file mode 100644 index 00000000000..efc86bb47d2 --- /dev/null +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/expression/predicate/conditional/CaseTests.java @@ -0,0 +1,100 @@ +/* + * 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.predicate.conditional; + +import org.elasticsearch.xpack.sql.expression.Expression; +import org.elasticsearch.xpack.sql.expression.function.scalar.FunctionTestUtils; +import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.Equals; +import org.elasticsearch.xpack.sql.tree.AbstractNodeTestCase; +import org.elasticsearch.xpack.sql.tree.NodeSubclassTests; +import org.elasticsearch.xpack.sql.tree.Source; +import org.elasticsearch.xpack.sql.tree.SourceTests; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static org.elasticsearch.xpack.sql.expression.function.scalar.FunctionTestUtils.randomIntLiteral; +import static org.elasticsearch.xpack.sql.expression.function.scalar.FunctionTestUtils.randomStringLiteral; +import static org.elasticsearch.xpack.sql.tree.SourceTests.randomSource; + +/** + * Needed to override tests in {@link NodeSubclassTests} as Case is special since its children are not usual + * expressions but {@link IfConditional}s. + */ +public class CaseTests extends AbstractNodeTestCase { + + public static Case randomCase() { + int noConditionals = randomIntBetween(1, 5); + List expressions = new ArrayList<>(noConditionals + 1); + for (int i = 0; i < noConditionals; i++) { + expressions.add(new IfConditional( + randomSource(), new Equals(randomSource(), randomStringLiteral(), randomStringLiteral()), randomIntLiteral())); + + } + // default else + expressions.add(randomIntLiteral()); + return new Case(randomSource(), expressions); + } + + @Override + protected Case randomInstance() { + return randomCase(); + } + + @Override + protected Case mutate(Case instance) { + Case c = randomCase(); + return new Case(c.source(), mutateChildren(c)); + } + + @Override + protected Case copy(Case instance) { + return new Case(instance.source(), instance.children()); + } + + @Override + public void testTransform() { + Case c = randomCase(); + + Source newSource = randomValueOtherThan(c.source(), SourceTests::randomSource); + assertEquals(new Case(c.source(), c.children()), + c.transformPropertiesOnly(p -> Objects.equals(p, c.source()) ? newSource: p, Object.class)); + + String newName = randomValueOtherThan(c.name(), () -> randomAlphaOfLength(5)); + assertEquals(new Case(c.source(), c.children()), + c.transformPropertiesOnly(p -> Objects.equals(p, c.name()) ? newName : p, Object.class)); + } + + @Override + public void testReplaceChildren() { + Case c = randomCase(); + + List newChildren = mutateChildren(c); + assertEquals(new Case(c.source(), newChildren), c.replaceChildren(newChildren)); + } + + private List mutateChildren(Case c) { + boolean removeConditional = randomBoolean(); + List expressions = new ArrayList<>(c.children().size()); + if (removeConditional) { + expressions.addAll(c.children().subList(0, c.children().size() - 2)); + } else { + int rndIdx = randomInt(c.conditions().size()); + for (int i = 0; i < c.conditions().size(); i++) { + if (i == rndIdx) { + expressions.add(new IfConditional(randomValueOtherThan(c.conditions().get(i).source(), SourceTests::randomSource), + new Equals(randomSource(), randomStringLiteral(), randomStringLiteral()), + randomValueOtherThan(c.conditions().get(i).condition(), FunctionTestUtils::randomStringLiteral))); + } else { + expressions.add(c.conditions().get(i)); + } + } + } + expressions.add(c.defaultElse()); + return expressions; + } +} diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/optimizer/OptimizerTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/optimizer/OptimizerTests.java index eb8ac2b4d15..f77088c3fdf 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/optimizer/OptimizerTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/optimizer/OptimizerTests.java @@ -44,9 +44,11 @@ import org.elasticsearch.xpack.sql.expression.function.scalar.string.Repeat; import org.elasticsearch.xpack.sql.expression.predicate.BinaryOperator; import org.elasticsearch.xpack.sql.expression.predicate.Range; import org.elasticsearch.xpack.sql.expression.predicate.conditional.ArbitraryConditionalFunction; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.Case; import org.elasticsearch.xpack.sql.expression.predicate.conditional.Coalesce; import org.elasticsearch.xpack.sql.expression.predicate.conditional.ConditionalFunction; import org.elasticsearch.xpack.sql.expression.predicate.conditional.Greatest; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.IfConditional; import org.elasticsearch.xpack.sql.expression.predicate.conditional.IfNull; import org.elasticsearch.xpack.sql.expression.predicate.conditional.Least; import org.elasticsearch.xpack.sql.expression.predicate.conditional.NullIf; @@ -112,9 +114,12 @@ import static org.elasticsearch.xpack.sql.expression.Literal.FALSE; import static org.elasticsearch.xpack.sql.expression.Literal.NULL; import static org.elasticsearch.xpack.sql.expression.Literal.TRUE; import static org.elasticsearch.xpack.sql.expression.Literal.of; +import static org.elasticsearch.xpack.sql.optimizer.Optimizer.SimplifyCase; +import static org.elasticsearch.xpack.sql.optimizer.Optimizer.SortAggregateOnOrderBy; import static org.elasticsearch.xpack.sql.tree.Source.EMPTY; import static org.elasticsearch.xpack.sql.util.DateUtils.UTC; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.startsWith; public class OptimizerTests extends ESTestCase { @@ -595,6 +600,91 @@ public class OptimizerTests extends ESTestCase { assertEquals(StringUtils.EMPTY, foldNull.rule(new Concat(EMPTY, NULL, NULL)).fold()); } + public void testSimplifyCaseConditionsFoldWhenFalse() { + // CASE WHEN a = 1 THEN 'foo1' + // WHEN 1 = 2 THEN 'bar1' + // WHEN 2 = 1 THEN 'bar2' + // WHEN a > 1 THEN 'foo2' + // ELSE 'default' + // END + // + // ==> + // + // CASE WHEN a = 1 THEN 'foo1' + // WHEN a > 1 THEN 'foo2' + // ELSE 'default' + // END + + Case c = new Case(EMPTY, Arrays.asList( + new IfConditional(EMPTY, new Equals(EMPTY, getFieldAttribute(), ONE), Literal.of(EMPTY, "foo1")), + new IfConditional(EMPTY, new Equals(EMPTY, ONE, TWO), Literal.of(EMPTY, "bar1")), + new IfConditional(EMPTY, new Equals(EMPTY, TWO, ONE), Literal.of(EMPTY, "bar2")), + new IfConditional(EMPTY, new GreaterThan(EMPTY, getFieldAttribute(), ONE), Literal.of(EMPTY, "foo2")), + Literal.of(EMPTY, "default"))); + Expression e = new SimplifyCase().rule(c); + assertEquals(Case.class, e.getClass()); + c = (Case) e; + assertEquals(2, c.conditions().size()); + assertThat(c.conditions().get(0).condition().toString(), startsWith("Equals[a{f}#")); + assertThat(c.conditions().get(1).condition().toString(), startsWith("GreaterThan[a{f}#")); + assertFalse(c.foldable()); + } + + public void testSimplifyCaseConditionsFoldWhenTrue() { + // CASE WHEN a = 1 THEN 'foo1' + // WHEN 1 = 1 THEN 'bar1' + // WHEN 2 = 1 THEN 'bar2' + // WHEN a > 1 THEN 'foo2' + // ELSE 'default' + // END + // + // ==> + // + // CASE WHEN a = 1 THEN 'foo1' + // WHEN 1 = 1 THEN 'bar1' + // ELSE 'default' + // END + + SimplifyCase rule = new SimplifyCase(); + Case c = new Case(EMPTY, Arrays.asList( + new IfConditional(EMPTY, new Equals(EMPTY, getFieldAttribute(), ONE), Literal.of(EMPTY, "foo1")), + new IfConditional(EMPTY, new Equals(EMPTY, ONE, ONE), Literal.of(EMPTY, "bar1")), + new IfConditional(EMPTY, new Equals(EMPTY, TWO, ONE), Literal.of(EMPTY, "bar2")), + new IfConditional(EMPTY, new GreaterThan(EMPTY, getFieldAttribute(), ONE), Literal.of(EMPTY, "foo2")), + Literal.of(EMPTY, "default"))); + Expression e = rule.rule(c); + assertEquals(Case.class, e.getClass()); + c = (Case) e; + assertEquals(2, c.conditions().size()); + assertThat(c.conditions().get(0).condition().toString(), startsWith("Equals[a{f}#")); + assertThat(c.conditions().get(1).condition().toString(), startsWith("Equals[=1,=1]#")); + assertFalse(c.foldable()); + } + + public void testSimplifyCaseConditionsFoldCompletely() { + // CASE WHEN 1 = 2 THEN 'foo1' + // WHEN 1 = 1 THEN 'foo2' + // ELSE 'default' + // END + // + // ==> + // + // 'foo2' + + SimplifyCase rule = new SimplifyCase(); + Case c = new Case(EMPTY, Arrays.asList( + new IfConditional(EMPTY, new Equals(EMPTY, ONE, TWO), Literal.of(EMPTY, "foo1")), + new IfConditional(EMPTY, new Equals(EMPTY, ONE, ONE), Literal.of(EMPTY, "foo2")), + Literal.of(EMPTY, "default"))); + Expression e = rule.rule(c); + assertEquals(Case.class, e.getClass()); + c = (Case) e; + assertEquals(1, c.conditions().size()); + assertThat(c.conditions().get(0).condition().toString(), startsWith("Equals[=1,=1]#")); + assertTrue(c.foldable()); + assertEquals("foo2", c.fold()); + } + // // Logical simplifications // @@ -1318,7 +1408,7 @@ public class OptimizerTests extends ESTestCase { OrderBy orderByPlan = new OrderBy(EMPTY, new Aggregate(EMPTY, FROM(), Arrays.asList(secondField, firstField), Arrays.asList(secondAlias, firstAlias)), Arrays.asList(firstOrderBy, secondOrderBy)); - LogicalPlan result = new Optimizer.SortAggregateOnOrderBy().apply(orderByPlan); + LogicalPlan result = new SortAggregateOnOrderBy().apply(orderByPlan); assertTrue(result instanceof OrderBy); List order = ((OrderBy) result).order(); @@ -1350,7 +1440,7 @@ public class OptimizerTests extends ESTestCase { OrderBy orderByPlan = new OrderBy(EMPTY, new Aggregate(EMPTY, FROM(), Arrays.asList(secondAlias, firstAlias), Arrays.asList(secondAlias, firstAlias)), Arrays.asList(firstOrderBy, secondOrderBy)); - LogicalPlan result = new Optimizer.SortAggregateOnOrderBy().apply(orderByPlan); + LogicalPlan result = new SortAggregateOnOrderBy().apply(orderByPlan); assertTrue(result instanceof OrderBy); List order = ((OrderBy) result).order(); diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/parser/ExpressionTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/parser/ExpressionTests.java index 98d7922d218..a8e5df8e07c 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/parser/ExpressionTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/parser/ExpressionTests.java @@ -11,6 +11,8 @@ import org.elasticsearch.xpack.sql.expression.Literal; import org.elasticsearch.xpack.sql.expression.function.UnresolvedFunction; import org.elasticsearch.xpack.sql.expression.function.scalar.Cast; import org.elasticsearch.xpack.sql.expression.literal.Interval; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.Case; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.IfConditional; import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Add; import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Mul; import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Neg; @@ -26,6 +28,7 @@ import java.time.temporal.TemporalAmount; import java.util.Locale; import static java.lang.String.format; +import static org.hamcrest.Matchers.startsWith; public class ExpressionTests extends ESTestCase { @@ -447,4 +450,63 @@ public class ExpressionTests extends ESTestCase { Expression expr = parser.createExpression(s); assertEquals(s, expr.sourceText()); } + + public void testCaseWithoutOperand() { + Expression expr = parser.createExpression( + "CASE WHEN a = 1 THEN 'one'" + + " WHEN a > 2 THEN 'a few'" + + " WHEN a > 10 THEN 'many' " + + "END"); + + assertEquals(Case.class, expr.getClass()); + Case c = (Case) expr; + assertEquals(3, c.conditions().size()); + IfConditional ifc = c.conditions().get(0); + assertEquals("WHEN a = 1 THEN 'one'", ifc.sourceText()); + assertThat(ifc.condition().toString(), startsWith("Equals[?a,1]#")); + assertEquals("'one'=one", ifc.result().toString()); + assertEquals(Literal.NULL, c.defaultElse()); + + expr = parser.createExpression( + "CASE WHEN a = 1 THEN 'one'" + + " WHEN a <= 2 THEN 'a few'" + + "ELSE 'many' " + + "END"); + + assertEquals(Case.class, expr.getClass()); + c = (Case) expr; + assertEquals(2, c.conditions().size()); + ifc = c.conditions().get(0); + assertEquals("WHEN a = 1 THEN 'one'", ifc.sourceText()); + assertEquals("'many'=many", c.defaultElse().toString()); + } + + public void testCaseWithOperand() { + Expression expr = parser.createExpression( + "CASE a WHEN 1 THEN 'one'" + + " WHEN 2 THEN 'two'" + + " WHEN 3 THEN 'three' " + + "END"); + + assertEquals(Case.class, expr.getClass()); + Case c = (Case) expr; + assertEquals(3, c.conditions().size()); + IfConditional ifc = c.conditions().get(0); + assertEquals("WHEN 1 THEN 'one'", ifc.sourceText()); + assertThat(ifc.condition().toString(), startsWith("Equals[?a,1]#")); + assertEquals("'one'=one", ifc.result().toString()); + assertEquals(Literal.NULL, c.defaultElse()); + + expr = parser.createExpression( + "CASE a WHEN 1 THEN 'one'" + + " WHEN 2 THEN 'two'" + + "ELSE 'many' " + + "END"); + assertEquals(Case.class, expr.getClass()); + c = (Case) expr; + assertEquals(2, c.conditions().size()); + ifc = c.conditions().get(0); + assertEquals("WHEN 1 THEN 'one'", ifc.sourceText()); + assertEquals("'many'=many", c.defaultElse().toString()); + } } diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/planner/QueryTranslatorTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/planner/QueryTranslatorTests.java index 85bc20596e9..ca3c3a92ce6 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/planner/QueryTranslatorTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/planner/QueryTranslatorTests.java @@ -587,6 +587,21 @@ public class QueryTranslatorTests extends ESTestCase { assertEquals("[{v=int}, {v=10}]", scriptTemplate.params().toString()); } + public void testTranslateCase_GroupBy_Painless() { + LogicalPlan p = plan("SELECT CASE WHEN int > 10 THEN 'foo' WHEN int > 20 THEN 'bar' ELSE 'default' END FROM test GROUP BY 1"); + assertTrue(p instanceof Aggregate); + Expression condition = ((Aggregate) p).groupings().get(0); + assertFalse(condition.foldable()); + QueryTranslator.GroupingContext groupingContext = QueryTranslator.groupBy(((Aggregate) p).groupings()); + assertNotNull(groupingContext); + ScriptTemplate scriptTemplate = groupingContext.tail.script(); + assertEquals("InternalSqlScriptUtils.caseFunction([InternalSqlScriptUtils.gt(InternalSqlScriptUtils.docValue(" + "" + + "doc,params.v0),params.v1),params.v2,InternalSqlScriptUtils.gt(InternalSqlScriptUtils.docValue(doc,params.v3)," + + "params.v4),params.v5,params.v6])", + scriptTemplate.toString()); + assertEquals("[{v=int}, {v=10}, {v=foo}, {v=int}, {v=20}, {v=bar}, {v=default}]", scriptTemplate.params().toString()); + } + public void testGroupByDateHistogram() { LogicalPlan p = plan("SELECT MAX(int) FROM test GROUP BY HISTOGRAM(int, 1000)"); assertTrue(p instanceof Aggregate); diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/tree/NodeSubclassTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/tree/NodeSubclassTests.java index f11519f0f97..cad06da0a82 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/tree/NodeSubclassTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/tree/NodeSubclassTests.java @@ -6,7 +6,6 @@ package org.elasticsearch.xpack.sql.tree; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; - import org.elasticsearch.common.Strings; import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.test.ESTestCase; @@ -29,6 +28,7 @@ import org.elasticsearch.xpack.sql.expression.gen.pipeline.BinaryPipesTests; import org.elasticsearch.xpack.sql.expression.gen.pipeline.Pipe; import org.elasticsearch.xpack.sql.expression.gen.processor.ConstantProcessor; import org.elasticsearch.xpack.sql.expression.gen.processor.Processor; +import org.elasticsearch.xpack.sql.expression.predicate.conditional.IfConditional; import org.elasticsearch.xpack.sql.expression.predicate.conditional.IfNull; import org.elasticsearch.xpack.sql.expression.predicate.fulltext.FullTextPredicate; import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.In; @@ -92,8 +92,8 @@ import static org.mockito.Mockito.mock; */ public class NodeSubclassTests> extends ESTestCase { - private static final List> CLASSES_WITH_MIN_TWO_CHILDREN = Arrays.asList(IfNull.class, In.class, InPipe.class, - Percentile.class, Percentiles.class, PercentileRanks.class); + private static final List> CLASSES_WITH_MIN_TWO_CHILDREN = Arrays.asList(IfConditional.class, IfNull.class, + In.class, InPipe.class, Percentile.class, Percentiles.class, PercentileRanks.class); private final Class subclass;