This is an automated email from the ASF dual-hosted git repository. jackietien pushed a commit to branch ty/TableModelGrammar in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 804915ee8f79683551b7d07c46764c5918afa267 Author: JackieTien97 <[email protected]> AuthorDate: Thu Feb 1 20:50:02 2024 +0800 init --- iotdb-core/pom.xml | 1 + iotdb-core/relational-grammar/pom.xml | 106 ++ .../db/relational/grammar/sql/RelationalSql.g4 | 1361 ++++++++++++++++++++ .../db/relational/grammar/type/TypeCalculation.g4 | 67 + .../grammar/sql/RelationalSqlKeywords.java | 43 + 5 files changed, 1578 insertions(+) diff --git a/iotdb-core/pom.xml b/iotdb-core/pom.xml index 11a501fc3c8..8151e23ce3c 100644 --- a/iotdb-core/pom.xml +++ b/iotdb-core/pom.xml @@ -37,5 +37,6 @@ <module>metrics</module> <module>node-commons</module> <module>tsfile</module> + <module>relational-grammar</module> </modules> </project> diff --git a/iotdb-core/relational-grammar/pom.xml b/iotdb-core/relational-grammar/pom.xml new file mode 100644 index 00000000000..b923cd0eb17 --- /dev/null +++ b/iotdb-core/relational-grammar/pom.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.iotdb</groupId> + <artifactId>iotdb-core</artifactId> + <version>1.3.1-SNAPSHOT</version> + </parent> + <artifactId>iotdb-relational-grammar</artifactId> + <name>IoTDB: Core: Relational-Antlr-Parser</name> + <description>Relational Antlr parser for IoTDB.</description> + <dependencies> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>org.antlr</groupId> + <artifactId>antlr4-runtime</artifactId> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.antlr</groupId> + <artifactId>antlr4-maven-plugin</artifactId> + <configuration> + <visitor>true</visitor> + </configuration> + <executions> + <execution> + <goals> + <goal>antlr4</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>build-helper-maven-plugin</artifactId> + <executions> + <execution> + <id>add-source</id> + <goals> + <goal>add-source</goal> + </goals> + <phase>generate-sources</phase> + <configuration> + <sources> + <source>${project.build.directory}/generated-sources/antlr4</source> + </sources> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-clean-plugin</artifactId> + <configuration> + <filesets> + <fileset> + <directory>${basedir}/gen</directory> + </fileset> + <fileset> + <directory>${basedir}/src</directory> + <includes> + <include>**/*.tokens</include> + </includes> + </fileset> + </filesets> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.rat</groupId> + <artifactId>apache-rat-plugin</artifactId> + <configuration> + <consoleOutput>true</consoleOutput> + <excludes combine.children="append"> + <exclude>**/SqlLexer.java</exclude> + <exclude>**/SqlLexer.interp</exclude> + </excludes> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 new file mode 100644 index 00000000000..771ccac2377 --- /dev/null +++ b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/sql/RelationalSql.g4 @@ -0,0 +1,1361 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +grammar RelationalSql; + +options { caseInsensitive = true; } + +tokens { + DELIMITER +} + +singleStatement + : statement EOF + ; + +standaloneExpression + : expression EOF + ; + +standalonePathSpecification + : pathSpecification EOF + ; + +standaloneType + : type EOF + ; + +standaloneRowPattern + : rowPattern EOF + ; + +standaloneFunctionSpecification + : functionSpecification EOF + ; + +statement + : rootQuery #statementDefault + | USE schema=identifier #use + | USE catalog=identifier '.' schema=identifier #use + | CREATE CATALOG (IF NOT EXISTS)? catalog=identifier + USING connectorName=identifier + (COMMENT string)? + (AUTHORIZATION principal)? + (WITH properties)? #createCatalog + | DROP CATALOG (IF EXISTS)? catalog=identifier + (CASCADE | RESTRICT)? #dropCatalog + | CREATE SCHEMA (IF NOT EXISTS)? qualifiedName + (AUTHORIZATION principal)? + (WITH properties)? #createSchema + | DROP SCHEMA (IF EXISTS)? qualifiedName (CASCADE | RESTRICT)? #dropSchema + | ALTER SCHEMA qualifiedName RENAME TO identifier #renameSchema + | ALTER SCHEMA qualifiedName SET AUTHORIZATION principal #setSchemaAuthorization + | CREATE (OR REPLACE)? TABLE (IF NOT EXISTS)? qualifiedName + columnAliases? + (COMMENT string)? + (WITH properties)? AS (rootQuery | '('rootQuery')') + (WITH (NO)? DATA)? #createTableAsSelect + | CREATE (OR REPLACE)? TABLE (IF NOT EXISTS)? qualifiedName + '(' tableElement (',' tableElement)* ')' + (COMMENT string)? + (WITH properties)? #createTable + | DROP TABLE (IF EXISTS)? qualifiedName #dropTable + | INSERT INTO qualifiedName columnAliases? rootQuery #insertInto + | DELETE FROM qualifiedName (WHERE booleanExpression)? #delete + | TRUNCATE TABLE qualifiedName #truncateTable + | COMMENT ON TABLE qualifiedName IS (string | NULL) #commentTable + | COMMENT ON VIEW qualifiedName IS (string | NULL) #commentView + | COMMENT ON COLUMN qualifiedName IS (string | NULL) #commentColumn + | ALTER TABLE (IF EXISTS)? from=qualifiedName + RENAME TO to=qualifiedName #renameTable + | ALTER TABLE (IF EXISTS)? tableName=qualifiedName + ADD COLUMN (IF NOT EXISTS)? column=columnDefinition #addColumn + | ALTER TABLE (IF EXISTS)? tableName=qualifiedName + RENAME COLUMN (IF EXISTS)? from=qualifiedName TO to=identifier #renameColumn + | ALTER TABLE (IF EXISTS)? tableName=qualifiedName + DROP COLUMN (IF EXISTS)? column=qualifiedName #dropColumn + | ALTER TABLE (IF EXISTS)? tableName=qualifiedName + ALTER COLUMN columnName=qualifiedName SET DATA TYPE type #setColumnType + | ALTER TABLE (IF EXISTS)? tableName=qualifiedName + ALTER COLUMN columnName=identifier DROP NOT NULL #dropNotNullConstraint + | ALTER TABLE tableName=qualifiedName SET AUTHORIZATION principal #setTableAuthorization + | ALTER TABLE tableName=qualifiedName + SET PROPERTIES propertyAssignments #setTableProperties + | ALTER TABLE tableName=qualifiedName + EXECUTE procedureName=identifier + ('(' (callArgument (',' callArgument)*)? ')')? + (WHERE where=booleanExpression)? #tableExecute + | ANALYZE qualifiedName (WITH properties)? #analyze + | CREATE (OR REPLACE)? MATERIALIZED VIEW + (IF NOT EXISTS)? qualifiedName + (GRACE PERIOD interval)? + (COMMENT string)? + (WITH properties)? AS rootQuery #createMaterializedView + | CREATE (OR REPLACE)? VIEW qualifiedName + (COMMENT string)? + (SECURITY (DEFINER | INVOKER))? AS rootQuery #createView + | REFRESH MATERIALIZED VIEW qualifiedName #refreshMaterializedView + | DROP MATERIALIZED VIEW (IF EXISTS)? qualifiedName #dropMaterializedView + | ALTER MATERIALIZED VIEW (IF EXISTS)? from=qualifiedName + RENAME TO to=qualifiedName #renameMaterializedView + | ALTER MATERIALIZED VIEW qualifiedName + SET PROPERTIES propertyAssignments #setMaterializedViewProperties + | DROP VIEW (IF EXISTS)? qualifiedName #dropView + | ALTER VIEW from=qualifiedName RENAME TO to=qualifiedName #renameView + | ALTER VIEW from=qualifiedName SET AUTHORIZATION principal #setViewAuthorization + | CALL qualifiedName '(' (callArgument (',' callArgument)*)? ')' #call + | CREATE (OR REPLACE)? functionSpecification #createFunction + | DROP FUNCTION (IF EXISTS)? functionDeclaration #dropFunction + | CREATE ROLE name=identifier + (WITH ADMIN grantor)? + (IN catalog=identifier)? #createRole + | DROP ROLE name=identifier (IN catalog=identifier)? #dropRole + | GRANT + roles + TO principal (',' principal)* + (WITH ADMIN OPTION)? + (GRANTED BY grantor)? + (IN catalog=identifier)? #grantRoles + | REVOKE + (ADMIN OPTION FOR)? + roles + FROM principal (',' principal)* + (GRANTED BY grantor)? + (IN catalog=identifier)? #revokeRoles + | SET ROLE (ALL | NONE | role=identifier) + (IN catalog=identifier)? #setRole + | GRANT + (privilege (',' privilege)* | ALL PRIVILEGES) + ON (SCHEMA | TABLE)? qualifiedName + TO grantee=principal + (WITH GRANT OPTION)? #grant + | DENY + (privilege (',' privilege)* | ALL PRIVILEGES) + ON (SCHEMA | TABLE)? qualifiedName + TO grantee=principal #deny + | REVOKE + (GRANT OPTION FOR)? + (privilege (',' privilege)* | ALL PRIVILEGES) + ON (SCHEMA | TABLE)? qualifiedName + FROM grantee=principal #revoke + | SHOW GRANTS (ON TABLE? qualifiedName)? #showGrants + | EXPLAIN ('(' explainOption (',' explainOption)* ')')? statement #explain + | EXPLAIN ANALYZE VERBOSE? statement #explainAnalyze + | SHOW CREATE TABLE qualifiedName #showCreateTable + | SHOW CREATE SCHEMA qualifiedName #showCreateSchema + | SHOW CREATE VIEW qualifiedName #showCreateView + | SHOW CREATE MATERIALIZED VIEW qualifiedName #showCreateMaterializedView + | SHOW TABLES ((FROM | IN) qualifiedName)? + (LIKE pattern=string (ESCAPE escape=string)?)? #showTables + | SHOW SCHEMAS ((FROM | IN) identifier)? + (LIKE pattern=string (ESCAPE escape=string)?)? #showSchemas + | SHOW CATALOGS + (LIKE pattern=string (ESCAPE escape=string)?)? #showCatalogs + | SHOW COLUMNS (FROM | IN) qualifiedName + (LIKE pattern=string (ESCAPE escape=string)?)? #showColumns + | SHOW STATS FOR qualifiedName #showStats + | SHOW STATS FOR '(' rootQuery ')' #showStatsForQuery + | SHOW CURRENT? ROLES ((FROM | IN) identifier)? #showRoles + | SHOW ROLE GRANTS ((FROM | IN) identifier)? #showRoleGrants + | DESCRIBE qualifiedName #showColumns + | DESC qualifiedName #showColumns + | SHOW FUNCTIONS ((FROM | IN) qualifiedName)? + (LIKE pattern=string (ESCAPE escape=string)?)? #showFunctions + | SHOW SESSION + (LIKE pattern=string (ESCAPE escape=string)?)? #showSession + | SET SESSION AUTHORIZATION authorizationUser #setSessionAuthorization + | RESET SESSION AUTHORIZATION #resetSessionAuthorization + | SET SESSION qualifiedName EQ expression #setSession + | RESET SESSION qualifiedName #resetSession + | START TRANSACTION (transactionMode (',' transactionMode)*)? #startTransaction + | COMMIT WORK? #commit + | ROLLBACK WORK? #rollback + | PREPARE identifier FROM statement #prepare + | DEALLOCATE PREPARE identifier #deallocate + | EXECUTE identifier (USING expression (',' expression)*)? #execute + | EXECUTE IMMEDIATE string (USING expression (',' expression)*)? #executeImmediate + | DESCRIBE INPUT identifier #describeInput + | DESCRIBE OUTPUT identifier #describeOutput + | SET PATH pathSpecification #setPath + | SET TIME ZONE (LOCAL | expression) #setTimeZone + | UPDATE qualifiedName + SET updateAssignment (',' updateAssignment)* + (WHERE where=booleanExpression)? #update + | MERGE INTO qualifiedName (AS? identifier)? + USING relation ON expression mergeCase+ #merge + ; + +rootQuery + : withFunction? query + ; + +withFunction + : WITH functionSpecification (',' functionSpecification)* + ; + +query + : with? queryNoWith + ; + +with + : WITH RECURSIVE? namedQuery (',' namedQuery)* + ; + +tableElement + : columnDefinition + | likeClause + ; + +columnDefinition + : qualifiedName type (NOT NULL)? (COMMENT string)? (WITH properties)? + ; + +likeClause + : LIKE qualifiedName (optionType=(INCLUDING | EXCLUDING) PROPERTIES)? + ; + +properties + : '(' propertyAssignments ')' + ; + +propertyAssignments + : property (',' property)* + ; + +property + : identifier EQ propertyValue + ; + +propertyValue + : DEFAULT #defaultPropertyValue + | expression #nonDefaultPropertyValue + ; + +queryNoWith + : queryTerm + (ORDER BY sortItem (',' sortItem)*)? + (OFFSET offset=rowCount (ROW | ROWS)?)? + ( (LIMIT limit=limitRowCount) + | (FETCH (FIRST | NEXT) (fetchFirst=rowCount)? (ROW | ROWS) (ONLY | WITH TIES)) + )? + ; + +limitRowCount + : ALL + | rowCount + ; + +rowCount + : INTEGER_VALUE + | QUESTION_MARK + ; + +queryTerm + : queryPrimary #queryTermDefault + | left=queryTerm operator=INTERSECT setQuantifier? right=queryTerm #setOperation + | left=queryTerm operator=(UNION | EXCEPT) setQuantifier? right=queryTerm #setOperation + ; + +queryPrimary + : querySpecification #queryPrimaryDefault + | TABLE qualifiedName #table + | VALUES expression (',' expression)* #inlineTable + | '(' queryNoWith ')' #subquery + ; + +sortItem + : expression ordering=(ASC | DESC)? (NULLS nullOrdering=(FIRST | LAST))? + ; + +querySpecification + : SELECT setQuantifier? selectItem (',' selectItem)* + (FROM relation (',' relation)*)? + (WHERE where=booleanExpression)? + (GROUP BY groupBy)? + (HAVING having=booleanExpression)? + (WINDOW windowDefinition (',' windowDefinition)*)? + ; + +groupBy + : setQuantifier? groupingElement (',' groupingElement)* + ; + +groupingElement + : groupingSet #singleGroupingSet + | ROLLUP '(' (groupingSet (',' groupingSet)*)? ')' #rollup + | CUBE '(' (groupingSet (',' groupingSet)*)? ')' #cube + | GROUPING SETS '(' groupingSet (',' groupingSet)* ')' #multipleGroupingSets + ; + +groupingSet + : '(' (expression (',' expression)*)? ')' + | expression + ; + +windowDefinition + : name=identifier AS '(' windowSpecification ')' + ; + +windowSpecification + : (existingWindowName=identifier)? + (PARTITION BY partition+=expression (',' partition+=expression)*)? + (ORDER BY sortItem (',' sortItem)*)? + windowFrame? + ; + +namedQuery + : name=identifier (columnAliases)? AS '(' query ')' + ; + +setQuantifier + : DISTINCT + | ALL + ; + +selectItem + : expression (AS? identifier)? #selectSingle + | primaryExpression '.' ASTERISK (AS columnAliases)? #selectAll + | ASTERISK #selectAll + ; + +relation + : left=relation + ( CROSS JOIN right=sampledRelation + | joinType JOIN rightRelation=relation joinCriteria + | NATURAL joinType JOIN right=sampledRelation + ) #joinRelation + | sampledRelation #relationDefault + ; + +joinType + : INNER? + | LEFT OUTER? + | RIGHT OUTER? + | FULL OUTER? + ; + +joinCriteria + : ON booleanExpression + | USING '(' identifier (',' identifier)* ')' + ; + +sampledRelation + : patternRecognition ( + TABLESAMPLE sampleType '(' percentage=expression ')' + )? + ; + +sampleType + : BERNOULLI + | SYSTEM + ; + +trimsSpecification + : LEADING + | TRAILING + | BOTH + ; + +listAggOverflowBehavior + : ERROR + | TRUNCATE string? listaggCountIndication + ; + +listaggCountIndication + : WITH COUNT + | WITHOUT COUNT + ; + +patternRecognition + : aliasedRelation ( + MATCH_RECOGNIZE '(' + (PARTITION BY partition+=expression (',' partition+=expression)*)? + (ORDER BY sortItem (',' sortItem)*)? + (MEASURES measureDefinition (',' measureDefinition)*)? + rowsPerMatch? + (AFTER MATCH skipTo)? + (INITIAL | SEEK)? + PATTERN '(' rowPattern ')' + (SUBSET subsetDefinition (',' subsetDefinition)*)? + DEFINE variableDefinition (',' variableDefinition)* + ')' + (AS? identifier columnAliases?)? + )? + ; + +measureDefinition + : expression AS identifier + ; + +rowsPerMatch + : ONE ROW PER MATCH + | ALL ROWS PER MATCH emptyMatchHandling? + ; + +emptyMatchHandling + : SHOW EMPTY MATCHES + | OMIT EMPTY MATCHES + | WITH UNMATCHED ROWS + ; + +skipTo + : 'SKIP' TO NEXT ROW + | 'SKIP' PAST LAST ROW + | 'SKIP' TO FIRST identifier + | 'SKIP' TO LAST identifier + | 'SKIP' TO identifier + ; + +subsetDefinition + : name=identifier EQ '(' union+=identifier (',' union+=identifier)* ')' + ; + +variableDefinition + : identifier AS expression + ; + +aliasedRelation + : relationPrimary (AS? identifier columnAliases?)? + ; + +columnAliases + : '(' identifier (',' identifier)* ')' + ; + +relationPrimary + : qualifiedName queryPeriod? #tableName + | '(' query ')' #subqueryRelation + | UNNEST '(' expression (',' expression)* ')' (WITH ORDINALITY)? #unnest + | LATERAL '(' query ')' #lateral + | TABLE '(' tableFunctionCall ')' #tableFunctionInvocation + | '(' relation ')' #parenthesizedRelation + ; + +tableFunctionCall + : qualifiedName '(' (tableFunctionArgument (',' tableFunctionArgument)*)? + (COPARTITION copartitionTables (',' copartitionTables)*)? ')' + ; + +tableFunctionArgument + : (identifier '=>')? (tableArgument | descriptorArgument | expression) // descriptor before expression to avoid parsing descriptor as a function call + ; + +tableArgument + : tableArgumentRelation + (PARTITION BY ('(' (expression (',' expression)*)? ')' | expression))? + (PRUNE WHEN EMPTY | KEEP WHEN EMPTY)? + (ORDER BY ('(' sortItem (',' sortItem)* ')' | sortItem))? + ; + +tableArgumentRelation + : TABLE '(' qualifiedName ')' (AS? identifier columnAliases?)? #tableArgumentTable + | TABLE '(' query ')' (AS? identifier columnAliases?)? #tableArgumentQuery + ; + +descriptorArgument + : DESCRIPTOR '(' descriptorField (',' descriptorField)* ')' + | CAST '(' NULL AS DESCRIPTOR ')' + ; + +descriptorField + : identifier type? + ; + +copartitionTables + : '(' qualifiedName ',' qualifiedName (',' qualifiedName)* ')' + ; + +expression + : booleanExpression + ; + +booleanExpression + : valueExpression predicate[$valueExpression.ctx]? #predicated + | NOT booleanExpression #logicalNot + | booleanExpression AND booleanExpression #and + | booleanExpression OR booleanExpression #or + ; + +// workaround for https://github.com/antlr/antlr4/issues/780 +predicate[ParserRuleContext value] + : comparisonOperator right=valueExpression #comparison + | comparisonOperator comparisonQuantifier '(' query ')' #quantifiedComparison + | NOT? BETWEEN lower=valueExpression AND upper=valueExpression #between + | NOT? IN '(' expression (',' expression)* ')' #inList + | NOT? IN '(' query ')' #inSubquery + | NOT? LIKE pattern=valueExpression (ESCAPE escape=valueExpression)? #like + | IS NOT? NULL #nullPredicate + | IS NOT? DISTINCT FROM right=valueExpression #distinctFrom + ; + +valueExpression + : primaryExpression #valueExpressionDefault + | valueExpression AT timeZoneSpecifier #atTimeZone + | operator=(MINUS | PLUS) valueExpression #arithmeticUnary + | left=valueExpression operator=(ASTERISK | SLASH | PERCENT) right=valueExpression #arithmeticBinary + | left=valueExpression operator=(PLUS | MINUS) right=valueExpression #arithmeticBinary + | left=valueExpression CONCAT right=valueExpression #concatenation + ; + +primaryExpression + : NULL #nullLiteral + | interval #intervalLiteral + | identifier string #typeConstructor + | DOUBLE PRECISION string #typeConstructor + | number #numericLiteral + | booleanValue #booleanLiteral + | string #stringLiteral + | BINARY_LITERAL #binaryLiteral + | QUESTION_MARK #parameter + | POSITION '(' valueExpression IN valueExpression ')' #position + | '(' expression (',' expression)+ ')' #rowConstructor + | ROW '(' expression (',' expression)* ')' #rowConstructor + | name=LISTAGG '(' setQuantifier? expression (',' string)? + (ON OVERFLOW listAggOverflowBehavior)? ')' + (WITHIN GROUP '(' ORDER BY sortItem (',' sortItem)* ')') + filter? #listagg + | processingMode? qualifiedName '(' (label=identifier '.')? ASTERISK ')' + filter? over? #functionCall + | processingMode? qualifiedName '(' (setQuantifier? expression (',' expression)*)? + (ORDER BY sortItem (',' sortItem)*)? ')' filter? (nullTreatment? over)? #functionCall + | identifier over #measure + | identifier '->' expression #lambda + | '(' (identifier (',' identifier)*)? ')' '->' expression #lambda + | '(' query ')' #subqueryExpression + // This is an extension to ANSI SQL, which considers EXISTS to be a <boolean expression> + | EXISTS '(' query ')' #exists + | CASE operand=expression whenClause+ (ELSE elseExpression=expression)? END #simpleCase + | CASE whenClause+ (ELSE elseExpression=expression)? END #searchedCase + | CAST '(' expression AS type ')' #cast + | TRY_CAST '(' expression AS type ')' #cast + | ARRAY '[' (expression (',' expression)*)? ']' #arrayConstructor + | value=primaryExpression '[' index=valueExpression ']' #subscript + | identifier #columnReference + | base=primaryExpression '.' fieldName=identifier #dereference + | name=CURRENT_DATE #specialDateTimeFunction + | name=CURRENT_TIME ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction + | name=CURRENT_TIMESTAMP ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction + | name=LOCALTIME ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction + | name=LOCALTIMESTAMP ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction + | name=CURRENT_USER #currentUser + | name=CURRENT_CATALOG #currentCatalog + | name=CURRENT_SCHEMA #currentSchema + | name=CURRENT_PATH #currentPath + | TRIM '(' (trimsSpecification? trimChar=valueExpression? FROM)? + trimSource=valueExpression ')' #trim + | TRIM '(' trimSource=valueExpression ',' trimChar=valueExpression ')' #trim + | SUBSTRING '(' valueExpression FROM valueExpression (FOR valueExpression)? ')' #substring + | NORMALIZE '(' valueExpression (',' normalForm)? ')' #normalize + | EXTRACT '(' identifier FROM valueExpression ')' #extract + | '(' expression ')' #parenthesizedExpression + | GROUPING '(' (qualifiedName (',' qualifiedName)*)? ')' #groupingOperation + | JSON_EXISTS '(' jsonPathInvocation (jsonExistsErrorBehavior ON ERROR)? ')' #jsonExists + | JSON_VALUE '(' + jsonPathInvocation + (RETURNING type)? + (emptyBehavior=jsonValueBehavior ON EMPTY)? + (errorBehavior=jsonValueBehavior ON ERROR)? + ')' #jsonValue + | JSON_QUERY '(' + jsonPathInvocation + (RETURNING type (FORMAT jsonRepresentation)?)? + (jsonQueryWrapperBehavior WRAPPER)? + ((KEEP | OMIT) QUOTES (ON SCALAR TEXT_STRING)?)? + (emptyBehavior=jsonQueryBehavior ON EMPTY)? + (errorBehavior=jsonQueryBehavior ON ERROR)? + ')' #jsonQuery + | JSON_OBJECT '(' + ( + jsonObjectMember (',' jsonObjectMember)* + (NULL ON NULL | ABSENT ON NULL)? + (WITH UNIQUE KEYS? | WITHOUT UNIQUE KEYS?)? + )? + (RETURNING type (FORMAT jsonRepresentation)?)? + ')' #jsonObject + | JSON_ARRAY '(' + ( + jsonValueExpression (',' jsonValueExpression)* + (NULL ON NULL | ABSENT ON NULL)? + )? + (RETURNING type (FORMAT jsonRepresentation)?)? + ')' #jsonArray + ; + +jsonPathInvocation + : jsonValueExpression ',' path=string + (AS pathName=identifier)? + (PASSING jsonArgument (',' jsonArgument)*)? + ; + +jsonValueExpression + : expression (FORMAT jsonRepresentation)? + ; + +jsonRepresentation + : JSON (ENCODING (UTF8 | UTF16 | UTF32))? // TODO add implementation-defined JSON representation option + ; + +jsonArgument + : jsonValueExpression AS identifier + ; + +jsonExistsErrorBehavior + : TRUE + | FALSE + | UNKNOWN + | ERROR + ; + +jsonValueBehavior + : ERROR + | NULL + | DEFAULT expression + ; + +jsonQueryWrapperBehavior + : WITHOUT ARRAY? + | WITH (CONDITIONAL | UNCONDITIONAL)? ARRAY? + ; + +jsonQueryBehavior + : ERROR + | NULL + | EMPTY ARRAY + | EMPTY OBJECT + ; + +jsonObjectMember + : KEY? expression VALUE jsonValueExpression + | expression ':' jsonValueExpression + ; + +processingMode + : RUNNING + | FINAL + ; + +nullTreatment + : IGNORE NULLS + | RESPECT NULLS + ; + +string + : STRING #basicStringLiteral + | UNICODE_STRING (UESCAPE STRING)? #unicodeStringLiteral + ; + +timeZoneSpecifier + : TIME ZONE interval #timeZoneInterval + | TIME ZONE string #timeZoneString + ; + +comparisonOperator + : EQ | NEQ | LT | LTE | GT | GTE + ; + +comparisonQuantifier + : ALL | SOME | ANY + ; + +booleanValue + : TRUE | FALSE + ; + +interval + : INTERVAL sign=(PLUS | MINUS)? string from=intervalField (TO to=intervalField)? + ; + +intervalField + : YEAR | MONTH | DAY | HOUR | MINUTE | SECOND + ; + +normalForm + : NFD | NFC | NFKD | NFKC + ; + +type + : ROW '(' rowField (',' rowField)* ')' #rowType + | INTERVAL from=intervalField (TO to=intervalField)? #intervalType + | base=TIMESTAMP ('(' precision = typeParameter ')')? (WITHOUT TIME ZONE)? #dateTimeType + | base=TIMESTAMP ('(' precision = typeParameter ')')? WITH TIME ZONE #dateTimeType + | base=TIME ('(' precision = typeParameter ')')? (WITHOUT TIME ZONE)? #dateTimeType + | base=TIME ('(' precision = typeParameter ')')? WITH TIME ZONE #dateTimeType + | DOUBLE PRECISION #doublePrecisionType + | ARRAY '<' type '>' #legacyArrayType + | MAP '<' keyType=type ',' valueType=type '>' #legacyMapType + | type ARRAY ('[' INTEGER_VALUE ']')? #arrayType + | identifier ('(' typeParameter (',' typeParameter)* ')')? #genericType + ; + +rowField + : type + | identifier type; + +typeParameter + : INTEGER_VALUE | type + ; + +whenClause + : WHEN condition=expression THEN result=expression + ; + +filter + : FILTER '(' WHERE booleanExpression ')' + ; + +mergeCase + : WHEN MATCHED (AND condition=expression)? THEN + UPDATE SET targets+=identifier EQ values+=expression + (',' targets+=identifier EQ values+=expression)* #mergeUpdate + | WHEN MATCHED (AND condition=expression)? THEN DELETE #mergeDelete + | WHEN NOT MATCHED (AND condition=expression)? THEN + INSERT ('(' targets+=identifier (',' targets+=identifier)* ')')? + VALUES '(' values+=expression (',' values+=expression)* ')' #mergeInsert + ; + +over + : OVER (windowName=identifier | '(' windowSpecification ')') + ; + +windowFrame + : (MEASURES measureDefinition (',' measureDefinition)*)? + frameExtent + (AFTER MATCH skipTo)? + (INITIAL | SEEK)? + (PATTERN '(' rowPattern ')')? + (SUBSET subsetDefinition (',' subsetDefinition)*)? + (DEFINE variableDefinition (',' variableDefinition)*)? + ; + +frameExtent + : frameType=RANGE start=frameBound + | frameType=ROWS start=frameBound + | frameType=GROUPS start=frameBound + | frameType=RANGE BETWEEN start=frameBound AND end=frameBound + | frameType=ROWS BETWEEN start=frameBound AND end=frameBound + | frameType=GROUPS BETWEEN start=frameBound AND end=frameBound + ; + +frameBound + : UNBOUNDED boundType=PRECEDING #unboundedFrame + | UNBOUNDED boundType=FOLLOWING #unboundedFrame + | CURRENT ROW #currentRowBound + | expression boundType=(PRECEDING | FOLLOWING) #boundedFrame + ; + +rowPattern + : patternPrimary patternQuantifier? #quantifiedPrimary + | rowPattern rowPattern #patternConcatenation + | rowPattern '|' rowPattern #patternAlternation + ; + +patternPrimary + : identifier #patternVariable + | '(' ')' #emptyPattern + | PERMUTE '(' rowPattern (',' rowPattern)* ')' #patternPermutation + | '(' rowPattern ')' #groupedPattern + | '^' #partitionStartAnchor + | '$' #partitionEndAnchor + | '{-' rowPattern '-}' #excludedPattern + ; + +patternQuantifier + : ASTERISK (reluctant=QUESTION_MARK)? #zeroOrMoreQuantifier + | PLUS (reluctant=QUESTION_MARK)? #oneOrMoreQuantifier + | QUESTION_MARK (reluctant=QUESTION_MARK)? #zeroOrOneQuantifier + | '{' exactly=INTEGER_VALUE '}' (reluctant=QUESTION_MARK)? #rangeQuantifier + | '{' (atLeast=INTEGER_VALUE)? ',' (atMost=INTEGER_VALUE)? '}' (reluctant=QUESTION_MARK)? #rangeQuantifier + ; + +updateAssignment + : identifier EQ expression + ; + +explainOption + : FORMAT value=(TEXT | GRAPHVIZ | JSON) #explainFormat + | TYPE value=(LOGICAL | DISTRIBUTED | VALIDATE | IO) #explainType + ; + +transactionMode + : ISOLATION LEVEL levelOfIsolation #isolationLevel + | READ accessMode=(ONLY | WRITE) #transactionAccessMode + ; + +levelOfIsolation + : READ UNCOMMITTED #readUncommitted + | READ COMMITTED #readCommitted + | REPEATABLE READ #repeatableRead + | SERIALIZABLE #serializable + ; + +callArgument + : expression #positionalArgument + | identifier '=>' expression #namedArgument + ; + +pathElement + : identifier '.' identifier #qualifiedArgument + | identifier #unqualifiedArgument + ; + +pathSpecification + : pathElement (',' pathElement)* + ; + +functionSpecification + : FUNCTION functionDeclaration returnsClause routineCharacteristic* controlStatement + ; + +functionDeclaration + : qualifiedName '(' (parameterDeclaration (',' parameterDeclaration)*)? ')' + ; + +parameterDeclaration + : identifier? type + ; + +returnsClause + : RETURNS type + ; + +routineCharacteristic + : LANGUAGE identifier #languageCharacteristic + | NOT? DETERMINISTIC #deterministicCharacteristic + | RETURNS NULL ON NULL INPUT #returnsNullOnNullInputCharacteristic + | CALLED ON NULL INPUT #calledOnNullInputCharacteristic + | SECURITY (DEFINER | INVOKER) #securityCharacteristic + | COMMENT string #commentCharacteristic + ; + +controlStatement + : RETURN valueExpression #returnStatement + | SET identifier EQ expression #assignmentStatement + | CASE expression caseStatementWhenClause+ elseClause? END CASE #simpleCaseStatement + | CASE caseStatementWhenClause+ elseClause? END CASE #searchedCaseStatement + | IF expression THEN sqlStatementList elseIfClause* elseClause? END IF #ifStatement + | ITERATE identifier #iterateStatement + | LEAVE identifier #leaveStatement + | BEGIN (variableDeclaration SEMICOLON)* sqlStatementList? END #compoundStatement + | (label=identifier ':')? LOOP sqlStatementList END LOOP #loopStatement + | (label=identifier ':')? WHILE expression DO sqlStatementList END WHILE #whileStatement + | (label=identifier ':')? REPEAT sqlStatementList UNTIL expression END REPEAT #repeatStatement + ; + +caseStatementWhenClause + : WHEN expression THEN sqlStatementList + ; + +elseIfClause + : ELSEIF expression THEN sqlStatementList + ; + +elseClause + : ELSE sqlStatementList + ; + +variableDeclaration + : DECLARE identifier (',' identifier)* type (DEFAULT valueExpression)? + ; + +sqlStatementList + : (controlStatement SEMICOLON)+ + ; + +privilege + : CREATE | SELECT | DELETE | INSERT | UPDATE + ; + +qualifiedName + : identifier ('.' identifier)* + ; + +queryPeriod + : FOR rangeType AS OF end=valueExpression + ; + +rangeType + : TIMESTAMP + | VERSION + ; + +grantor + : principal #specifiedPrincipal + | CURRENT_USER #currentUserGrantor + | CURRENT_ROLE #currentRoleGrantor + ; + +principal + : identifier #unspecifiedPrincipal + | USER identifier #userPrincipal + | ROLE identifier #rolePrincipal + ; + +roles + : identifier (',' identifier)* + ; + +identifier + : IDENTIFIER #unquotedIdentifier + | QUOTED_IDENTIFIER #quotedIdentifier + | nonReserved #unquotedIdentifier + | BACKQUOTED_IDENTIFIER #backQuotedIdentifier + | DIGIT_IDENTIFIER #digitIdentifier + ; + +number + : MINUS? DECIMAL_VALUE #decimalLiteral + | MINUS? DOUBLE_VALUE #doubleLiteral + | MINUS? INTEGER_VALUE #integerLiteral + ; + +authorizationUser + : identifier #identifierUser + | string #stringUser + ; + +nonReserved + // IMPORTANT: this rule must only contain tokens. Nested rules are not supported. See SqlParser.exitNonReserved + : ABSENT | ADD | ADMIN | AFTER | ALL | ANALYZE | ANY | ARRAY | ASC | AT | AUTHORIZATION + | BEGIN | BERNOULLI | BOTH + | CALL | CALLED | CASCADE | CATALOG | CATALOGS | COLUMN | COLUMNS | COMMENT | COMMIT | COMMITTED | CONDITIONAL | COPARTITION | COUNT | CURRENT + | DATA | DATE | DAY | DECLARE | DEFAULT | DEFINE | DEFINER | DENY | DESC | DESCRIPTOR | DETERMINISTIC | DISTRIBUTED | DO | DOUBLE + | ELSEIF | EMPTY | ENCODING | ERROR | EXCLUDING | EXPLAIN + | FETCH | FILTER | FINAL | FIRST | FOLLOWING | FORMAT | FUNCTION | FUNCTIONS + | GRACE | GRANT | GRANTED | GRANTS | GRAPHVIZ | GROUPS + | HOUR + | IF | IGNORE | IMMEDIATE | INCLUDING | INITIAL | INPUT | INTERVAL | INVOKER | IO | ITERATE | ISOLATION + | JSON + | KEEP | KEY | KEYS + | LANGUAGE | LAST | LATERAL | LEADING | LEAVE | LEVEL | LIMIT | LOCAL | LOGICAL | LOOP + | MAP | MATCH | MATCHED | MATCHES | MATCH_RECOGNIZE | MATERIALIZED | MEASURES | MERGE | MINUTE | MONTH + | NESTED | NEXT | NFC | NFD | NFKC | NFKD | NO | NONE | NULLIF | NULLS + | OBJECT | OF | OFFSET | OMIT | ONE | ONLY | OPTION | ORDINALITY | OUTPUT | OVER | OVERFLOW + | PARTITION | PARTITIONS | PASSING | PAST | PATH | PATTERN | PER | PERIOD | PERMUTE | PLAN | POSITION | PRECEDING | PRECISION | PRIVILEGES | PROPERTIES | PRUNE + | QUOTES + | RANGE | READ | REFRESH | RENAME | REPEAT | REPEATABLE | REPLACE | RESET | RESPECT | RESTRICT | RETURN | RETURNING | RETURNS | REVOKE | ROLE | ROLES | ROLLBACK | ROW | ROWS | RUNNING + | SCALAR | SCHEMA | SCHEMAS | SECOND | SECURITY | SEEK | SERIALIZABLE | SESSION | SET | SETS + | SHOW | SOME | START | STATS | SUBSET | SUBSTRING | SYSTEM + | TABLES | TABLESAMPLE | TEXT | TEXT_STRING | TIES | TIME | TIMESTAMP | TO | TRAILING | TRANSACTION | TRUNCATE | TRY_CAST | TYPE + | UNBOUNDED | UNCOMMITTED | UNCONDITIONAL | UNIQUE | UNKNOWN | UNMATCHED | UNTIL | UPDATE | USE | USER | UTF16 | UTF32 | UTF8 + | VALIDATE | VALUE | VERBOSE | VERSION | VIEW + | WHILE | WINDOW | WITHIN | WITHOUT | WORK | WRAPPER | WRITE + | YEAR + | ZONE + ; + +ABSENT: 'ABSENT'; +ADD: 'ADD'; +ADMIN: 'ADMIN'; +AFTER: 'AFTER'; +ALL: 'ALL'; +ALTER: 'ALTER'; +ANALYZE: 'ANALYZE'; +AND: 'AND'; +ANY: 'ANY'; +ARRAY: 'ARRAY'; +AS: 'AS'; +ASC: 'ASC'; +AT: 'AT'; +AUTHORIZATION: 'AUTHORIZATION'; +BEGIN: 'BEGIN'; +BERNOULLI: 'BERNOULLI'; +BETWEEN: 'BETWEEN'; +BOTH: 'BOTH'; +BY: 'BY'; +CALL: 'CALL'; +CALLED: 'CALLED'; +CASCADE: 'CASCADE'; +CASE: 'CASE'; +CAST: 'CAST'; +CATALOG: 'CATALOG'; +CATALOGS: 'CATALOGS'; +COLUMN: 'COLUMN'; +COLUMNS: 'COLUMNS'; +COMMENT: 'COMMENT'; +COMMIT: 'COMMIT'; +COMMITTED: 'COMMITTED'; +CONDITIONAL: 'CONDITIONAL'; +CONSTRAINT: 'CONSTRAINT'; +COUNT: 'COUNT'; +COPARTITION: 'COPARTITION'; +CREATE: 'CREATE'; +CROSS: 'CROSS'; +CUBE: 'CUBE'; +CURRENT: 'CURRENT'; +CURRENT_CATALOG: 'CURRENT_CATALOG'; +CURRENT_DATE: 'CURRENT_DATE'; +CURRENT_PATH: 'CURRENT_PATH'; +CURRENT_ROLE: 'CURRENT_ROLE'; +CURRENT_SCHEMA: 'CURRENT_SCHEMA'; +CURRENT_TIME: 'CURRENT_TIME'; +CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'; +CURRENT_USER: 'CURRENT_USER'; +DATA: 'DATA'; +DATE: 'DATE'; +DAY: 'DAY'; +DEALLOCATE: 'DEALLOCATE'; +DECLARE: 'DECLARE'; +DEFAULT: 'DEFAULT'; +DEFINE: 'DEFINE'; +DEFINER: 'DEFINER'; +DELETE: 'DELETE'; +DENY: 'DENY'; +DESC: 'DESC'; +DESCRIBE: 'DESCRIBE'; +DESCRIPTOR: 'DESCRIPTOR'; +DETERMINISTIC: 'DETERMINISTIC'; +DISTINCT: 'DISTINCT'; +DISTRIBUTED: 'DISTRIBUTED'; +DO: 'DO'; +DOUBLE: 'DOUBLE'; +DROP: 'DROP'; +ELSE: 'ELSE'; +EMPTY: 'EMPTY'; +ELSEIF: 'ELSEIF'; +ENCODING: 'ENCODING'; +END: 'END'; +ERROR: 'ERROR'; +ESCAPE: 'ESCAPE'; +EXCEPT: 'EXCEPT'; +EXCLUDING: 'EXCLUDING'; +EXECUTE: 'EXECUTE'; +EXISTS: 'EXISTS'; +EXPLAIN: 'EXPLAIN'; +EXTRACT: 'EXTRACT'; +FALSE: 'FALSE'; +FETCH: 'FETCH'; +FILTER: 'FILTER'; +FINAL: 'FINAL'; +FIRST: 'FIRST'; +FOLLOWING: 'FOLLOWING'; +FOR: 'FOR'; +FORMAT: 'FORMAT'; +FROM: 'FROM'; +FULL: 'FULL'; +FUNCTION: 'FUNCTION'; +FUNCTIONS: 'FUNCTIONS'; +GRACE: 'GRACE'; +GRANT: 'GRANT'; +GRANTED: 'GRANTED'; +GRANTS: 'GRANTS'; +GRAPHVIZ: 'GRAPHVIZ'; +GROUP: 'GROUP'; +GROUPING: 'GROUPING'; +GROUPS: 'GROUPS'; +HAVING: 'HAVING'; +HOUR: 'HOUR'; +IF: 'IF'; +IGNORE: 'IGNORE'; +IMMEDIATE: 'IMMEDIATE'; +IN: 'IN'; +INCLUDING: 'INCLUDING'; +INITIAL: 'INITIAL'; +INNER: 'INNER'; +INPUT: 'INPUT'; +INSERT: 'INSERT'; +INTERSECT: 'INTERSECT'; +INTERVAL: 'INTERVAL'; +INTO: 'INTO'; +INVOKER: 'INVOKER'; +IO: 'IO'; +IS: 'IS'; +ISOLATION: 'ISOLATION'; +ITERATE: 'ITERATE'; +JOIN: 'JOIN'; +JSON: 'JSON'; +JSON_ARRAY: 'JSON_ARRAY'; +JSON_EXISTS: 'JSON_EXISTS'; +JSON_OBJECT: 'JSON_OBJECT'; +JSON_QUERY: 'JSON_QUERY'; +JSON_TABLE: 'JSON_TABLE'; +JSON_VALUE: 'JSON_VALUE'; +KEEP: 'KEEP'; +KEY: 'KEY'; +KEYS: 'KEYS'; +LANGUAGE: 'LANGUAGE'; +LAST: 'LAST'; +LATERAL: 'LATERAL'; +LEADING: 'LEADING'; +LEAVE: 'LEAVE'; +LEFT: 'LEFT'; +LEVEL: 'LEVEL'; +LIKE: 'LIKE'; +LIMIT: 'LIMIT'; +LISTAGG: 'LISTAGG'; +LOCAL: 'LOCAL'; +LOCALTIME: 'LOCALTIME'; +LOCALTIMESTAMP: 'LOCALTIMESTAMP'; +LOGICAL: 'LOGICAL'; +LOOP: 'LOOP'; +MAP: 'MAP'; +MATCH: 'MATCH'; +MATCHED: 'MATCHED'; +MATCHES: 'MATCHES'; +MATCH_RECOGNIZE: 'MATCH_RECOGNIZE'; +MATERIALIZED: 'MATERIALIZED'; +MEASURES: 'MEASURES'; +MERGE: 'MERGE'; +MINUTE: 'MINUTE'; +MONTH: 'MONTH'; +NATURAL: 'NATURAL'; +NESTED: 'NESTED'; +NEXT: 'NEXT'; +NFC : 'NFC'; +NFD : 'NFD'; +NFKC : 'NFKC'; +NFKD : 'NFKD'; +NO: 'NO'; +NONE: 'NONE'; +NORMALIZE: 'NORMALIZE'; +NOT: 'NOT'; +NULL: 'NULL'; +NULLIF: 'NULLIF'; +NULLS: 'NULLS'; +OBJECT: 'OBJECT'; +OF: 'OF'; +OFFSET: 'OFFSET'; +OMIT: 'OMIT'; +ON: 'ON'; +ONE: 'ONE'; +ONLY: 'ONLY'; +OPTION: 'OPTION'; +OR: 'OR'; +ORDER: 'ORDER'; +ORDINALITY: 'ORDINALITY'; +OUTER: 'OUTER'; +OUTPUT: 'OUTPUT'; +OVER: 'OVER'; +OVERFLOW: 'OVERFLOW'; +PARTITION: 'PARTITION'; +PARTITIONS: 'PARTITIONS'; +PASSING: 'PASSING'; +PAST: 'PAST'; +PATH: 'PATH'; +PATTERN: 'PATTERN'; +PER: 'PER'; +PERIOD: 'PERIOD'; +PERMUTE: 'PERMUTE'; +PLAN : 'PLAN'; +POSITION: 'POSITION'; +PRECEDING: 'PRECEDING'; +PRECISION: 'PRECISION'; +PREPARE: 'PREPARE'; +PRIVILEGES: 'PRIVILEGES'; +PROPERTIES: 'PROPERTIES'; +PRUNE: 'PRUNE'; +QUOTES: 'QUOTES'; +RANGE: 'RANGE'; +READ: 'READ'; +RECURSIVE: 'RECURSIVE'; +REFRESH: 'REFRESH'; +RENAME: 'RENAME'; +REPEAT: 'REPEAT'; +REPEATABLE: 'REPEATABLE'; +REPLACE: 'REPLACE'; +RESET: 'RESET'; +RESPECT: 'RESPECT'; +RESTRICT: 'RESTRICT'; +RETURN: 'RETURN'; +RETURNING: 'RETURNING'; +RETURNS: 'RETURNS'; +REVOKE: 'REVOKE'; +RIGHT: 'RIGHT'; +ROLE: 'ROLE'; +ROLES: 'ROLES'; +ROLLBACK: 'ROLLBACK'; +ROLLUP: 'ROLLUP'; +ROW: 'ROW'; +ROWS: 'ROWS'; +RUNNING: 'RUNNING'; +SCALAR: 'SCALAR'; +SCHEMA: 'SCHEMA'; +SCHEMAS: 'SCHEMAS'; +SECOND: 'SECOND'; +SECURITY: 'SECURITY'; +SEEK: 'SEEK'; +SELECT: 'SELECT'; +SERIALIZABLE: 'SERIALIZABLE'; +SESSION: 'SESSION'; +SET: 'SET'; +SETS: 'SETS'; +SHOW: 'SHOW'; +SOME: 'SOME'; +START: 'START'; +STATS: 'STATS'; +SUBSET: 'SUBSET'; +SUBSTRING: 'SUBSTRING'; +SYSTEM: 'SYSTEM'; +TABLE: 'TABLE'; +TABLES: 'TABLES'; +TABLESAMPLE: 'TABLESAMPLE'; +TEXT: 'TEXT'; +TEXT_STRING: 'STRING'; +THEN: 'THEN'; +TIES: 'TIES'; +TIME: 'TIME'; +TIMESTAMP: 'TIMESTAMP'; +TO: 'TO'; +TRAILING: 'TRAILING'; +TRANSACTION: 'TRANSACTION'; +TRIM: 'TRIM'; +TRUE: 'TRUE'; +TRUNCATE: 'TRUNCATE'; +TRY_CAST: 'TRY_CAST'; +TYPE: 'TYPE'; +UESCAPE: 'UESCAPE'; +UNBOUNDED: 'UNBOUNDED'; +UNCOMMITTED: 'UNCOMMITTED'; +UNCONDITIONAL: 'UNCONDITIONAL'; +UNION: 'UNION'; +UNIQUE: 'UNIQUE'; +UNKNOWN: 'UNKNOWN'; +UNMATCHED: 'UNMATCHED'; +UNNEST: 'UNNEST'; +UNTIL: 'UNTIL'; +UPDATE: 'UPDATE'; +USE: 'USE'; +USER: 'USER'; +USING: 'USING'; +UTF16: 'UTF16'; +UTF32: 'UTF32'; +UTF8: 'UTF8'; +VALIDATE: 'VALIDATE'; +VALUE: 'VALUE'; +VALUES: 'VALUES'; +VERBOSE: 'VERBOSE'; +VERSION: 'VERSION'; +VIEW: 'VIEW'; +WHEN: 'WHEN'; +WHERE: 'WHERE'; +WHILE: 'WHILE'; +WINDOW: 'WINDOW'; +WITH: 'WITH'; +WITHIN: 'WITHIN'; +WITHOUT: 'WITHOUT'; +WORK: 'WORK'; +WRAPPER: 'WRAPPER'; +WRITE: 'WRITE'; +YEAR: 'YEAR'; +ZONE: 'ZONE'; + +EQ: '='; +NEQ: '<>' | '!='; +LT: '<'; +LTE: '<='; +GT: '>'; +GTE: '>='; + +PLUS: '+'; +MINUS: '-'; +ASTERISK: '*'; +SLASH: '/'; +PERCENT: '%'; +CONCAT: '||'; +QUESTION_MARK: '?'; +SEMICOLON: ';'; + +STRING + : '\'' ( ~'\'' | '\'\'' )* '\'' + ; + +UNICODE_STRING + : 'U&\'' ( ~'\'' | '\'\'' )* '\'' + ; + +// Note: we allow any character inside the binary literal and validate +// its a correct literal when the AST is being constructed. This +// allows us to provide more meaningful error messages to the user +BINARY_LITERAL + : 'X\'' (~'\'')* '\'' + ; + +INTEGER_VALUE + : DECIMAL_INTEGER + | HEXADECIMAL_INTEGER + | OCTAL_INTEGER + | BINARY_INTEGER + ; + +DECIMAL_VALUE + : DECIMAL_INTEGER '.' DECIMAL_INTEGER? + | '.' DECIMAL_INTEGER + ; + +DOUBLE_VALUE + : DIGIT+ ('.' DIGIT*)? EXPONENT + | '.' DIGIT+ EXPONENT + ; + +IDENTIFIER + : (LETTER | '_') (LETTER | DIGIT | '_')* + ; + +DIGIT_IDENTIFIER + : DIGIT (LETTER | DIGIT | '_')+ + ; + +QUOTED_IDENTIFIER + : '"' ( ~'"' | '""' )* '"' + ; + +BACKQUOTED_IDENTIFIER + : '`' ( ~'`' | '``' )* '`' + ; + +fragment DECIMAL_INTEGER + : DIGIT ('_'? DIGIT)* + ; + +fragment HEXADECIMAL_INTEGER + : '0X' ('_'? (DIGIT | [A-F]))+ + ; + +fragment OCTAL_INTEGER + : '0O' ('_'? [0-7])+ + ; + +fragment BINARY_INTEGER + : '0B' ('_'? [01])+ + ; + +fragment EXPONENT + : 'E' [+-]? DIGIT+ + ; + +fragment DIGIT + : [0-9] + ; + +fragment LETTER + : [A-Z] + ; + +SIMPLE_COMMENT + : '--' ~[\r\n]* '\r'? '\n'? -> channel(HIDDEN) + ; + +BRACKETED_COMMENT + : '/*' .*? '*/' -> channel(HIDDEN) + ; + +WS + : [ \r\n\t]+ -> channel(HIDDEN) + ; + +// Catch-all for anything we can't recognize. +// We use this to be able to ignore and recover all the text +// when splitting statements with DelimiterLexer +UNRECOGNIZED + : . + ; diff --git a/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/type/TypeCalculation.g4 b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/type/TypeCalculation.g4 new file mode 100644 index 00000000000..652bf75fa64 --- /dev/null +++ b/iotdb-core/relational-grammar/src/main/antlr4/org/apache/iotdb/db/relational/grammar/type/TypeCalculation.g4 @@ -0,0 +1,67 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//TODO: consider using the SQL grammar for this +grammar TypeCalculation; + +options { caseInsensitive = true; } + +// workaround for: +// https://github.com/antlr/antlr4/issues/118 +typeCalculation + : expression EOF + ; + +expression + : NULL #nullLiteral + | INTEGER_VALUE #numericLiteral + | binaryFunctionName '(' left=expression ',' right=expression ')' #binaryFunction + | IDENTIFIER #identifier + | '(' expression ')' #parenthesizedExpression + | operator=(MINUS | PLUS) expression #arithmeticUnary + | left=expression operator=(ASTERISK | SLASH) right=expression #arithmeticBinary + | left=expression operator=(PLUS | MINUS) right=expression #arithmeticBinary + ; + +binaryFunctionName + : name=(MAX | MIN) + ; + +PLUS: '+'; +MINUS: '-'; +ASTERISK: '*'; +SLASH: '/'; +NULL: 'NULL'; +MIN: 'MIN'; +MAX: 'MAX'; + +IDENTIFIER + : (LETTER | '_') (LETTER | DIGIT | '_' )* + ; + +INTEGER_VALUE + : DIGIT+ + ; + +fragment DIGIT + : ('0'..'9') + ; + +fragment LETTER + : [A-Z] + ; + +WS + : [ \r\n\t]+ -> channel(HIDDEN) + ; diff --git a/iotdb-core/relational-grammar/src/main/java/org/apache/iotdb/db/relational/grammar/sql/RelationalSqlKeywords.java b/iotdb-core/relational-grammar/src/main/java/org/apache/iotdb/db/relational/grammar/sql/RelationalSqlKeywords.java new file mode 100644 index 00000000000..8bb374f788a --- /dev/null +++ b/iotdb-core/relational-grammar/src/main/java/org/apache/iotdb/db/relational/grammar/sql/RelationalSqlKeywords.java @@ -0,0 +1,43 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.iotdb.db.relational.grammar.sql; + +import com.google.common.collect.ImmutableSet; +import org.antlr.v4.runtime.Vocabulary; + +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static com.google.common.base.Strings.nullToEmpty; + +public final class RelationalSqlKeywords { + private static final Pattern IDENTIFIER = Pattern.compile("'([A-Z_]+)'"); + + private RelationalSqlKeywords() {} + + public static Set<String> sqlKeywords() { + ImmutableSet.Builder<String> names = ImmutableSet.builder(); + Vocabulary vocabulary = RelationalSqlLexer.VOCABULARY; + for (int i = 0; i <= vocabulary.getMaxTokenType(); i++) { + String name = nullToEmpty(vocabulary.getLiteralName(i)); + Matcher matcher = IDENTIFIER.matcher(name); + if (matcher.matches()) { + names.add(matcher.group(1)); + } + } + return names.build(); + } +}
