[
  {
    "path": ".gitignore",
    "content": "# Created by .ignore support plugin (hsz.mobi)\ntarget\n.idea\nsuperior-sql-parser.iml\nmetastore_db\nderby.log\n.DS_Store\ngen\n*.tokens\n*.iml"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2022 Ververica Inc.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README.md",
    "content": "## 介绍\n\n基于 antlr4 的多种数据库SQL解析器，获取SQL中元数据，可用于数据平台产品中的多个场景：ddl语句提取元数据、sql 权限校验、表级血缘、sql语法校验等场景。支持spark、flink、gauss、starrocks、Oracle、MYSQL、Postgresql，sqlserver,、db2等\n```xml\n<dependency>\n    <groupId>io.github.melin.superior</groupId>\n    <artifactId>superior-[spark|presto|mysql|oracle|...]-parser</artifactId>\n    <version>4.0.22</version>\n</dependency>\n```\n\n## Build\n```\nexport GPG_TTY=$(tty)\nmvn clean deploy -Pdeploy\n```\n\n### API\n\n每个数据库SQL 提供 Helper 类，Helper 方法提供四个方法：\n```agsl\n1. parseStatement(String sql) // 解析单个完整sql\n    a. ddl: 获取ddl 详细信息。例如：数据库执行完ddl以后，解析ddl，获取到相关信息，同步到元数据信息。\n    b. dml: 获取sql中使用到的表，用于构建表级血缘，或者校验表权限。\n2. parseMultiStatement(String sql) // 解析多个完整sql，支持空格、换行、分号分隔\n3. splitSql(String sql) // sql 文本包含多个完整sql，方法用于分隔sql语句，支持空格、换行、分号分隔\n4. checkSqlSyntax(String sql) // 验证单个完整sql语法是否正确\n5. sqlKeywords() // 获取sql 关键字，主要用于sql editor 关键字提示\n```\n\n## Example\n\n```kotlin\n// Spark SQL\nval sql = \"select bzdys, bzhyyh, bzdy, week, round((bzdy-bzdys)*100/bzdys, 2) \" +\n        \"from (select lag(bzdy) over (order by week) bzdys, bzhyyh, bzdy, week \" +\n        \"from (select count(distinct partner_code) bzhyyh, count(1) bzdy, week from tdl_dt2x_table)) limit 111\"\n\nval statement = SparkSQLHelper.parseStatement(sql)\nif (statement is QueryStmt) {\n    Assert.assertEquals(StatementType.SELECT, statement.statementType)\n    Assert.assertEquals(1, statement.inputTables.size)\n    Assert.assertEquals(\"tdl_dt2x_table\", statement.inputTables.get(0).tableName)\n    Assert.assertEquals(111, statement.limit)\n} else {\n    Assert.fail()\n}\n\n// Spark Jar\nval sql = \"\"\"\n    set spark.shuffle.compress=true;set spark.rdd.compress=true;\n    set spark.driver.maxResultSize=3g;\n    set spark.serializer=org.apache.spark.serializer.KryoSerializer;\n    set spark.kryoserializer.buffer.max=1024m;\n    set spark.kryoserializer.buffer=256m;\n    set spark.network.timeout=300s;\n    examples-jar-with-dependencies.jar imei_test.euSaveHBase gaea_offline:account_mobile sh md shda.interest_radar_mobile_score_dt 20180318 /xiaoyong.fu/sh/mobile/loan 400 '%7B%22job_type%22=' --jar\n    \"\"\";\n\nval statementDatas = JobTaskHelper.parseStatement(sql)\nAssert.assertEquals(8, statementDatas.size)\nvar statementData = statementDatas.get(7)\nvar statement = statementData.statement\nif (statement is JobData) {\n    Assert.assertEquals(StatementType.JOB, statement.statementType)\n    Assert.assertEquals(\"createHfile-1.2-SNAPSHOT-jar-with-dependencies.jar\", statement.resourceName)\n    Assert.assertEquals(\"imei_test.euSaveHBase\", statement.className)\n    Assert.assertEquals(\"/xiaoyong.fu/sh/mobile/loan\", statement.params?.get(5))\n    Assert.assertEquals(\"400\", statement.params?.get(6))\n    Assert.assertEquals(\"%7B%22job_type%22=\", statement.params?.get(7))\n    Assert.assertEquals(\"--jar\", statement.params?.get(8))\n} else {\n    Assert.fail()\n}\n\n// MySQL\nval sql = \"insert into bigdata.user select * from users a left outer join address b on a.address_id = b.id\"\nval statement = MySQLHelper.parseStatement(sql)\nif(statement is QueryStmt) {\n    Assert.assertEquals(StatementType.INSERT_SELECT, statement.statementType)\n    Assert.assertEquals(\"bigdata\", statement.outpuTables.get(0).databaseName)\n    Assert.assertEquals(\"user\", statement.outpuTables.get(0).tableName)\n    Assert.assertEquals(2, statement.inputTables.size)\n} else {\n    Assert.fail()\n}\n\n// Postgres\nval sql = \"\"\"\n    select a.* from datacompute1.datacompute.dc_job a left join datacompute1.datacompute.dc_job_scheduler b on a.id=b.job_id\n\"\"\".trimIndent()\n\nval statement = PostgreSQLHelper.parseStatement(sql)\nif (statement is QueryStmt) {\n    Assert.assertEquals(StatementType.SELECT, statement.statementType)\n    Assert.assertEquals(2, statement.inputTables.size)\n} else {\n    Assert.fail()\n}\n```\n\n## 支持数据库\n1. [MySQL](https://github.com/antlr/grammars-v4/tree/master/sql/mysql)\n2. [PrestoSQL](https://github.com/prestosql/presto/tree/master/presto-parser/src/main/antlr4/io/prestosql/sql/parser)\n3. [PostgreSQL](https://github.com/pgcodekeeper/pgcodekeeper/tree/master/apgdiff/antlr-src)\n4. [Spark 3.x](https://github.com/apache/spark/tree/master/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser)\n5. [Sql Server](https://github.com/antlr/grammars-v4/tree/master/sql/tsql) \n6. [StarRocks](https://github.com/StarRocks/starrocks/tree/main/fe/fe-core/src/main/java/com/starrocks/sql/parser)\n7. [Oracle](https://github.com/antlr/grammars-v4/tree/master/sql/plsql)\n8. [OceanBase](https://github.com/oceanbase/odc/tree/main/libs/ob-sql-parser)\n9. [Flink SQL / Flink CDC SQL](https://github.com/DTStack/dt-sql-parser/tree/main/src/grammar/flinksql)\n\n## 相关项目\n1. https://gitee.com/melin/bee\n2. https://github.com/melin/sqlflow/ 字段血缘解析\n3. https://github.com/melin/superior-sql-formatter spark sql 代码格式化\n4. https://github.com/melin/datatunnel spark 数据同步工具\n5. https://github.com/melin/flink-jobserver \n6. https://github.com/melin/spark-jobserver\n\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <groupId>io.github.melin.superior</groupId>\n    <artifactId>superior-sql-parser</artifactId>\n    <version>4.0.23</version>\n    <packaging>pom</packaging>\n    <name>Superior SQL Parser</name>\n\n    <description>Superior SQL Parser</description>\n\n    <modules>\n        <module>superior-common-parser</module>\n        <module>superior-arithmetic-parser</module>\n        <module>superior-appjar-parser</module>\n\n        <module>superior-spark-parser</module>\n        <module>superior-mysql-parser</module>\n        <module>superior-postgres-parser</module>\n        <module>superior-trino-parser</module>\n        <module>superior-presto-parser</module>\n        <module>superior-sqlserver-parser</module>\n        <module>superior-flink-parser</module>\n        <module>superior-oracle-parser</module>\n        <module>superior-dameng-parser</module>\n        <module>superior-starrocks-parser</module>\n        <module>superior-redshift-parser</module>\n    </modules>\n\n    <properties>\n        <maven.compiler.source>8</maven.compiler.source>\n        <maven.compiler.target>8</maven.compiler.target>\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <kotlin.compiler.incremental>true</kotlin.compiler.incremental>\n\n        <kotlin.version>2.3.20</kotlin.version>\n        <antlr4.version>4.9.3</antlr4.version>\n        <slf4j.version>2.0.17</slf4j.version>\n        <log4j.version>2.25.3</log4j.version>\n        <commons-lang3.version>3.20.0</commons-lang3.version>\n        <commons-io.version>2.21.0</commons-io.version>\n    </properties>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.antlr</groupId>\n            <artifactId>antlr4-runtime</artifactId>\n            <version>${antlr4.version}</version>\n            <exclusions>\n                <exclusion>\n                    <groupId>org.jetbrains.kotlin</groupId>\n                    <artifactId>*</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n\n        <dependency>\n            <groupId>org.jetbrains.kotlin</groupId>\n            <artifactId>kotlin-stdlib</artifactId>\n            <version>${kotlin.version}</version>\n        </dependency>\n\n        <dependency>\n            <groupId>org.apache.commons</groupId>\n            <artifactId>commons-lang3</artifactId>\n            <version>${commons-lang3.version}</version>\n        </dependency>\n\n        <dependency>\n            <groupId>com.google.guava</groupId>\n            <artifactId>guava</artifactId>\n            <version>33.4.0-jre</version>\n            <scope>provided</scope>\n        </dependency>\n\n        <dependency>\n            <groupId>junit</groupId>\n            <artifactId>junit</artifactId>\n            <version>4.13.2</version>\n            <scope>test</scope>\n        </dependency>\n\n        <dependency>\n            <groupId>commons-io</groupId>\n            <artifactId>commons-io</artifactId>\n            <version>${commons-io.version}</version>\n            <scope>test</scope>\n        </dependency>\n\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n            <version>${slf4j.version}</version>\n        </dependency>\n\n        <dependency>\n            <groupId>org.apache.logging.log4j</groupId>\n            <artifactId>log4j-core</artifactId>\n            <version>${log4j.version}</version>\n            <scope>test</scope>\n        </dependency>\n\n        <dependency>\n            <groupId>org.apache.logging.log4j</groupId>\n            <artifactId>log4j-slf4j-impl</artifactId>\n            <version>${log4j.version}</version>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-javadoc-plugin</artifactId>\n                <version>3.12.0</version>\n                <inherited>true</inherited>\n                <configuration>\n                    <maxmemory>1024</maxmemory>\n                    <encoding>UTF-8</encoding>\n                    <show>protected</show>\n                    <notree>true</notree>\n\n                    <!-- Avoid running into Java 8's very restrictive doclint issues -->\n                    <failOnError>false</failOnError>\n                    <doclint>none</doclint>\n                </configuration>\n                <executions>\n                    <execution>\n                        <id>bundle-sources</id>\n                        <goals>\n                            <goal>jar</goal>\n                        </goals>\n                        <phase>package</phase>\n                    </execution>\n                </executions>\n            </plugin>\n\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <version>3.5.4</version>\n            </plugin>\n\n            <plugin>\n                <groupId>org.jetbrains.kotlin</groupId>\n                <artifactId>kotlin-maven-plugin</artifactId>\n                <version>${kotlin.version}</version>\n                <extensions>true</extensions>\n                <executions>\n                    <execution>\n                        <id>compile</id>\n                        <goals>\n                            <goal>compile</goal>\n                        </goals>\n                        <phase>process-sources</phase>\n                        <configuration>\n                            <sourceDirs>\n                                <sourceDir>${project.basedir}/src/main/kotlin</sourceDir>\n                                <sourceDir>${project.basedir}/src/main/java</sourceDir>\n                                <sourceDir>${project.build.directory}/generated-sources/antlr4</sourceDir>\n                            </sourceDirs>\n                        </configuration>\n                    </execution>\n                    <execution>\n                        <id>test-compile</id>\n                        <goals>\n                            <goal>test-compile</goal>\n                        </goals>\n                        <configuration>\n                            <sourceDirs>\n                                <sourceDir>${project.basedir}/src/test/kotlin</sourceDir>\n                                <sourceDir>${project.basedir}/src/test/java</sourceDir>\n                            </sourceDirs>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <configuration>\n                    <source>1.8</source>\n                    <target>1.8</target>\n                    <encoding>UTF-8</encoding>\n                </configuration>\n                <executions>\n                    <!-- Replacing default-compile as it is treated specially by maven -->\n                    <execution>\n                        <id>default-compile</id>\n                        <phase>none</phase>\n                    </execution>\n                    <!-- Replacing default-testCompile as it is treated specially by maven -->\n                    <execution>\n                        <id>default-testCompile</id>\n                        <phase>none</phase>\n                    </execution>\n                    <execution>\n                        <id>java-compile</id>\n                        <goals>\n                            <goal>compile</goal>\n                        </goals>\n                        <phase>compile</phase>\n                    </execution>\n                    <execution>\n                        <id>java-test-compile</id>\n                        <goals>\n                            <goal>testCompile</goal>\n                        </goals>\n                        <phase>test-compile</phase>\n                    </execution>\n                </executions>\n            </plugin>\n\n            <plugin>\n                <groupId>org.antlr</groupId>\n                <artifactId>antlr4-maven-plugin</artifactId>\n                <version>${antlr4.version}</version>\n                <configuration>\n                    <!--<listener>true</listener>-->\n                    <visitor>true</visitor>\n                    <!--<treatWarningsAsErrors>true</treatWarningsAsErrors>-->\n                </configuration>\n                <executions>\n                    <execution>\n                        <id>antlr</id>\n                        <goals>\n                            <goal>antlr4</goal>\n                        </goals>\n                        <phase>generate-sources</phase>\n                    </execution>\n                </executions>\n            </plugin>\n\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-release-plugin</artifactId>\n                <configuration>\n                    <mavenExecutorId>forked-path</mavenExecutorId>\n                    <useReleaseProfile>false</useReleaseProfile>\n                    <arguments>-Psonatype-oss-release</arguments>\n                </configuration>\n            </plugin>\n\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-source-plugin</artifactId>\n                <version>3.4.0</version>\n                <inherited>true</inherited>\n                <configuration>\n                    <excludeResources>true</excludeResources>\n                    <useDefaultExcludes>true</useDefaultExcludes>\n                </configuration>\n                <executions>\n                    <execution>\n                        <id>attach-sources</id>\n                        <goals>\n                            <goal>jar</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n\n        </plugins>\n    </build>\n\n    <profiles>\n        <profile>\n            <id>deploy</id>\n            <build>\n                <plugins>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-gpg-plugin</artifactId>\n                        <executions>\n                            <execution>\n                                <id>sign-artifacts</id>\n                                <goals>\n                                    <goal>sign</goal>\n                                </goals>\n                                <phase>verify</phase>\n                            </execution>\n                        </executions>\n                    </plugin>\n\n                    <plugin>\n                        <groupId>org.sonatype.central</groupId>\n                        <artifactId>central-publishing-maven-plugin</artifactId>\n                        <version>0.10.0</version>\n                        <extensions>true</extensions>\n                        <configuration>\n                            <deploymentName>superior-sql-parser-${project.version}</deploymentName>\n                            <publishingServerId>central</publishingServerId>\n                            <autoPublish>true</autoPublish>\n                        </configuration>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n\n    <url>https://github.com/melin/superior-sql-parser</url>\n\n    <licenses>\n        <license>\n            <name>The Apache Software License, Version 2.0</name>\n            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>\n            <distribution>repo</distribution>\n        </license>\n    </licenses>\n\n    <developers>\n        <developer>\n            <name>melin</name>\n            <email>libinsong1204@gmail.com</email>\n            <url>https://github.com/melin/superior-sql-parser</url>\n        </developer>\n    </developers>\n\n    <scm>\n        <connection>scm:git:https://github.com/melin/superior-sql-parser.git</connection>\n        <developerConnection>scm:git:https://github.com/melin/superior-sql-parser.git</developerConnection>\n        <url>https://github.com/melin/superior-sql-parser</url>\n    </scm>\n\n    <issueManagement>\n        <system>gitee</system>\n        <url>https://github.com/melin/superior-sql-parser/issues</url>\n    </issueManagement>\n\n</project>\n"
  },
  {
    "path": "superior-appjar-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-appjar-parser</artifactId>\n    <name>superior-appjar-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "superior-appjar-parser/src/main/antlr4/io/github/melin/superior/parser/job/antlr4/AppJarLexer.g4",
    "content": "lexer grammar AppJarLexer;\n\nchannels { DCSTREAMCOMMENT, ERRORCHANNEL }\n\n// SKIP\n\nSPACE:                               [ \\t\\r\\n]+    -> channel(HIDDEN);\nSPEC_MYSQL_COMMENT:                  '/*!' .+? '*/' -> channel(DCSTREAMCOMMENT);\nCOMMENT_INPUT:                       '/*' .*? '*/' -> channel(HIDDEN);\nLINE_COMMENT:                        (\n                                       ('-- ' | '#') ~[\\r\\n]* ('\\r'? '\\n' | EOF)\n                                       | '--' ('\\r'? '\\n' | EOF)\n                                     ) -> channel(HIDDEN);\n\nSET:                                 'SET';\nRESET:                               'RESET';\n\nSTAR:                                '*';\nDIVIDE:                              '/';\nMODULE:                              '%';\nPLUS:                                '+';\nMINUS:                               '-';\n\n// Operators. Comparation\nEQUAL_SYMBOL:                        '=';\nGREATER_SYMBOL:                      '>';\nLESS_SYMBOL:                         '<';\nEXCLAMATION_SYMBOL:                  '!';\n\n\n// Operators. Bit\nBIT_NOT_OP:                          '~';\nBIT_OR_OP:                           '|';\nBIT_AND_OP:                          '&';\nBIT_XOR_OP:                          '^';\n\n// Constructors symbols\nDOT:                                 '.';\nLR_BRACKET:                          '(';\nRR_BRACKET:                          ')';\nCOMMA:                               ',';\nSEMI:                                ';';\n\nDOT_ID:                              '.' ID_LITERAL;\n\nID:                                  ID_LITERAL;\nREVERSE_QUOTE_ID:                    '`' ~'`'+ '`';\nSTRING_LITERAL:                      DQUOTA_STRING | SQUOTA_STRING;\n\nfragment ID_LITERAL:                 [A-Z_$0-9,:-]*;\nfragment DQUOTA_STRING:              '\"' ( '\\\\'. | '\"\"' | ~('\"'| '\\\\') )* '\"';\nfragment SQUOTA_STRING:              '\\'' ('\\\\'. | '\\'\\'' | ~('\\'' | '\\\\'))* '\\'';\n\nERROR_RECONGNIGION:                  .    -> channel(ERRORCHANNEL);"
  },
  {
    "path": "superior-appjar-parser/src/main/antlr4/io/github/melin/superior/parser/job/antlr4/AppJarParser.g4",
    "content": "parser grammar AppJarParser;\n\noptions { tokenVocab=AppJarLexer; }\n\nrootx\n    : jobTasks? EOF\n    ;\n\njobTasks\n    : (jobTask SEMI | emptyStatement)*\n    (jobTask (SEMI)? | emptyStatement)\n    ;\n\njobTask\n    :  setStatement | resetStatement | jobStatement\n    ;\n\njobStatement\n    : resourceNameExpr classNameExpr paramsExpr?\n    ;\n\nresourceNameExpr\n    : ID (DOT_ID)*\n    | fileDir\n    ;\n\nclassNameExpr\n    : ID (DOT_ID)*\n    ;\n\nparamsExpr\n    : paramExpr (paramExpr)*\n    ;\n\nparamExpr\n    : ID (DOT_ID)*\n    | fileDir\n    | ID DOT_ID* ('/' '/'? ID DOT_ID*)*\n    | STRING_LITERAL\n    ;\n\nfileDir\n    : '/' ID DOT_ID* ('/' (ID DOT_ID* | '*'))* '/'?\n    ;\n\nsetStatement\n    : SET keyExpr EQUAL_SYMBOL value=valueExpr\n    ;\n\nresetStatement\n    : RESET keyExpr\n    ;\n\nkeyExpr\n    : ID (DOT_ID)*\n    ;\n\nvalueExpr\n    : word (word)*\n    ;\n\nword\n    : ID\n    | DOT_ID | SET | RESET\n    | STAR | DIVIDE | MODULE | PLUS | MINUS\n    | EQUAL_SYMBOL | GREATER_SYMBOL | LESS_SYMBOL | EXCLAMATION_SYMBOL\n    | BIT_NOT_OP | BIT_OR_OP | BIT_AND_OP | BIT_XOR_OP\n    | LR_BRACKET | RR_BRACKET | COMMA\n    | STRING_LITERAL\n    ;\n\nemptyStatement\n    : SEMI\n    ;\n"
  },
  {
    "path": "superior-appjar-parser/src/main/kotlin/io/github/melin/superior/parser/appjar/AbstractJarParser.kt",
    "content": "package io.github.melin.superior.parser.appjar\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.job.antlr4.AppJarParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractJarParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(AppJarParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: AppJarParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(AppJarParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-appjar-parser/src/main/kotlin/io/github/melin/superior/parser/appjar/AppJarAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.appjar\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.common.ReSetStatement\nimport io.github.melin.superior.common.relational.common.SetStatement\nimport io.github.melin.superior.parser.job.antlr4.AppJarParser\nimport io.github.melin.superior.parser.job.antlr4.AppJarParserBaseVisitor\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by binsong.li on 2018/3/31 下午1:44 */\nclass AppJarAntlr4Visitor : AppJarParserBaseVisitor<Statement>() {\n\n    private var command: String? = null\n\n    private val jobStmts = ArrayList<Statement>()\n\n    override fun visitJobTask(ctx: AppJarParser.JobTaskContext): Statement {\n        val jobStmt = super.visitJobTask(ctx)\n        val sql = source(ctx)\n        jobStmt.setSql(sql)\n\n        jobStmts.add(jobStmt)\n        return jobStmt\n    }\n\n    override fun visitJobStatement(ctx: AppJarParser.JobStatementContext): Statement {\n        val resourceName = ctx.resourceNameExpr().text\n        val className = ctx.classNameExpr().text\n\n        val params: ArrayList<String> = arrayListOf()\n\n        if (ctx.paramsExpr() != null) {\n            ctx.paramsExpr().children.forEach { item ->\n                val param = item as AppJarParser.ParamExprContext\n                var value = source(param)\n                if (StringUtils.startsWith(value, \"/\")) { // 解决连续多个文件路径，不能正确解析\n                    value = replaceWhitespace(value)\n\n                    params.addAll(StringUtils.split(value, \" \"))\n                } else {\n                    value = CommonUtils.cleanQuote(value)\n                    params.add(value)\n                }\n            }\n        }\n\n        return AppJarInfo(resourceName, className, params)\n    }\n\n    override fun visitSetStatement(ctx: AppJarParser.SetStatementContext): Statement {\n        val key = ctx.keyExpr().text\n        val value = CommonUtils.cleanQuote(source(ctx.value))\n\n        return SetStatement(key, value)\n    }\n\n    override fun visitResetStatement(ctx: AppJarParser.ResetStatementContext): Statement {\n        val key = ctx.keyExpr().text\n        return ReSetStatement(key)\n    }\n\n    private fun replaceWhitespace(str: String): String {\n        val len = str.length\n        if (len > 0) {\n            val dest = CharArray(len)\n            var destPos = 0\n            for (i in 0 until len) {\n                val c = str[i]\n                if (!Character.isWhitespace(c)) {\n                    dest[destPos++] = c\n                } else {\n                    dest[destPos++] = ' '\n                }\n            }\n            return String(dest, 0, destPos)\n        }\n        return str\n    }\n\n    fun getJobStmts(): ArrayList<Statement> {\n        return jobStmts\n    }\n\n    fun setCommand(command: String) {\n        this.command = command\n    }\n}\n"
  },
  {
    "path": "superior-appjar-parser/src/main/kotlin/io/github/melin/superior/parser/appjar/AppJarHelper.kt",
    "content": "package io.github.melin.superior.parser.appjar\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.job.antlr4.AppJarLexer\nimport io.github.melin.superior.parser.job.antlr4.AppJarParser\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by binsong.li on 2018/3/31 下午1:47 */\nobject AppJarHelper {\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until AppJarLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = AppJarLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): ArrayList<Statement> {\n        val trimCmd = StringUtils.trim(command)\n\n        val charStream = UpperCaseCharStream(CharStreams.fromString(trimCmd))\n        val lexer = AppJarLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = AppJarParser(tokenStream)\n        AbstractJarParser.installCaches(parser)\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n        parser.interpreter.predictionMode = PredictionMode.SLL\n\n        val cmdVisitor = AppJarAntlr4Visitor()\n        cmdVisitor.setCommand(trimCmd)\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                cmdVisitor.visit(parser.jobTasks())\n                return cmdVisitor.getJobStmts()\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                cmdVisitor.visit(parser.jobTasks())\n                return cmdVisitor.getJobStmts()\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(trimCmd)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractJarParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-appjar-parser/src/main/kotlin/io/github/melin/superior/parser/appjar/AppJarInfo.kt",
    "content": "package io.github.melin.superior.parser.appjar\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class AppJarInfo(val resourceName: String, val className: String, val params: List<String>?) : Statement() {\n    override val statementType = StatementType.APP_JAR\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-appjar-parser/src/test/kotlin/io/github/melin/superior/parser/appjar/AppJarParserTest.kt",
    "content": "package io.github.melin.superior.parser.appjar\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.common.ReSetStatement\nimport io.github.melin.superior.common.relational.common.SetStatement\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by binsong.li on 2018/3/31 下午1:59 */\nclass AppJarParserTest {\n\n    @Test\n    fun setConfigTest1() {\n        val sql =\n            \"\"\"\n            set flink.test = 'hello world';\n            set flink.test = setsd,sd,resr;\n            set flink.test = hello world;\n            set flink.test = hello-world;\n            set flink.test = hello $\\{usename} test;\n            #set flink.test = hello comment;\n            set flink.test = hello 'test' world;\n            set flink.test = hello \"test\" world;\n            set flink.test = hdfs://user/hive;\n            set flink.test = 12,12;\n            set flink.test = 3.45;\n            set flink.test = ibdex.json;\n            reset flink.test;\n            set flink.test = dw.eset_sdfe_sd;\n            set flink.test = demo.test;\n            set flink.test = dsd(id)%=2;\n            tet_test-demo_1.23-sdfd.jar com.example.Demo1 param1  param2 'hello \\n world'\n             'hdfs://user/hive'\n             '{\"user\": \"binsong.li\",\n               address: \"hangzhou\"\n             }'\n             /user/jars/*\n             --jars /user/jars/flink.jar\n            \"\"\"\n\n        val statements = AppJarHelper.parseStatement(sql)\n        Assert.assertEquals(16, statements.size)\n\n        var statement = statements.get(0)\n        if (statement is SetStatement) {\n            Assert.assertEquals(StatementType.SET, statement.statementType)\n            Assert.assertEquals(\"flink.test\", statement.key)\n            Assert.assertEquals(\"hello world\", statement.value)\n        } else {\n            Assert.fail()\n        }\n\n        var setCount = 0\n        statements.filter { it.statementType == StatementType.SET }.forEach { setCount = setCount + 1 }\n\n        Assert.assertEquals(14, setCount)\n\n        statement = statements.get(11)\n        if (statement is ReSetStatement) {\n            Assert.assertEquals(StatementType.RESET, statement.statementType)\n            Assert.assertEquals(\"flink.test\", statement.key)\n        } else {\n            Assert.fail()\n        }\n\n        statement = statements.get(15)\n        if (statement is AppJarInfo) {\n            Assert.assertEquals(StatementType.APP_JAR, statement.statementType)\n            Assert.assertEquals(\"tet_test-demo_1.23-sdfd.jar\", statement.resourceName)\n            Assert.assertEquals(\"com.example.Demo1\", statement.className)\n            Assert.assertEquals(8, statement.params?.size)\n            Assert.assertEquals(\"/user/jars/*\", statement.params?.get(5))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setConfigTest2() {\n        val sql = \"demo.jar com.example.Demo 'hello \\\"test\\\" world' param2 \\n param3\"\n\n        val statementDatas = AppJarHelper.parseStatement(sql)\n        Assert.assertEquals(1, statementDatas.size)\n\n        val statement = statementDatas.get(0)\n        if (statement is AppJarInfo) {\n            Assert.assertEquals(StatementType.APP_JAR, statement.statementType)\n            Assert.assertEquals(\"demo.jar\", statement.resourceName)\n            Assert.assertEquals(\"com.example.Demo\", statement.className)\n            Assert.assertEquals(3, statement.params?.size)\n\n            Assert.assertEquals(\"hello \\\"test\\\" world\", statement.params?.get(0))\n            Assert.assertEquals(\"param3\", statement.params?.get(2))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setConfigTest3() {\n        val sql =\n            \"\"\"\n            set spark.yarn.queue=newoffline;\n            set spark.sql.autoBroadcastJoinThreshold=40485760;\n            set spark.executor.memory=8g;\n            set spark.sql.hive.convertMetastoreParquet=true ;\n            set spark.driver.maxResultSize=4g;\n            set spark.driver.memory=10g;\n            set spark.psi.ds=20180312;\n            set spark.psi.dstTable=dw.index_psi_dt;\n            set spark.psi.dims=idnumber;\n            set spark.psi.num=0;\n            set spark.psi.parNum=2;\n            set spark.indexPSI.type=2;\n            set spark.metrics.indexFile=index-mobile.json;\n            psi_new_calculate_metrics-1.1-SNAPSHOT-jar-with-dependencies.jar  com.example.dw.psi.StartDCJob 1,3,sd,qw\n            \"\"\"\n\n        val statementDatas = AppJarHelper.parseStatement(sql)\n        Assert.assertEquals(14, statementDatas.size)\n\n        val statement = statementDatas.get(13)\n        if (statement is AppJarInfo) {\n            Assert.assertEquals(StatementType.APP_JAR, statement.statementType)\n            Assert.assertEquals(\n                \"psi_new_calculate_metrics-1.1-SNAPSHOT-jar-with-dependencies.jar\",\n                statement.resourceName\n            )\n            Assert.assertEquals(\"com.example.dw.psi.StartDCJob\", statement.className)\n            Assert.assertEquals(\"1,3,sd,qw\", statement.params?.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setConfigTest4() {\n        val sql =\n            \"\"\"\n            set spark.yarn.queue=newoffline;\nset spark.dynamicAllocation.maxExecutors=100;\nset spark.driver.maxResultSize=30g;\nset spark.driver.memory=15g;\nset spark.executor.instances=80;\nset spark.executor.cores=5;\nset spark.executor.memory=30g;\nset spark.sql.shuffle.partitions=5000;\nset spark.shuffle.io.maxRetries=60;\nset spark.shuffle.io.retryWait=60s;\nset spark.metrics.indexFile=index-mobile.json;\nset spark.metrics.indexInputTable=dw.dwa_mobile_model_dt;\nset spark.metrics.indexOutputTable=dw.app_mdl_mobile_index_dt;\nset spark.metrics.indexWaitFullPartition=true;\nset spark.metrics.indexHashWhere=abs(hash(mobile))%4=3;\nnew_calculate_metrics-100-SNAPSHOT-jar-with-dependencies.jar com.example.dw.index.StartDCJob IndexOffline 2018-03-18\n            \"\"\"\n\n        val statementDatas = AppJarHelper.parseStatement(sql)\n        Assert.assertEquals(16, statementDatas.size)\n\n        val statement = statementDatas.get(15)\n        if (statement is AppJarInfo) {\n            Assert.assertEquals(StatementType.APP_JAR, statement.statementType)\n            Assert.assertEquals(\"new_calculate_metrics-100-SNAPSHOT-jar-with-dependencies.jar\", statement.resourceName)\n            Assert.assertEquals(\"com.example.dw.index.StartDCJob\", statement.className)\n            Assert.assertEquals(\"2018-03-18\", statement.params?.get(1))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setConfigTest5() {\n        val sql =\n            \"\"\"\n            set spark.shuffle.compress=true;set spark.rdd.compress=true;\nset spark.driver.maxResultSize=3g;\nset spark.serializer=org.apache.spark.serializer.KryoSerializer;\nset spark.kryoserializer.buffer.max=1024m;\nset spark.kryoserializer.buffer=256m;\nset spark.network.timeout=300s;\ncreateHfile-1.2-SNAPSHOT-jar-with-dependencies.jar imei_test.euSaveHBase gaea_offline:account_mobile sh md shda.interest_radar_mobile_score_dt 20180318 /xiaoyong.fu/sh/mobile/loan 400 '%7B%22job_type%22=' --jar\n            \"\"\"\n\n        val statementDatas = AppJarHelper.parseStatement(sql)\n        Assert.assertEquals(8, statementDatas.size)\n\n        val statement = statementDatas.get(7)\n        if (statement is AppJarInfo) {\n            Assert.assertEquals(StatementType.APP_JAR, statement.statementType)\n            Assert.assertEquals(\"createHfile-1.2-SNAPSHOT-jar-with-dependencies.jar\", statement.resourceName)\n            Assert.assertEquals(\"imei_test.euSaveHBase\", statement.className)\n            Assert.assertEquals(\"/xiaoyong.fu/sh/mobile/loan\", statement.params?.get(5))\n            Assert.assertEquals(\"400\", statement.params?.get(6))\n            Assert.assertEquals(\"%7B%22job_type%22=\", statement.params?.get(7))\n            Assert.assertEquals(\"--jar\", statement.params?.get(8))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setConfigTest6() {\n        val sql =\n            \"\"\"\n            set spark.toMysql.url=jdbc:mysql://192.168.40.110:3306/data_quality;set spark.toMysql.user=dq;\nset spark.toMysql.password=0nlpSvpgC5leeKuw;\nset spark.screenJob.screenType=3;\nset spark.screenJob.test=true;\nset spark.screenTool.srcTable=default.activity_flat;\nset spark.toMysql.tableName=province;\nset spark.toMysql.field=creditProvinceAmountJson,creditForeignAmount,creditCityAmountJson,zhejiangFraud,fraudProvinceAmountJson;\nprovince-1.0-SNAPSHOT-jar-with-dependencies.jar com.example.screen_dc.ScreenJob /xiaoyong.fu/2017-22-03/sh/mobile/loan/ --write-private-test;\nprovince-1.0-SNAPSHOT-jar-with-dependencies.jar com.example.screen_dc.ScreenJob /xiaoyong.fu/2017-22-03/sh/mobile/loan/ --write-private-test\n            \"\"\"\n\n        val statementDatas = AppJarHelper.parseStatement(sql)\n        Assert.assertEquals(10, statementDatas.size)\n\n        val statement = statementDatas.get(9)\n        if (statement is AppJarInfo) {\n            Assert.assertEquals(StatementType.APP_JAR, statement.statementType)\n            Assert.assertEquals(\"province-1.0-SNAPSHOT-jar-with-dependencies.jar\", statement.resourceName)\n            Assert.assertEquals(\"com.example.screen_dc.ScreenJob\", statement.className)\n            Assert.assertEquals(\"/xiaoyong.fu/2017-22-03/sh/mobile/loan/\", statement.params?.get(0))\n            Assert.assertEquals(\"--write-private-test\", statement.params?.get(1))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setConfigTest7() {\n        val sql =\n            \"\"\"\n            raph.edgesSNAPSHOT.eventType.jar com.example.graph.PhoenixCSVWriterJob graph_csv_s_2 /user/datacompute/bigdata/data/shuoyi.zhao/graph_csv_s_2/2018/12/day_12\n            /user/datacompute/bigdata/data/shuoyi.zhao/graph_csv_s_new_2/Loan/2018/12/day_12 500 Loan hdfs://192.168.40.37,hdfs://192.168.39.133 hdfs://192.168.40.37,hdfs://192.168.39.130;\n            \"\"\"\n\n        val statementDatas = AppJarHelper.parseStatement(sql)\n        Assert.assertEquals(1, statementDatas.size)\n\n        val statement = statementDatas.get(0)\n        if (statement is AppJarInfo) {\n            Assert.assertEquals(StatementType.APP_JAR, statement.statementType)\n            Assert.assertEquals(\"raph.edgesSNAPSHOT.eventType.jar\", statement.resourceName)\n            Assert.assertEquals(\"com.example.graph.PhoenixCSVWriterJob\", statement.className)\n            Assert.assertEquals(\"hdfs://192.168.40.37,hdfs://192.168.39.130\", statement.params?.get(6))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setConfigTest8() {\n        val sql =\n            \"\"\"\n            set spark.app.name=sparkAppName;\n            set spark.memory.storageFraction=0.1;\n            set spark.memory.fraction=0.95;\n            set spark.memory.useLegacyMode=true;\n            set master=yarn-cluster;\n            /user/pontus_2.1/pontus-core-2.1.0-SNAPSHOT-fat.jar com.example.pontus.core.Engine customCmd \"-j{'readerFields':[{'field':'uuid','type':'string'},{'field':'rule_detail','type':'string'}],'resourceSetting':{'spark.driver.memory':'2g','spark.pontus.writer.mapper':'2'},'reader':{'databaseName':'afraudtech','connectionType':'hive','table':'antifraud_rule_result'},'writerFields':[{'transform':'uuid','field':'uuid','type':'varchar(32)'},{'filter':'where id=\\'test\\'','transform':'rule_detail','field':'policy_recommendation','type':'text'}],'writer':{'dataSourceId':'364','connectionAttr':'jdbc:mysql://192.168.74.136:3306/athena','password':'6ydJDezPBLBuco+sCV6QL6XsdTN/ShtYIz1Gi3TVusw=','writeMode':'UPSERT','userName':'athena','connectionType':'mysql','table':'edison_warning_result'}}\"  --jars /user/pontus_2.1/*\n            \"\"\"\n\n        val statementDatas = AppJarHelper.parseStatement(sql)\n        Assert.assertEquals(6, statementDatas.size)\n\n        val statement = statementDatas.get(5)\n        if (statement is AppJarInfo) {\n            Assert.assertEquals(StatementType.APP_JAR, statement.statementType)\n            Assert.assertEquals(\"/user/pontus_2.1/pontus-core-2.1.0-SNAPSHOT-fat.jar\", statement.resourceName)\n            Assert.assertEquals(\"com.example.pontus.core.Engine\", statement.className)\n            Assert.assertEquals(4, statement.params?.size)\n            val config =\n                \"\"\"\n                -j{'readerFields':[{'field':'uuid','type':'string'},{'field':'rule_detail','type':'string'}],'resourceSetting':{'spark.driver.memory':'2g','spark.pontus.writer.mapper':'2'},'reader':{'databaseName':'afraudtech','connectionType':'hive','table':'antifraud_rule_result'},'writerFields':[{'transform':'uuid','field':'uuid','type':'varchar(32)'},{'filter':'where id=\\'test\\'','transform':'rule_detail','field':'policy_recommendation','type':'text'}],'writer':{'dataSourceId':'364','connectionAttr':'jdbc:mysql://192.168.74.136:3306/athena','password':'6ydJDezPBLBuco+sCV6QL6XsdTN/ShtYIz1Gi3TVusw=','writeMode':'UPSERT','userName':'athena','connectionType':'mysql','table':'edison_warning_result'}}\n                \"\"\"\n            Assert.assertEquals(config.trim(), statement.params?.get(1))\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-appjar-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-arithmetic-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-arithmetic-parser</artifactId>\n    <name>superior-arithmetic-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "superior-arithmetic-parser/src/main/antlr4/io/github/melin/superior/parser/antlr4/arithmetic/Arithmetic.g4",
    "content": "grammar Arithmetic;\n\n@members {\n    public boolean bracket_enbled = true;\n}\n\narithmetic: expression EOF;\n\nexpression\n    : booleanExpression\n    ;\n\nbooleanExpression\n    : NOT booleanExpression                                        #logicalNot\n    | valueExpression predicate?                                   #predicated\n    | left=booleanExpression operator=AND right=booleanExpression  #logicalBinary\n    | left=booleanExpression operator=OR right=booleanExpression   #logicalBinary\n    ;\n\npredicate\n    : NOT? kind=BETWEEN lower=valueExpression AND upper=valueExpression\n    | NOT? kind=IN '(' expression (',' expression)* ')'\n    | NOT? kind=RLIKE pattern=valueExpression\n    | NOT? kind=LIKE pattern=valueExpression (ESCAPE escapeChar=STRING)?\n    | IS NOT? kind=NULL\n    | IS NOT? kind=(TRUE | FALSE | UNKNOWN)\n    ;\n\nvalueExpression\n    : primaryExpression                                                                      #valueExpressionDefault\n    | operator=(MINUS | PLUS | TILDE) valueExpression                                        #arithmeticUnary\n    | left=valueExpression operator=(ASTERISK | SLASH | PERCENT | DIV) right=valueExpression #arithmeticBinary\n    | left=valueExpression operator=(PLUS | MINUS | CONCAT_PIPE) right=valueExpression       #arithmeticBinary\n    | left=valueExpression operator=AMPERSAND right=valueExpression                          #arithmeticBinary\n    | left=valueExpression operator=HAT right=valueExpression                                #arithmeticBinary\n    | left=valueExpression operator=PIPE right=valueExpression                               #arithmeticBinary\n    | left=valueExpression comparisonOperator right=valueExpression                          #comparison\n    ;\n\nprimaryExpression\n    : CASE whenClause+ (ELSE elseExpression=expression)? END                                   #searchedCase\n    | CASE value=expression whenClause+ (ELSE elseExpression=expression)? END                  #simpleCase\n    | constant                                                                                 #constantDefault\n    | functionName '(' (setQuantifier? argument+=expression (',' argument+=expression)*)? ')'  #functionCall\n    | identifier '->' expression                                                               #lambda\n    | '(' identifier (',' identifier)+ ')' '->' expression                                     #lambda\n    | value=primaryExpression '[' index=valueExpression ']'                                    #subscript\n    | identifier                                                                               #columnReference\n    | '(' expression ')'                                                                       #parenthesizedExpression\n    ;\n\ncomparisonOperator\n    : EQ | NEQ | NEQJ | LT | LTE | GT | GTE | NSEQ\n    ;\n\nwhenClause\n    : WHEN condition=expression THEN result=expression\n    ;\n\nfunctionName\n    : IDENTIFIER\n    ;\n\nidentifier\n    : {!bracket_enbled}? IDENTIFIER\n    | {bracket_enbled}? LBRACKET IDENTIFIER RBRACKET\n    ;\n\nconstant\n    : NULL                                                                                     #nullLiteral\n    | number                                                                                   #numericLiteral\n    | booleanValue                                                                             #booleanLiteral\n    | STRING+                                                                                  #stringLiteral\n    ;\n\nsetQuantifier\n    : DISTINCT\n    | ALL\n    ;\n\nnumber\n    : MINUS? INTEGER_VALUE            #integerLiteral\n    | MINUS? BIGINT_LITERAL           #bigIntLiteral\n    | MINUS? SMALLINT_LITERAL         #smallIntLiteral\n    | MINUS? TINYINT_LITERAL          #tinyIntLiteral\n    | MINUS? DOUBLE_LITERAL           #doubleLiteral\n    | MINUS? BIGDECIMAL_LITERAL       #bigDecimalLiteral\n    ;\n\nbooleanValue\n    : TRUE | FALSE\n    ;\n\nSTRING\n    : '\\'' ( ~('\\''|'\\\\') | ('\\\\' .) )* '\\''\n    | '\"' ( ~('\"'|'\\\\') | ('\\\\' .) )* '\"'\n    ;\n\nTRUE: 'TRUE';\nFALSE: 'FALSE';\nNULL: 'NULL';\nCASE: 'CASE';\nWHEN: 'WHEN';\nTHEN: 'THEN';\nELSE: 'ELSE';\nEND: 'END';\nDISTINCT: 'DISTINCT';\nALL: 'ALL';\n\nNOT: 'NOT';\nAND: 'AND';\nOR: 'OR';\nBETWEEN: 'BETWEEN';\nIN: 'IN';\nRLIKE: 'RLIKE';\nLIKE: 'LIKE';\nIS: 'IS';\nESCAPE: 'ESCAPE';\nUNKNOWN: 'UNKNOWN';\n\nEQ  : '=' | '==';\nNSEQ: '<=>';\nNEQ : '<>';\nNEQJ: '!=';\nLT  : '<';\nLTE : '<=';\nGT  : '>';\nGTE : '>=';\nLBRACKET : '[' ;\nRBRACKET : ']' ;\n\nPLUS: '+';\nMINUS: '-';\nASTERISK: '*';\nSLASH: '/';\nPERCENT: '%';\nDIV: 'DIV';\nTILDE: '~';\nAMPERSAND: '&';\nPIPE: '|';\nCONCAT_PIPE: '||';\nHAT: '^';\n\nBIGINT_LITERAL\n    : DIGIT+ 'L'\n    ;\n\nSMALLINT_LITERAL\n    : DIGIT+ 'S'\n    ;\n\nTINYINT_LITERAL\n    : DIGIT+ 'Y'\n    ;\n\nINTEGER_VALUE\n    : DIGIT+\n    ;\n\nIDENTIFIER\n    : (LETTER | DIGIT | '_')+\n    ;\n\nfragment EXPONENT\n    : 'E' [+-]? DIGIT+\n    ;\n\nfragment DECIMAL_DIGITS\n    : DIGIT+ '.' DIGIT*\n    | '.' DIGIT+\n    ;\n\nDOUBLE_LITERAL\n    : DIGIT+ EXPONENT? 'D'\n    | DECIMAL_DIGITS EXPONENT? 'D'\n    ;\n\nBIGDECIMAL_LITERAL\n    : DIGIT+ EXPONENT? 'BD'\n    | DECIMAL_DIGITS EXPONENT? 'BD'\n    ;\n\nfragment DIGIT\n    : [0-9]\n    ;\n\nfragment LETTER\n    : [a-zA-Z]\n    | ~[\\u0000-\\u007F\\uD800-\\uDBFF] // covers all characters above 0x7F which are not a surrogate\n    | [\\uD800-\\uDBFF] [\\uDC00-\\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF\n    ;\n\nSIMPLE_COMMENT\n    : '--' ('\\\\\\n' | ~[\\r\\n])* '\\r'? '\\n'? -> channel(HIDDEN)\n    ;\n\nBRACKETED_EMPTY_COMMENT\n    : '/**/' -> channel(HIDDEN)\n    ;\n\nBRACKETED_COMMENT\n    : '/*' ~[+] .*? '*/' -> channel(HIDDEN)\n    ;\n\nWS  : [ \\r\\n\\t] + -> skip ;\n"
  },
  {
    "path": "superior-arithmetic-parser/src/main/kotlin/io/github/melin/superior/parser/arithmetic/AbstractArithParser.kt",
    "content": "package io.github.melin.superior.parser.arithmetic\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.antlr4.arithmetic.ArithmeticParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractArithParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(ArithmeticParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: ArithmeticParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(ArithmeticParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-arithmetic-parser/src/main/kotlin/io/github/melin/superior/parser/arithmetic/ArithmeticAntlr4Visitor.kt",
    "content": "package com.github.melin.superior.sql.parser.arithmetic\n\nimport io.github.melin.superior.common.SQLParserException\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.antlr4.arithmetic.ArithmeticBaseVisitor\nimport io.github.melin.superior.parser.antlr4.arithmetic.ArithmeticParser\nimport io.github.melin.superior.parser.arithmetic.ArithmeticData\nimport org.antlr.v4.runtime.tree.ParseTree\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2020/7/28 9:49 上午 */\nclass ArithmeticAntlr4Visitor(val bracketEnbled: Boolean) : ArithmeticBaseVisitor<Statement>() {\n\n    private var statement: Statement? = null\n\n    private val arithmetic = ArithmeticData()\n\n    override fun visit(tree: ParseTree): Statement? {\n        super.visit(tree)\n\n        if (statement == null) {\n            throw SQLParserException(\"不支持的表达式\")\n        }\n\n        return statement\n    }\n\n    override fun visitExpression(ctx: ArithmeticParser.ExpressionContext): Statement? {\n        statement = arithmetic\n        return super.visitExpression(ctx)\n    }\n\n    override fun visitIdentifier(ctx: ArithmeticParser.IdentifierContext): Statement? {\n        val name = ctx.text\n        if (!arithmetic.functions.contains(name)) {\n            if (bracketEnbled) {\n                arithmetic.variables.add(StringUtils.substringBetween(name, \"[\", \"]\"))\n            } else {\n                arithmetic.variables.add(name)\n            }\n        }\n        return super.visitIdentifier(ctx)\n    }\n\n    override fun visitFunctionName(ctx: ArithmeticParser.FunctionNameContext): Statement? {\n        val name = ctx.text\n        arithmetic.functions.add(name)\n        return super.visitFunctionName(ctx)\n    }\n}\n"
  },
  {
    "path": "superior-arithmetic-parser/src/main/kotlin/io/github/melin/superior/parser/arithmetic/ArithmeticHelper.kt",
    "content": "package com.github.melin.superior.sql.parser.arithmetic\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.antlr4.arithmetic.ArithmeticLexer\nimport io.github.melin.superior.parser.antlr4.arithmetic.ArithmeticParser\nimport io.github.melin.superior.parser.arithmetic.AbstractArithParser\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/1/10. */\nobject ArithmeticHelper {\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement? {\n        return ArithmeticHelper.parseStatement(command, true)\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String, bracketEnbled: Boolean): Statement? {\n        val trimCmd = StringUtils.trim(command)\n\n        val charStream = CharStreams.fromString(trimCmd)\n        val lexer = ArithmeticLexer(charStream)\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = ArithmeticParser(tokenStream)\n        AbstractArithParser.installCaches(parser)\n        parser.bracket_enbled = bracketEnbled\n        parser.interpreter.predictionMode = PredictionMode.SLL\n\n        val sqlVisitor = ArithmeticAntlr4Visitor(bracketEnbled)\n\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                return sqlVisitor.visit(parser.expression())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                return sqlVisitor.visit(parser.expression())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(trimCmd)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractArithParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-arithmetic-parser/src/main/kotlin/io/github/melin/superior/parser/arithmetic/Data.kt",
    "content": "package io.github.melin.superior.parser.arithmetic\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class ArithmeticData(\n    val variables: java.util.HashSet<String> = HashSet(),\n    val functions: java.util.HashSet<String> = HashSet()\n) : Statement() {\n    override val statementType = StatementType.ARITHMETIC\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-arithmetic-parser/src/test/kotlin/io/github/melin/superior/parser/arithmetic/ArithmetricParserTest.kt",
    "content": "package io.github.melin.superior.parser.arithmetic\n\nimport com.github.melin.superior.sql.parser.arithmetic.ArithmeticHelper\nimport io.github.melin.superior.common.StatementType\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2018/1/10. */\nclass ArithmetricParserTest {\n\n    @Test\n    fun test0() {\n        val sql = \"\"\"\n            特征1 / (特征_dd_2\n                - (log2(feature_12) + 特征3))\n            \"\"\"\n\n        val statement = ArithmeticHelper.parseStatement(sql, false)\n        Assert.assertEquals(StatementType.ARITHMETIC, statement?.statementType)\n        if (statement is ArithmeticData) {\n            Assert.assertEquals(4, statement.variables.toArray().size)\n            Assert.assertEquals(1, statement.functions.size)\n            Assert.assertEquals(\"log2\", statement.functions.toArray().get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun test1() {\n        val sql =\n            \"\"\"\n            case when rand <= 12 then 1\n                                when rand <= 23 then 2\n                                else 3 end\n            \"\"\"\n\n        val statement = ArithmeticHelper.parseStatement(sql, false)\n        Assert.assertEquals(StatementType.ARITHMETIC, statement?.statementType)\n        if (statement is ArithmeticData) {\n            Assert.assertEquals(1, statement.variables.toArray().size)\n            Assert.assertEquals(0, statement.functions.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun test2() {\n        val sql = \"\"\"\n            [特征1] / ([特征_dd_2]\n                - (log2([feature_12]) + [特征3]))\n            \"\"\"\n\n        val statement = ArithmeticHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ARITHMETIC, statement?.statementType)\n        if (statement is ArithmeticData) {\n            Assert.assertEquals(4, statement.variables.toArray().size)\n            Assert.assertEquals(1, statement.functions.size)\n            Assert.assertEquals(\"log2\", statement.functions.toArray().get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-arithmetic-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-common-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-common-parser</artifactId>\n    <name>superior-common-parser</name>\n\n</project>\n"
  },
  {
    "path": "superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/AntlrCaches.java",
    "content": "package io.github.melin.superior.common.antlr4;\n\nimport org.antlr.v4.runtime.Parser;\nimport org.antlr.v4.runtime.atn.ATN;\nimport org.antlr.v4.runtime.atn.ParserATNSimulator;\nimport org.antlr.v4.runtime.atn.PredictionContextCache;\nimport org.antlr.v4.runtime.dfa.DFA;\n\npublic class AntlrCaches {\n\n    public static final String RELEASE_ANTLR_CACHE_AFTER_PARSING = \"releaseAntlrCacheAfterParsing\";\n\n    private final ATN atn;\n\n    private final PredictionContextCache predictionContextCache = new PredictionContextCache();\n\n    private final DFA[] decisionToDFA;\n\n    public AntlrCaches(ATN atn) {\n        this.atn = atn;\n        this.decisionToDFA = makeDecisionToDFA(this.atn);\n    }\n\n    public void installCaches(Parser parser) {\n        parser.setInterpreter(new ParserATNSimulator(parser, atn, decisionToDFA, predictionContextCache));\n    }\n\n    private DFA[] makeDecisionToDFA(ATN atn) {\n        DFA[] decisionToDFA = new DFA[atn.getNumberOfDecisions()];\n        for (int i = 0, len = atn.getNumberOfDecisions(); i < len; i++) {\n            decisionToDFA[i] = new DFA(atn.getDecisionState(i), i);\n        }\n        return decisionToDFA;\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/Origin.java",
    "content": "package io.github.melin.superior.common.antlr4;\n\npublic class Origin {\n    private int line;\n    private int startPosition;\n\n    public Origin(int line, int startPosition) {\n        this.line = line;\n        this.startPosition = startPosition;\n    }\n\n    public int getLine() {\n        return line;\n    }\n\n    public void setLine(int line) {\n        this.line = line;\n    }\n\n    public int getStartPosition() {\n        return startPosition;\n    }\n\n    public void setStartPosition(int startPosition) {\n        this.startPosition = startPosition;\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/ParseErrorListener.java",
    "content": "package io.github.melin.superior.common.antlr4;\n\nimport org.antlr.v4.runtime.BaseErrorListener;\nimport org.antlr.v4.runtime.RecognitionException;\nimport org.antlr.v4.runtime.Recognizer;\n\npublic class ParseErrorListener extends BaseErrorListener {\n\n    @Override\n    public void syntaxError(\n            Recognizer<?, ?> recognizer,\n            Object offendingSymbol,\n            int line,\n            int charPositionInLine,\n            java.lang.String msg,\n            RecognitionException e) {\n        Origin position = new Origin(line, charPositionInLine);\n        throw new ParseException(msg, position, position);\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/ParseException.java",
    "content": "package io.github.melin.superior.common.antlr4;\n\nimport org.apache.commons.lang3.StringUtils;\n\npublic class ParseException extends RuntimeException {\n    private String command;\n    private String message;\n    private Origin start;\n    private Origin stop;\n\n    public ParseException(String message, Origin start, Origin stop) {\n        this.message = message;\n        this.start = start;\n        this.stop = stop;\n    }\n\n    public ParseException(String command, String message, Origin start, Origin stop) {\n        this.command = command;\n        this.message = message;\n        this.start = start;\n        this.stop = stop;\n    }\n\n    @Override\n    public String getMessage() {\n        StringBuilder builder = new StringBuilder();\n        builder.append(\"\\n\").append(message);\n        if (start != null) {\n            builder.append(\"(line \" + start.getLine() + \", pos \" + start.getStartPosition() + \")\\n\");\n            if (StringUtils.isNotBlank(command)) {\n                String[] lines = command.split(\"\\n\");\n                builder.append(\"\\n== SQL ==\\n\");\n                for (int i = 0; i < start.getLine(); i++) {\n                    builder.append(lines[i]).append(\"\\n\");\n                }\n\n                for (int i = 0; i < start.getStartPosition(); i++) {\n                    builder.append(\"-\");\n                }\n                builder.append(\"^^^\\n\");\n\n                for (int i = start.getLine(); i < lines.length; i++) {\n                    builder.append(lines[i]).append(\"\\n\");\n                }\n            }\n        } else {\n            builder.append(\"\\n== SQL ==\\n\").append(command);\n        }\n\n        return StringUtils.trim(builder.toString());\n    }\n\n    public ParseException withCommand(String cmd) {\n        return new ParseException(cmd, message, start, stop);\n    }\n\n    public String getCommand() {\n        return command;\n    }\n\n    public Origin getStart() {\n        return start;\n    }\n\n    public Origin getStop() {\n        return stop;\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/ParserUtils.java",
    "content": "package io.github.melin.superior.common.antlr4;\n\nimport org.antlr.v4.runtime.CharStream;\nimport org.antlr.v4.runtime.ParserRuleContext;\nimport org.antlr.v4.runtime.Token;\nimport org.antlr.v4.runtime.misc.Interval;\nimport org.antlr.v4.runtime.tree.TerminalNode;\n\npublic class ParserUtils {\n\n    /** Get the code that creates the given node. */\n    public static String source(ParserRuleContext ctx) {\n        CharStream stream = ctx.getStart().getInputStream();\n        return stream.getText(\n                Interval.of(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex()));\n    }\n\n    public static String getString(Token token) {\n        return unescapeSQLString(token.getText());\n    }\n\n    public static String getString(TerminalNode token) {\n        return unescapeSQLString(token.getText());\n    }\n\n    public static int getInt(Token token) {\n        return Integer.parseInt(token.getText());\n    }\n\n    public static String command(ParserRuleContext ctx) {\n        CharStream stream = ctx.getStart().getInputStream();\n        return stream.getText(Interval.of(0, stream.size()));\n    }\n\n    public static Origin position(Token token) {\n        return new Origin(token.getLine(), token.getCharPositionInLine());\n    }\n\n    private static void appendEscapedChar(StringBuilder sb, char n) {\n        switch (n) {\n            case '0':\n                sb.append(\"\\u0000\");\n            case '\\'':\n                sb.append(\"\\'\");\n            case '\"':\n                sb.append(\"\\\"\");\n            case 'b':\n                sb.append(\"\\b\");\n            case 'n':\n                sb.append(\"\\n\");\n            case 'r':\n                sb.append(\"\\r\");\n            case 't':\n                sb.append(\"\\t\");\n            case 'Z':\n                sb.append(\"\\u001A\");\n            case '\\\\':\n                sb.append(\"\\\\\");\n                // The following 2 lines are exactly what MySQL does TODO: why do we do this?\n            case '%':\n                sb.append(\"\\\\%\");\n            case '_':\n                sb.append(\"\\\\_\");\n            default:\n                sb.append(n);\n        }\n    }\n\n    private static String unescapeSQLString(String b) {\n        Character enclosure = null;\n        StringBuilder sb = new StringBuilder(b.length());\n\n        int i = 0;\n        int strLength = b.length();\n        while (i < strLength) {\n            char currentChar = b.charAt(i);\n            if (enclosure == null) {\n                if (currentChar == '\\'' || currentChar == '\\\"') {\n                    enclosure = currentChar;\n                }\n            } else if (enclosure == currentChar) {\n                enclosure = null;\n            } else if (currentChar == '\\\\') {\n\n                if ((i + 6 < strLength) && b.charAt(i + 1) == 'u') {\n                    // \\u0000 style character literals.\n\n                    int code = 0;\n                    int base = i + 2;\n                    for (int h = 0; h < 4; h++) {\n                        int digit = Character.digit(b.charAt(h + base), 16);\n                        code = (code << 4) + digit;\n                    }\n                    sb.append((char) code);\n                    i += 5;\n                } else if (i + 4 < strLength) {\n                    // \\000 style character literals.\n\n                    char i1 = b.charAt(i + 1);\n                    char i2 = b.charAt(i + 2);\n                    char i3 = b.charAt(i + 3);\n\n                    if ((i1 >= '0' && i1 <= '1') && (i2 >= '0' && i2 <= '7') && (i3 >= '0' && i3 <= '7')) {\n                        char tmp = (char) ((i3 - '0') + ((i2 - '0') << 3) + ((i1 - '0') << 6));\n                        sb.append(tmp);\n                        i += 3;\n                    } else {\n                        appendEscapedChar(sb, i1);\n                        i += 1;\n                    }\n                } else if (i + 2 < strLength) {\n                    // escaped character literals.\n                    char n = b.charAt(i + 1);\n                    appendEscapedChar(sb, n);\n                    i += 1;\n                }\n            } else {\n                // non-escaped character literals.\n                sb.append(currentChar);\n            }\n            i += 1;\n        }\n        return sb.toString();\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/UpperCaseCharStream.java",
    "content": "package io.github.melin.superior.common.antlr4;\n\nimport org.antlr.v4.runtime.CharStream;\nimport org.antlr.v4.runtime.CodePointCharStream;\nimport org.antlr.v4.runtime.IntStream;\nimport org.antlr.v4.runtime.misc.Interval;\n\npublic class UpperCaseCharStream implements CharStream {\n\n    private CodePointCharStream wrapped;\n\n    public UpperCaseCharStream(CodePointCharStream wrapped) {\n        this.wrapped = wrapped;\n    }\n\n    @Override\n    public void consume() {\n        wrapped.consume();\n    }\n\n    @Override\n    public int LA(int i) {\n        int la = wrapped.LA(i);\n        if (la == 0 || la == IntStream.EOF) {\n            return la;\n        } else {\n            return Character.toUpperCase(la);\n        }\n    }\n\n    @Override\n    public String getText(Interval interval) {\n        if (size() > 0 && (interval.b - interval.a >= 0)) {\n            return wrapped.getText(interval);\n        } else {\n            return \"\";\n        }\n    }\n\n    @Override\n    public int mark() {\n        return wrapped.mark();\n    }\n\n    @Override\n    public void release(int i) {\n        wrapped.release(i);\n    }\n\n    @Override\n    public int index() {\n        return wrapped.index();\n    }\n\n    @Override\n    public void seek(int i) {\n        wrapped.seek(i);\n    }\n\n    @Override\n    public int size() {\n        return wrapped.size();\n    }\n\n    @Override\n    public String getSourceName() {\n        return wrapped.getSourceName();\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/AlterActionType.kt",
    "content": "package io.github.melin.superior.common\n\nimport java.io.Serializable\n\nenum class AlterActionType : Serializable {\n    SET_PROPS,\n    SET_SERDE,\n    TOUCH_TABLE,\n    ALTER_COLUMN,\n    ALTER_VIEW_QUERY,\n    ADD_UNIQUE_KEY,\n    ADD_PRIMARY_KEY,\n    ADD_INDEX,\n    ADD_PARTITION,\n    DROP_INDEX,\n    ADD_COLUMN,\n    SET_COLUMN_DEFAULT,\n    DROP_COLUMN,\n    DROP_COLUMN_DRFAULT,\n    DROP_PARTITION,\n    DROP_PRIMARY_KEY,\n    RENAME,\n    RENAME_PARTITION,\n    DETACH_PARTITION,\n    ATTACH_PARTITION,\n    TRUNCATE_PARTITION,\n    REFRESH_MV,\n\n    // Iceberg SQL Extensions\n    CREATE_TAG,\n    CREATE_BRANCH,\n    DROP_TAG,\n    DROP_BRANCH,\n    ADD_PARTITION_FIELD,\n    DROP_PARTITION_FIELD,\n    REPLACE_PARTITION_FIELD,\n    SET_WRITE_DISTRIBUTION_AND_ORDERING,\n    SET_IDENTIFIER_FIELDS,\n    DROP_IDENTIFIER_FIELDS,\n\n    // delta\n    ADD_CONSTRAINT,\n    DROP_CONSTRAINT,\n    DROP_FEATURE,\n    CLUSTER_BY,\n    SYNC_IDENTITY,\n    UNKOWN\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/PrivilegeType.kt",
    "content": "package io.github.melin.superior.common\n\nenum class PrivilegeType {\n    READ,\n    WRITE,\n    ALTER,\n    DROP,\n    ADMIN,\n    CREATE,\n    PROCEDURE,\n    OTHER,\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/SQLParserException.kt",
    "content": "package io.github.melin.superior.common\n\nclass SQLParserException : RuntimeException {\n    constructor(message: String, ex: Exception?) : super(message, ex) {}\n\n    constructor(message: String) : super(message) {}\n\n    constructor(ex: Exception) : super(ex) {}\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/SqlType.kt",
    "content": "package io.github.melin.superior.common\n\nenum class SqlType(val desc: String) {\n    DML(\"Data Manipulation Language\"),\n    DDL(\"Data Definition Language\"),\n    DQL(\"Data Query Language\"),\n    DCL(\"Data Control Language\"),\n    TCL(\"Transaction Control Language\")\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/StatementType.kt",
    "content": "package io.github.melin.superior.common\n\nimport java.io.Serializable\n\n/** Created by libinsong on 2017/3/6. */\nenum class StatementType : Serializable {\n    CREATE_CATALOG,\n    CREATE_DATABASE,\n    CREATE_SCHEMA,\n    CREATE_TABLE,\n    CREATE_TABLE_AS_SELECT,\n    CREATE_TABLE_AS_LIKE,\n    CREATE_MATERIALIZED_VIEW,\n    CREATE_VIEW,\n    CREATE_FILE_VIEW, // spark\n    CREATE_TEMP_VIEW_USING, // spark\n    CREATE_FUNCTION,\n    CREATE_PROCEDURE,\n    DROP_CATALOG,\n    DROP_DATABASE,\n    DROP_SCHEMA,\n    DROP_TABLE,\n    DROP_VIEW,\n    DROP_MATERIALIZED_VIEW,\n    DROP_FUNCTION,\n    DROP_SEQUENCE,\n    DROP_PROCEDURE,\n    TRUNCATE_TABLE,\n    REFRESH_TABLE,\n    EXPORT_TABLE,\n    CANCEL_EXPORT,\n    ANALYZE_TABLE,\n    ALTER_DATABASE,\n    ALTER_VIEW,\n    ALTER_MATERIALIZED_VIEW,\n    ALTER_TABLE,\n    REPAIR_TABLE,\n    COMMENT,\n\n    // DML\n    SELECT,\n    DELETE,\n    UPDATE,\n    MERGE,\n    INSERT,\n    LOAD_DATA, // spark\n    SHOW,\n    DESC,\n\n    // spark\n    CACHE,\n    UNCACHE,\n    CLEAR_CACHE,\n\n    // spark delta\n    VACUUM_TABLE,\n    OPTIMIZE_TABLE,\n    DESC_DELTA_DETAIL,\n    DESC_DELTA_HISTORY,\n\n    // spark\n    DESC_FUNCTION,\n    DESC_CATALOG,\n    DESC_DATABASE,\n    DESC_SCHEMA,\n    DESC_TABLE,\n    DESC_QUERY,\n\n    //\n    REFRESH_MV,\n    CANCEL_REFRESH_MV,\n    EXPLAIN,\n    SET,\n    RESET,\n    USE,\n    SPARK_DIST_CP,\n    DATATUNNEL, // spark\n    MERGE_FILE, // spark\n    APP_JAR, // spark\n    CALL, // hudi\n    HELP, // hudi\n    ARITHMETIC,\n\n    // StarRocks\n    SR_SUBMIT_TASK,\n    SR_DROP_TASK,\n    SR_CREATE_ROUTINE_LOAD,\n    SR_PAUSE_ROUTINE_LOAD,\n    SR_RESUME_ROUTINE_LOAD,\n    SR_STOP_ROUTINE_LOAD,\n    SR_ALTER_ROUTINE_LOAD,\n    LOAD_TABLE,\n    CANCEL_LOAD_TABLE,\n    ALTER_LOAD_TABLE,\n    ADD_RESOURCE,\n    LIST_RESOURCE,\n    REMOVE_RESOURCE,\n    SYNC_META,\n    SYNC_TABLE,\n    SYNC_DATABASE,\n    UNKOWN\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/TableType.kt",
    "content": "package io.github.melin.superior.common\n\nenum class TableType {\n    HIVE,\n    MYSQL,\n    ORACLE,\n    STARROCKS,\n    POSTGRES,\n    SQLSERVER,\n    FLINK,\n    SPARK_STREAM,\n    DAMENG,\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/AnalyzeTable.kt",
    "content": "package io.github.melin.superior.common.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\n\ndata class AnalyzeTable(val tableIds: List<TableId>) : Statement() {\n    override val statementType = StatementType.ANALYZE_TABLE\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/DefaultStatement.kt",
    "content": "package io.github.melin.superior.common.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\n\nclass DefaultStatement(override val statementType: StatementType) : Statement() {\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/FunctionId.kt",
    "content": "package io.github.melin.superior.common.relational\n\nimport com.google.common.collect.Lists\nimport org.apache.commons.lang3.StringUtils\n\ndata class FunctionId(\n    val catalogName: String?,\n    val schemaName: String?,\n    val functionName: String,\n) {\n\n    companion object {\n        @JvmStatic fun of(functionName: String) = TableId(functionName)\n\n        @JvmStatic fun of(schemaName: String, functionName: String) = TableId(schemaName, functionName)\n\n        @JvmStatic\n        fun of(catalogName: String, schemaName: String, functionName: String) =\n            TableId(catalogName, schemaName, functionName)\n    }\n\n    var funcType: String = \"CF\" // callfunction & TVF\n    var functionArguments: List<String> = Lists.newArrayList()\n\n    constructor(schemaName: String?, tableName: String) : this(null, schemaName, tableName)\n\n    constructor(tableName: String) : this(null, null, tableName)\n\n    fun getFullFunctionName(): String {\n        if (catalogName != null) {\n            return \"$catalogName.$schemaName.$functionName\"\n        }\n\n        if (schemaName != null) {\n            return \"$schemaName.$functionName\"\n        }\n\n        return functionName\n    }\n\n    fun getLowerCatalogName(): String {\n        return StringUtils.lowerCase(catalogName)\n    }\n\n    fun getLowerSchemaName(): String {\n        return StringUtils.lowerCase(schemaName)\n    }\n\n    fun getLowerTableName(): String {\n        return StringUtils.lowerCase(functionName)\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/ProcedureId.kt",
    "content": "package io.github.melin.superior.common.relational\n\nimport org.apache.commons.lang3.StringUtils\n\ndata class ProcedureId(val catalogName: String?, val schemaName: String?, val procedureName: String) {\n\n    constructor(schemaName: String?, procedureName: String) : this(null, schemaName, procedureName)\n\n    constructor(procedureName: String) : this(null, null, procedureName)\n\n    fun getFullFunctionName(): String {\n        if (catalogName != null) {\n            return \"${catalogName}.${schemaName}.${procedureName}\"\n        }\n\n        if (schemaName != null) {\n            return \"${schemaName}.${procedureName}\"\n        }\n\n        return procedureName\n    }\n\n    fun getLowerCatalogName(): String {\n        return StringUtils.lowerCase(catalogName)\n    }\n\n    fun getLowerSchemaName(): String {\n        return StringUtils.lowerCase(schemaName)\n    }\n\n    fun getLowerTableName(): String {\n        return StringUtils.lowerCase(procedureName)\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/SchemaId.kt",
    "content": "package io.github.melin.superior.common.relational\n\nimport org.apache.commons.lang3.StringUtils\n\ndata class SchemaId(val catalogName: String?, val schemaName: String) {\n\n    companion object {\n        @JvmStatic fun of(schemaName: String) = SchemaId(schemaName)\n\n        @JvmStatic fun of(catalogName: String, schemaName: String) = SchemaId(catalogName, schemaName)\n    }\n\n    constructor(schemaName: String) : this(null, schemaName)\n\n    fun getFullSchemaName(): String {\n        if (catalogName != null) {\n            return \"${catalogName}.${schemaName}\"\n        }\n\n        return schemaName\n    }\n\n    fun getLowerCatalogName(): String {\n        return StringUtils.lowerCase(catalogName)\n    }\n\n    fun getLowerSchemaName(): String {\n        return StringUtils.lowerCase(schemaName)\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/Statement.kt",
    "content": "package io.github.melin.superior.common.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport org.apache.commons.lang3.StringUtils\nimport java.io.Serializable\n\nabstract class Statement : Serializable {\n    abstract val statementType: StatementType\n    abstract val privilegeType: PrivilegeType\n    abstract val sqlType: SqlType\n    private var sql: String = \"\"\n\n    fun setSql(sql: String) {\n        if (StringUtils.endsWith(sql, \";\")) {\n            this.sql = StringUtils.substringBeforeLast(sql, \";\")\n        } else {\n            this.sql = sql\n        }\n    }\n\n    fun getSql(): String {\n        return this.sql\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/TableId.kt",
    "content": "package io.github.melin.superior.common.relational\n\nimport org.apache.commons.lang3.StringUtils\n\ndata class TableId(val catalogName: String?, val schemaName: String?, val tableName: String, val metaType: String?) {\n\n    companion object {\n        @JvmStatic fun of(tableName: String) = TableId(tableName)\n\n        @JvmStatic fun of(schemaName: String, tableName: String) = TableId(schemaName, tableName)\n\n        @JvmStatic\n        fun of(catalogName: String, schemaName: String, tableName: String) = TableId(catalogName, schemaName, tableName)\n    }\n\n    constructor(\n        catalogName: String?,\n        schemaName: String?,\n        tableName: String\n    ) : this(catalogName, schemaName, tableName, null)\n\n    constructor(schemaName: String?, tableName: String) : this(null, schemaName, tableName, null)\n\n    constructor(tableName: String) : this(null, null, tableName, null)\n\n    fun getFullTableName(): String {\n        if (catalogName != null) {\n            return \"${catalogName}.${schemaName}.${tableName}\"\n        }\n\n        if (schemaName != null) {\n            return \"${schemaName}.${tableName}\"\n        }\n\n        return tableName\n    }\n\n    fun getLowerCatalogName(): String {\n        return StringUtils.lowerCase(catalogName)\n    }\n\n    fun getLowerSchemaName(): String {\n        return StringUtils.lowerCase(schemaName)\n    }\n\n    fun getLowerTableName(): String {\n        return StringUtils.lowerCase(tableName)\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/abs/AbsDatabaseStatement.kt",
    "content": "package io.github.melin.superior.common.relational.abs\n\nimport io.github.melin.superior.common.relational.Statement\n\nabstract class AbsDatabaseStatement : Statement() {\n    abstract val databaseName: String\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/abs/AbsTableStatement.kt",
    "content": "package io.github.melin.superior.common.relational.abs\n\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\n\nabstract class AbsTableStatement : Statement() {\n    abstract val tableId: TableId\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterAction.kt",
    "content": "package io.github.melin.superior.common.relational.alter\n\nimport io.github.melin.superior.common.AlterActionType\nimport io.github.melin.superior.common.PrivilegeType\n\nabstract class AlterAction(val privilegeType: PrivilegeType = PrivilegeType.ALTER) {\n    abstract val alterType: AlterActionType\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterActions.kt",
    "content": "package io.github.melin.superior.common.relational.alter\n\nimport com.google.common.collect.Maps\nimport io.github.melin.superior.common.AlterActionType\nimport io.github.melin.superior.common.relational.SortType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport io.github.melin.superior.common.relational.table.ColumnRel\nimport java.util.HashMap\n\ndata class AlterTableAction(override var alterType: AlterActionType) : AlterAction()\n\ndata class AlterPropsAction(var location: String? = null, var properties: HashMap<String, String> = Maps.newHashMap()) :\n    AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.SET_PROPS\n\n    constructor(properties: HashMap<String, String>) : this(null, properties)\n}\n\ndata class AlterSerDeAction(var properties: HashMap<String, String> = Maps.newHashMap()) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.SET_SERDE\n}\n\ndata class RenameAction(var newTableId: TableId, var ifExists: Boolean = false) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.RENAME\n}\n\ndata class AlterTouchPartitionAction(\n    val newTableId: TableId, // 修改表，新列名称\n    val partitionVals: LinkedHashMap<String, String>?\n) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.TOUCH_TABLE\n}\n\ndata class AlterViewAction(\n    val queryStmt: QueryStmt // 修改表，新列名称\n) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.ALTER_VIEW_QUERY\n}\n\ndata class RefreshMvAction(var async: Boolean = false) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.REFRESH_MV\n}\n\ndata class AlterColumnAction(\n    override var alterType: AlterActionType,\n    var columName: String? = null, // 修改列名\n    var dataType: String? = null,\n    var comment: String? = null,\n    var position: String? = null,\n    var afterCol: String? = null,\n    var setOrDrop: String? = null,\n    var nullable: Boolean = true,\n    var defaultExpression: String? = null,\n    var dropDefault: Boolean = false,\n    var ifNotExists: Boolean = false\n) : AlterAction() {\n    var newColumName: String? = null // 修改列名，新列名称\n\n    fun getColumn(): ColumnRel? {\n        return if (columName != null) {\n            ColumnRel(columName!!, dataType, comment, nullable, defaultExpression)\n        } else {\n            null\n        }\n    }\n}\n\ndata class DropColumnAction(var columNames: ArrayList<String> = arrayListOf()) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.DROP_COLUMN\n\n    fun firstColumn(): String {\n        return columNames.first()\n    }\n\n    constructor(columName: String) : this(arrayListOf(columName))\n}\n\ndata class AddPartitionAction(var ifNotExists: Boolean = false, var partitions: List<LinkedHashMap<String, String>>) :\n    AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.ADD_PARTITION\n}\n\ndata class DropPartitionAction(\n    var ifExists: Boolean = false,\n    var partitions: List<LinkedHashMap<String, String>> = listOf()\n) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.DROP_PARTITION\n}\n\ndata class RenamePartitionAction(\n    var fromPartitionVals: LinkedHashMap<String, String>,\n    var toPartitionVals: LinkedHashMap<String, String>\n) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.RENAME_PARTITION\n}\n\ndata class CreateIndex(val indexName: String, val indexColumnNames: ArrayList<IndexColumnName> = arrayListOf()) :\n    AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.ADD_INDEX\n    var intimeAction: String = \"ONLINE\" // mysql ONLINE & OFFLINE\n    var indexCategory: String? = null\n    var indexType: String? = null\n    var comment: String? = null\n}\n\ndata class IndexColumnName(\n    val columnName: String,\n    val sortType: SortType = SortType.UNKOWN,\n)\n\ndata class DropIndex(val indexName: String, var ifExists: Boolean = false) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.DROP_INDEX\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterDatabase.kt",
    "content": "package io.github.melin.superior.common.relational.alter\n\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.relational.abs.AbsDatabaseStatement\nimport kotlin.collections.ArrayList\n\ndata class AlterDatabase(\n    val alterActionType: AlterActionType,\n    override val databaseName: String,\n    private val action: AlterAction?\n) : AbsDatabaseStatement() {\n    override val statementType = StatementType.ALTER_DATABASE\n    override val privilegeType = PrivilegeType.ALTER\n    override val sqlType = SqlType.DDL\n\n    val actions: ArrayList<AlterAction> = ArrayList()\n    var ifExists: Boolean = false\n\n    init {\n        if (action != null) {\n            actions.add(action)\n        }\n    }\n\n    constructor(alterActionType: AlterActionType, databaseName: String) : this(alterActionType, databaseName, null)\n\n    fun addActions(list: List<AlterAction>) {\n        actions.addAll(list)\n    }\n\n    fun firstAction(): AlterAction {\n        return actions.first()\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterDatabaseActions.kt",
    "content": "package io.github.melin.superior.common.relational.alter\n\nimport com.google.common.collect.Maps\nimport io.github.melin.superior.common.AlterActionType\nimport java.util.HashMap\n\ndata class AlterDbPropsAction(\n    var location: String? = null,\n    var properties: HashMap<String, String> = Maps.newHashMap()\n) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.SET_PROPS\n}\n\ndata class RenameDbAction(var newDatabaseName: String) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.RENAME\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterMaterializedView.kt",
    "content": "package io.github.melin.superior.common.relational.alter\n\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\nimport kotlin.collections.ArrayList\n\ndata class AlterMaterializedView(override val tableId: TableId, private val action: AlterAction?) :\n    AbsTableStatement() {\n    override val statementType = StatementType.ALTER_MATERIALIZED_VIEW\n    override val privilegeType = PrivilegeType.ALTER\n    override val sqlType = SqlType.DDL\n\n    val actions: ArrayList<AlterAction> = ArrayList()\n    var ifExists: Boolean = false\n\n    init {\n        if (action != null) {\n            actions.add(action)\n        }\n    }\n\n    constructor(tableId: TableId) : this(tableId, null)\n\n    fun addActions(list: List<AlterAction>) {\n        actions.addAll(list)\n    }\n\n    fun firstAction(): AlterAction {\n        return actions.first()\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterTable.kt",
    "content": "package io.github.melin.superior.common.relational.alter\n\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\nimport kotlin.collections.ArrayList\n\ndata class AlterTable(\n    override val tableId: TableId,\n    private val action: AlterAction?,\n) : AbsTableStatement() {\n    override val statementType = StatementType.ALTER_TABLE\n    override val privilegeType = PrivilegeType.ALTER\n    override val sqlType = SqlType.DDL\n\n    val actions: ArrayList<AlterAction> = ArrayList()\n    var ifExists: Boolean = false\n\n    init {\n        if (action != null) {\n            actions.add(action)\n        }\n    }\n\n    constructor(tableId: TableId) : this(tableId, null)\n\n    fun addAction(action: AlterAction) {\n        actions.add(action)\n    }\n\n    fun addActions(list: List<AlterAction>) {\n        actions.addAll(list)\n    }\n\n    fun firstAction(): AlterAction {\n        return if (action != null) action else actions.first()\n    }\n\n    fun getFirstAlterType(): AlterActionType {\n        val action = firstAction()\n        return action.alterType\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterView.kt",
    "content": "package io.github.melin.superior.common.relational.alter\n\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\nimport kotlin.collections.ArrayList\n\ndata class AlterView(override val tableId: TableId, private val action: AlterAction?) : AbsTableStatement() {\n    override val statementType = StatementType.ALTER_VIEW\n    override val privilegeType = PrivilegeType.ALTER\n    override val sqlType = SqlType.DDL\n\n    val actions: ArrayList<AlterAction> = ArrayList()\n    var ifExists: Boolean = false\n\n    init {\n        if (action != null) {\n            actions.add(action)\n        }\n    }\n\n    constructor(tableId: TableId) : this(tableId, null)\n\n    fun addActions(list: List<AlterAction>) {\n        actions.addAll(list)\n    }\n\n    fun firstAction(): AlterAction {\n        return actions.first()\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/DeltaAlterActions.kt",
    "content": "package io.github.melin.superior.common.relational.alter\n\nimport io.github.melin.superior.common.AlterActionType\n\nclass AlterAddConstraintAction() : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.ADD_CONSTRAINT\n}\n\nclass AlterDropConstraintAction() : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.DROP_CONSTRAINT\n}\n\nclass AlterDropFeatureAction() : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.DROP_FEATURE\n}\n\nclass AlterClusterByAction() : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.CLUSTER_BY\n}\n\nclass AlterSyncIdentityAction() : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.SYNC_IDENTITY\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/IcebergAlterActions.kt",
    "content": "package io.github.melin.superior.common.relational.alter\n\nimport io.github.melin.superior.common.AlterActionType\n\ndata class AlterCreateTagAction(val tagName: String) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.CREATE_TAG\n}\n\ndata class AlterDropTagAction(val tagName: String) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.DROP_TAG\n}\n\ndata class AlterCreateBranchAction(val branchName: String) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.CREATE_BRANCH\n}\n\ndata class AlterDropBranchAction(val branchName: String) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.DROP_BRANCH\n}\n\ndata class AlterSetIdentifierFieldsAction(val fields: List<String>) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.SET_IDENTIFIER_FIELDS\n}\n\ndata class AlterDropIdentifierFieldsAction(val fields: List<String>) : AlterAction() {\n    override var alterType: AlterActionType = AlterActionType.DROP_IDENTIFIER_FIELDS\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/AddResourceStatement.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\nclass AddResourceStatement(val fileNames: List<String>, val resourceType: String) : Statement() {\n    override val statementType = StatementType.ADD_RESOURCE\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n\n    constructor(fileName: String, resourceType: String) : this(listOf(fileName), resourceType)\n\n    fun first(): String {\n        return fileNames.first()\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/CallProcedure.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport com.google.common.collect.Sets\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.ProcedureId\nimport io.github.melin.superior.common.relational.Statement\n\ndata class CallProcedure(var procedureIds: HashSet<ProcedureId>, var properties: Map<String, String> = mapOf()) :\n    Statement() {\n    override val statementType = StatementType.CALL\n    override val privilegeType = PrivilegeType.ADMIN\n    override val sqlType = SqlType.DML\n\n    constructor(procedureId: ProcedureId) : this(Sets.newHashSet(procedureId))\n\n    constructor(\n        procedureId: ProcedureId,\n        properties: Map<String, String>\n    ) : this(Sets.newHashSet(procedureId), properties)\n\n    fun first(): ProcedureId {\n        return procedureIds.first()\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/CancelExport.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class CancelExport(val database: String?, var queryId: String) : Statement() {\n    override val statementType = StatementType.CANCEL_EXPORT\n    override val privilegeType = PrivilegeType.ALTER\n    override val sqlType = SqlType.DML\n\n    constructor(queryId: String) : this(null, queryId)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/CommentStatement.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class CommentStatement(\n    val comment: String? = null,\n    val isNull: Boolean = false,\n    val objType: String? = null,\n    val objValue: String? = null\n) : Statement() {\n    override val statementType = StatementType.COMMENT\n    override val privilegeType = PrivilegeType.ALTER\n    override val sqlType = SqlType.TCL\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/DescModel.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.SchemaId\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport org.apache.commons.lang3.StringUtils\n\nclass DescStatement(vararg val keywords: String) : Statement() {\n    override val statementType = StatementType.DESC\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n\n    fun checkSql(sql: String): Boolean {\n        val words = StringUtils.split(sql, \" \")\n        if (this.keywords.size != words.size) {\n            return false\n        }\n\n        val size = this.keywords.size\n        for (i in 0 until size) {\n            if (!StringUtils.equalsIgnoreCase(this.keywords.get(i), words[i])) {\n                return false\n            }\n        }\n\n        return true\n    }\n}\n\n// spark\ndata class DescFunction(val functionId: FunctionId) : Statement() {\n    override val statementType = StatementType.DESC_FUNCTION\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DDL\n}\n\ndata class DescCatalog(val catalog: String) : Statement() {\n    override val statementType = StatementType.DESC_CATALOG\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DDL\n}\n\n// 适用pg 类型数据库\ndata class DescDatabase(val database: String) : Statement() {\n    override val statementType = StatementType.DESC_DATABASE\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DDL\n}\n\ndata class DescSchema(val schemaId: SchemaId) : Statement() {\n    override val statementType = StatementType.DESC_SCHEMA\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DDL\n}\n\ndata class DescTable(val tableId: TableId) : Statement() {\n    override val statementType = StatementType.DESC_TABLE\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DDL\n}\n\ndata class DescQuery(val queryStmt: QueryStmt) : Statement() {\n    override val statementType = StatementType.DESC_QUERY\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DDL\n}\n\n// spark delta\ndata class DescDeltaDetail(override val tableId: TableId) : AbsTableStatement() {\n    override val statementType = StatementType.DESC_DELTA_DETAIL\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DDL\n}\n\n// spark delta\ndata class DescDeltaHistory(override val tableId: TableId, val limit: Int? = null) : AbsTableStatement() {\n    override val statementType = StatementType.DESC_DELTA_HISTORY\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DDL\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/ListResourceStatement.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\nclass ListResourceStatement(val fileNames: List<String>, val resourceType: String) : Statement() {\n    override val statementType = StatementType.ADD_RESOURCE\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n\n    constructor(fileName: String, resourceType: String) : this(listOf(fileName), resourceType)\n\n    fun first(): String {\n        return fileNames.first()\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/ReSetStatement.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class ReSetStatement(val key: String) : Statement() {\n    override val statementType = StatementType.RESET\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.TCL\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/RefreshMaterializedView.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\n\ndata class RefreshMaterializedView(\n    val tableId: TableId,\n    val force: Boolean = false,\n    val mode: String = \"Async\",\n    val partitionStart: String? = null,\n    val partitionEnd: String? = null,\n) : Statement() {\n    override val statementType = StatementType.REFRESH_MV\n    override val privilegeType = PrivilegeType.ADMIN\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/RemoveResourceStatement.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\nclass RemoveResourceStatement(val fileNames: List<String>, val resourceType: String) : Statement() {\n    override val statementType = StatementType.REMOVE_RESOURCE\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n\n    constructor(fileName: String, resourceType: String) : this(listOf(fileName), resourceType)\n\n    fun first(): String {\n        return fileNames.first()\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/SetStatement.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class SetStatement(val key: String, val value: String? = null) : Statement() {\n    override val statementType = StatementType.SET\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.TCL\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/ShowStatement.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\nimport org.apache.commons.lang3.StringUtils\n\nclass ShowStatement(vararg val keywords: String) : Statement() {\n    override val statementType = StatementType.SHOW\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n\n    fun checkSql(sql: String): Boolean {\n        val words = StringUtils.split(sql, \" \")\n        if (this.keywords.size != words.size) {\n            return false\n        }\n\n        val size = this.keywords.size\n        for (i in 0 until size) {\n            if (!StringUtils.equalsIgnoreCase(this.keywords.get(i), words[i])) {\n                return false\n            }\n        }\n\n        return true\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/SyncStatement.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport com.google.common.collect.Maps\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.table.ColumnRel\n\ndata class SyncTable(\n    var sinkTableId: TableId,\n    var sourceTableId: TableId,\n) : Statement() {\n    override val statementType = StatementType.SYNC_TABLE\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DML\n\n    val sinkOptions: HashMap<String, String> = Maps.newHashMap()\n\n    val sourceOptions: HashMap<String, String> = Maps.newHashMap()\n\n    var computeCols: List<ColumnRel>? = null\n}\n\ndata class SyncDatabase(\n    var sinkCatalogName: String?,\n    var sinkDatabaseName: String,\n    var sourceCatalogName: String?,\n    var sourceDatabaseName: String,\n    var includingTables: String = \".*\"\n) : Statement() {\n    override val statementType = StatementType.SYNC_DATABASE\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DML\n\n    val sinkOptions: HashMap<String, String> = Maps.newHashMap()\n\n    val sourceOptions: HashMap<String, String> = Maps.newHashMap()\n\n    var excludingTables: String? = null\n}\n\ndata class SyncDatabaseMetadata(val catalogName: String?, val databaseName: String, val owner: String?) : Statement() {\n    override val statementType = StatementType.SYNC_META\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DDL\n}\n\ndata class SyncTableMetadata(val tableId: TableId, val owner: String?) : Statement() {\n    override val statementType = StatementType.SYNC_META\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DDL\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/UseStatement.kt",
    "content": "package io.github.melin.superior.common.relational.common\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class UseCatalog(val catalogName: String) : Statement() {\n    override val statementType = StatementType.USE\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n}\n\ndata class UseDatabase(val catalogName: String?, val databaseName: String) : Statement() {\n    override val statementType = StatementType.USE\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n\n    constructor(databaseName: String) : this(null, databaseName)\n}\n\ndata class UseSchema(val databaseName: String?, val schemaName: String) : Statement() {\n    override val statementType = StatementType.USE\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n\n    constructor(databaseName: String) : this(null, databaseName)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateCatalog.kt",
    "content": "package io.github.melin.superior.common.relational.create\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\nclass CreateCatalog(\n    val catalogName: String,\n    var properties: Map<String, String>? = null,\n) : Statement() {\n    override val statementType = StatementType.CREATE_CATALOG\n    override val privilegeType = PrivilegeType.ADMIN\n    override val sqlType = SqlType.DDL\n\n    constructor(catalogName: String) : this(catalogName, null)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateDatabase.kt",
    "content": "package io.github.melin.superior.common.relational.create\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\nclass CreateDatabase(\n    val catalogName: String?,\n    val databaseName: String,\n    val location: String? = null,\n    var properties: Map<String, String>? = null,\n    var ifNotExists: Boolean = false,\n) : Statement() {\n    override val statementType = StatementType.CREATE_DATABASE\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DDL\n\n    constructor(databaseName: String) : this(null, databaseName, null, null)\n\n    constructor(\n        catalogName: String?,\n        databaseName: String,\n        properties: Map<String, String>? = null,\n        ifNotExists: Boolean = false\n    ) : this(catalogName, databaseName, null, properties, ifNotExists)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateFunction.kt",
    "content": "package io.github.melin.superior.common.relational.create\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.Statement\n\ndata class CreateFunction(\n    val functionId: FunctionId,\n    val childStatements: ArrayList<Statement>,\n    var replace: Boolean = false,\n    var temporary: Boolean = false,\n    val className: String? = null,\n    val file: String? = null\n) : Statement() {\n    override val statementType = StatementType.CREATE_FUNCTION\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DML\n\n    var global: Boolean = false // starrocks\n    var properties: Map<String, String>? = null // starrocks\n    var argumentTypes: List<String>? = null // starrocks\n    var returnType: String? = null // starrocks\n\n    constructor(\n        functionId: FunctionId,\n        childStatements: ArrayList<Statement>,\n        replace: Boolean\n    ) : this(functionId, childStatements, replace, false)\n\n    constructor(\n        functionId: FunctionId,\n        childStatements: ArrayList<Statement>\n    ) : this(functionId, childStatements, false, false)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateMaterializedView.kt",
    "content": "package io.github.melin.superior.common.relational.create\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport io.github.melin.superior.common.relational.table.ColumnRel\n\ndata class CreateMaterializedView(\n    override val tableId: TableId,\n    var queryStmt: QueryStmt,\n    val comment: String? = null,\n    var ifNotExists: Boolean = false, // 是否存在 if not exists 关键字\n    var columnRels: List<ColumnRel>? = null\n) : AbsTableStatement() {\n    override val statementType = StatementType.CREATE_MATERIALIZED_VIEW\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DDL\n\n    var modelType: String = \"Sync\" // 表模型类型\n    var properties: Map<String, String> = mapOf()\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateProcedure.kt",
    "content": "package io.github.melin.superior.common.relational.create\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.ProcedureId\nimport io.github.melin.superior.common.relational.Statement\n\ndata class CreateProcedure(\n    val procedureId: ProcedureId?,\n    val childStatements: ArrayList<Statement>,\n    var replace: Boolean = false,\n    var temporary: Boolean = false,\n    val className: String? = null,\n    val file: String? = null\n) : Statement() {\n    override val statementType = StatementType.CREATE_PROCEDURE\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DML\n\n    constructor(\n        procedureId: ProcedureId,\n        childStatements: ArrayList<Statement>,\n        replace: Boolean\n    ) : this(procedureId, childStatements, replace, false)\n\n    constructor(childStatements: ArrayList<Statement>) : this(null, childStatements)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateSchema.kt",
    "content": "package io.github.melin.superior.common.relational.create\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\nclass CreateSchema(val databaseName: String?, val schemaName: String) : Statement() {\n    override val statementType = StatementType.CREATE_SCHEMA\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DDL\n\n    constructor(schemaName: String) : this(null, schemaName)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateTable.kt",
    "content": "package io.github.melin.superior.common.relational.create\n\nimport com.google.common.collect.Lists\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.TableType\nimport io.github.melin.superior.common.relational.PartitionType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\nimport io.github.melin.superior.common.relational.table.ColumnRel\n\ndata class CreateTable(\n    override val tableId: TableId,\n    val tableType: TableType,\n    val comment: String? = null,\n    var lifeCycle: Int? = null,\n    var partitionColumnRels: List<ColumnRel>? = null,\n    var columnRels: List<ColumnRel>? = null,\n    var properties: Map<String, String>? = null,\n    var fileFormat: String? = null,\n    var ifNotExists: Boolean = false, // 是否存在 if not exists 关键字\n    var external: Boolean = false,\n    var temporary: Boolean = false,\n    var location: String? = null,\n    var querySql: String? = null,\n    val partitionColumnNames: ArrayList<String> = arrayListOf()\n) : AbsTableStatement() { // 是否存在 if exists 关键字\n    override val statementType = StatementType.CREATE_TABLE\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DDL\n\n    // 建表方式：hive & spark. https://spark.apache.org/docs/3.2.0/sql-ref-syntax-ddl-create-table.html\n    var replace = false\n    var modelType: String = \"hive\" // 表模型类型\n    var partitionType: PartitionType? = null // 分区类型\n    var options: Map<String, String>? = null\n    var clusteredColumns: List<String> = Lists.newArrayList() // 分桶表分桶列\n    var sortedColumns: List<String> = Lists.newArrayList() // 分桶表排序列\n    var storageHandler: String? = null\n\n    constructor(\n        tableId: TableId,\n        tableType: TableType,\n        comment: String?,\n        columnRels: List<ColumnRel>?\n    ) : this(tableId, tableType, comment, null, null, columnRels, null, null, false)\n\n    constructor(\n        tableId: TableId,\n        tableType: TableType,\n        comment: String?,\n        lifeCycle: Int?,\n        columnRels: List<ColumnRel>?\n    ) : this(tableId, tableType, comment, lifeCycle, null, columnRels, null, null, false)\n\n    constructor(\n        tableId: TableId,\n        tableType: TableType,\n        comment: String? = null,\n        columnRels: List<ColumnRel>? = null,\n        ifNotExists: Boolean,\n        properties: Map<String, String>? = null\n    ) : this(tableId, tableType, comment, null, null, columnRels, properties, null, ifNotExists)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateTableAsSelect.kt",
    "content": "package io.github.melin.superior.common.relational.create\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.PartitionType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport io.github.melin.superior.common.relational.table.ColumnRel\n\ndata class CreateTableAsSelect(\n    override val tableId: TableId,\n    var queryStmt: QueryStmt,\n    val comment: String? = null,\n    var lifeCycle: Int? = null,\n    var partitionColumnRels: List<ColumnRel>? = null,\n    var columnRels: List<ColumnRel>? = null,\n    var properties: Map<String, String>? = null,\n    var fileFormat: String? = null,\n    var ifNotExists: Boolean = false, // 是否存在 if not exists 关键字\n    var locationPath: String? = null,\n    val partitionColumnNames: ArrayList<String> = arrayListOf()\n) : AbsTableStatement() { // 是否存在 if exists 关键字\n    override val statementType = StatementType.CREATE_TABLE_AS_SELECT\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DDL\n\n    var replace = false\n    // 建表方式：hive & spark. https://spark.apache.org/docs/3.2.0/sql-ref-syntax-ddl-create-table.html\n    var modelType: String = \"hive\"\n    var partitionType: PartitionType? = null // 分区类型\n    var options: Map<String, String>? = null\n    var storageHandler: String? = null\n\n    constructor(\n        tableId: TableId,\n        queryStmt: QueryStmt\n    ) : this(tableId, queryStmt, null, null, null, null, null, null, false)\n\n    constructor(\n        tableId: TableId,\n        queryStmt: QueryStmt,\n        comment: String? = null,\n        ifNotExists: Boolean,\n        properties: Map<String, String>? = null\n    ) : this(tableId, queryStmt, comment, null, null, null, properties, null, ifNotExists)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateTableLike.kt",
    "content": "package io.github.melin.superior.common.relational.create\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class CreateTableLike(\n    val oldTableId: TableId,\n    override val tableId: TableId,\n    var ifNotExists: Boolean = false,\n    var external: Boolean = false,\n    var temporary: Boolean = false\n) : AbsTableStatement() {\n    override val statementType = StatementType.CREATE_TABLE_AS_LIKE\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DDL\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateView.kt",
    "content": "package io.github.melin.superior.common.relational.create\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport io.github.melin.superior.common.relational.table.ColumnRel\n\ndata class CreateView(\n    override val tableId: TableId,\n    var queryStmt: QueryStmt,\n    val comment: String? = null,\n    var ifNotExists: Boolean = false, // 是否存在 if not exists 关键字\n    var columnRels: List<ColumnRel>? = null\n) : AbsTableStatement() {\n    override val statementType = StatementType.CREATE_VIEW\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DDL\n\n    var replace: Boolean = false\n    var temporary: Boolean = false\n    var global: Boolean = false\n\n    var fileFormat: String? = null\n    var properties: Map<String, String> = mapOf()\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/delta/OptimizeTable.kt",
    "content": "package io.github.melin.superior.common.relational.delta\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class OptimizeTable(override val tableId: TableId) : AbsTableStatement() {\n    override val statementType = StatementType.OPTIMIZE_TABLE\n    override val privilegeType = PrivilegeType.WRITE\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/delta/VacuumTable.kt",
    "content": "package io.github.melin.superior.common.relational.delta\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class VacuumTable(override val tableId: TableId) : AbsTableStatement() {\n    override val statementType = StatementType.VACUUM_TABLE\n    override val privilegeType = PrivilegeType.WRITE\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/DeleteTable.kt",
    "content": "package io.github.melin.superior.common.relational.dml\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class DeleteTable(\n    override val tableId: TableId,\n    val inputTables: List<TableId>,\n) : AbsTableStatement() {\n    override val statementType = StatementType.DELETE\n    override val privilegeType = PrivilegeType.WRITE\n    override val sqlType = SqlType.DML\n\n    val outputTables: ArrayList<TableId> = arrayListOf()\n\n    init {\n        if (!outputTables.contains(tableId)) {\n            outputTables.add(tableId)\n        }\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/InsertFiles.kt",
    "content": "package io.github.melin.superior.common.relational.dml\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class InsertFiles(\n    val mode: InsertMode,\n    val queryStmt: QueryStmt,\n    var properties: Map<String, String>,\n) : Statement() {\n    override val statementType = StatementType.INSERT\n    override val privilegeType = PrivilegeType.WRITE\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/InsertMode.kt",
    "content": "package io.github.melin.superior.common.relational.dml\n\nimport java.io.Serializable\n\nenum class InsertMode : Serializable {\n    INTO,\n    INTO_REPLACE,\n    OVERWRITE,\n    OVERWRITE_HIVE_DIR,\n    OVERWRITE_DIR,\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/InsertMultiTable.kt",
    "content": "package io.github.melin.superior.common.relational.dml\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class InsertMultiTable(\n    val insertTables: List<InsertTable>,\n) : Statement() {\n    override val statementType = StatementType.UNKOWN\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/InsertTable.kt",
    "content": "package io.github.melin.superior.common.relational.dml\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\nimport io.github.melin.superior.common.relational.table.ColumnRel\nimport java.util.*\nimport kotlin.collections.ArrayList\nimport kotlin.collections.LinkedHashMap\n\ndata class InsertTable(\n    val mode: InsertMode,\n    val queryStmt: QueryStmt,\n    override val tableId: TableId,\n    var columnRels: List<ColumnRel>? = null,\n) : AbsTableStatement() {\n    override val statementType = StatementType.INSERT\n    override val privilegeType = PrivilegeType.WRITE\n    override val sqlType = SqlType.DML\n\n    var properties: Map<String, String>? = null\n    var fileFormat: String? = null\n    var partitionVals: LinkedHashMap<String, String>? = null\n    var rows: ArrayList<List<String>>? = null\n    val outputTables: ArrayList<TableId> = arrayListOf()\n    var hints: LinkedHashMap<String, LinkedList<String>>? = null\n\n    var mysqlReplace: Boolean = false\n\n    init {\n        if (!outputTables.contains(tableId)) {\n            outputTables.add(tableId)\n        }\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/MergeTable.kt",
    "content": "package io.github.melin.superior.common.relational.dml\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\n\ndata class MergeTable(\n    var targetTable: TableId,\n    var inputTables: List<TableId> = listOf(),\n) : Statement() {\n    override val statementType = StatementType.MERGE\n    override val privilegeType = PrivilegeType.WRITE\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/QueryStmt.kt",
    "content": "package io.github.melin.superior.common.relational.dml\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\n\ndata class QueryStmt(\n    var inputTables: List<TableId>,\n    var limit: Int? = null,\n    var offset: Int? = null,\n) : Statement() {\n    override val statementType = StatementType.SELECT\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DQL\n\n    val functionNames: HashSet<FunctionId> = hashSetOf()\n\n    constructor() : this(listOf())\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/UpdateTable.kt",
    "content": "package io.github.melin.superior.common.relational.dml\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class UpdateTable(\n    override val tableId: TableId,\n    var inputTables: List<TableId>,\n) : AbsTableStatement() {\n    override val statementType = StatementType.UPDATE\n    override val privilegeType = PrivilegeType.WRITE\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropCatalog.kt",
    "content": "package io.github.melin.superior.common.relational.drop\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\nclass DropCatalog(val catalogName: String) : Statement() {\n    override val statementType = StatementType.DROP_CATALOG\n    override val privilegeType = PrivilegeType.ADMIN\n    override val sqlType = SqlType.DDL\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropDatabase.kt",
    "content": "package io.github.melin.superior.common.relational.drop\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\nclass DropDatabase(val catalogName: String?, val databaseName: String, var ifExists: Boolean = false) : Statement() {\n    override val statementType = StatementType.DROP_DATABASE\n    override val privilegeType = PrivilegeType.DROP\n    override val sqlType = SqlType.DDL\n\n    val databaseNames: ArrayList<String> = arrayListOf()\n\n    constructor(databaseName: String) : this(null, databaseName)\n\n    constructor(databaseName: String, ifExists: Boolean) : this(null, databaseName, ifExists)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropFunction.kt",
    "content": "package io.github.melin.superior.common.relational.drop\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.Statement\n\ndata class DropFunction(val functionId: FunctionId) : Statement() {\n    override val statementType = StatementType.DROP_FUNCTION\n    override val privilegeType = PrivilegeType.DROP\n    override val sqlType = SqlType.DDL\n\n    var argumentTypes: List<String>? = null // starrocks\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropMaterializedView.kt",
    "content": "package io.github.melin.superior.common.relational.drop\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class DropMaterializedView(override val tableId: TableId, var ifExists: Boolean = false) : AbsTableStatement() {\n    override val statementType = StatementType.DROP_MATERIALIZED_VIEW\n    override val privilegeType = PrivilegeType.DROP\n    override val sqlType = SqlType.DDL\n\n    val tableIds: ArrayList<TableId> = arrayListOf()\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropProcedure.kt",
    "content": "package io.github.melin.superior.common.relational.drop\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.ProcedureId\nimport io.github.melin.superior.common.relational.Statement\n\ndata class DropProcedure(val procedureId: ProcedureId) : Statement() {\n    override val statementType = StatementType.DROP_PROCEDURE\n    override val privilegeType = PrivilegeType.DROP\n    override val sqlType = SqlType.DDL\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropSchema.kt",
    "content": "package io.github.melin.superior.common.relational.drop\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\nclass DropSchema(\n    val databaseName: String?,\n    val schemaName: String,\n) : Statement() {\n    override val statementType = StatementType.DROP_SCHEMA\n    override val privilegeType = PrivilegeType.DROP\n    override val sqlType = SqlType.DDL\n\n    constructor(schemaName: String) : this(null, schemaName)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropSequence.kt",
    "content": "package io.github.melin.superior.common.relational.drop\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class DropSequence(\n    override val tableId: TableId,\n    var ifExists: Boolean = false,\n    var isMaterialized: Boolean = false,\n) : AbsTableStatement() {\n    override val statementType = StatementType.DROP_SEQUENCE\n    override val privilegeType = PrivilegeType.DROP\n    override val sqlType = SqlType.DDL\n\n    val tableIds: ArrayList<TableId> = arrayListOf()\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropTable.kt",
    "content": "package io.github.melin.superior.common.relational.drop\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class DropTable(override val tableId: TableId, var ifExists: Boolean = false) : AbsTableStatement() {\n    override val statementType = StatementType.DROP_TABLE\n    override val privilegeType = PrivilegeType.DROP\n    override val sqlType = SqlType.DDL\n\n    val tableIds: ArrayList<TableId> = arrayListOf()\n    var force: Boolean = false\n    var purge: Boolean = false\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropView.kt",
    "content": "package io.github.melin.superior.common.relational.drop\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class DropView(override val tableId: TableId, var ifExists: Boolean = false) : AbsTableStatement() {\n    override val statementType = StatementType.DROP_VIEW\n    override val privilegeType = PrivilegeType.DROP\n    override val sqlType = SqlType.DDL\n\n    val tableIds: ArrayList<TableId> = arrayListOf()\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/enums.kt",
    "content": "package io.github.melin.superior.common.relational\n\nenum class SortType {\n    ASC,\n    DESC,\n    UNKOWN\n}\n\nenum class PartitionType {\n    RANGE,\n    LIST,\n    HASH,\n    KEY,\n    VALUES,\n    NORMAL,\n    EXPRESSION\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/io/AlterLoadTable.kt",
    "content": "package io.github.melin.superior.common.relational.io\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class AlterLoadTable(\n    val schemaName: String?,\n    val labelName: String,\n) : Statement() {\n    override val statementType = StatementType.ALTER_LOAD_TABLE\n    override val privilegeType = PrivilegeType.ALTER\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/io/CancelLoadTable.kt",
    "content": "package io.github.melin.superior.common.relational.io\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class CancelLoadTable(\n    val schemaName: String?,\n    val labelName: String,\n) : Statement() {\n    override val statementType = StatementType.CANCEL_LOAD_TABLE\n    override val privilegeType = PrivilegeType.DROP\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/io/ExportTable.kt",
    "content": "package io.github.melin.superior.common.relational.io\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class ExportTable(\n    override val tableId: TableId,\n    val path: String,\n    var properties: Map<String, String>,\n    var partitionVals: LinkedHashMap<String, String>,\n    var fileFormat: String? = null,\n    var compression: String? = null,\n    var maxFileSize: String? = null,\n    var overwrite: Boolean = false,\n    var single: Boolean = false,\n    var inputTables: ArrayList<TableId>,\n) : AbsTableStatement() {\n    override val statementType = StatementType.EXPORT_TABLE\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DML\n\n    val functionNames: HashSet<FunctionId> = hashSetOf()\n\n    constructor(\n        tableId: TableId,\n        path: String,\n        properties: Map<String, String>,\n    ) : this(tableId, path, properties, linkedMapOf(), null, null, null, false, false, arrayListOf())\n\n    constructor(\n        tableId: TableId,\n        path: String,\n        properties: Map<String, String>,\n        partitionVals: LinkedHashMap<String, String>,\n        fileFormat: String? = null,\n        compression: String? = null,\n        maxFileSize: String? = null,\n        overwrite: Boolean = false,\n        single: Boolean = false,\n    ) : this(\n        tableId,\n        path,\n        properties,\n        partitionVals,\n        fileFormat,\n        compression,\n        maxFileSize,\n        overwrite,\n        single,\n        arrayListOf()\n    )\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/io/LoadTable.kt",
    "content": "package io.github.melin.superior.common.relational.io\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class LoadTable(\n    val schemaName: String?,\n    val labelName: String,\n    val tableNames: List<String>,\n) : Statement() {\n    override val statementType = StatementType.LOAD_TABLE\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/table/ColumnRel.kt",
    "content": "package io.github.melin.superior.common.relational.table\n\ndata class ColumnRel(\n    val columnName: String,\n    val typeName: String? = null,\n    val comment: String? = null,\n    var nullable: Boolean = true,\n    var defaultExpr: String? = null,\n    var primaryKey: Boolean = false,\n    val columnDefType: ColumnDefType = ColumnDefType.COMPUTED\n) {\n    var columnLength = 0\n    var precision = 0\n    var scale = 0\n\n    var expression: String? = null // 计算表达式\n    var position: String? = null\n    var afterCol: String? = null\n    var jsonPath: String? = null // spark streaming sql json path\n\n    var computedExpr: String? = null // 计算列\n    var metadataKey: String? = null // 元数据列\n\n    constructor(\n        columnName: String,\n        typeName: String?,\n        comment: String?\n    ) : this(columnName, typeName, comment, true, null)\n\n    constructor(\n        columnName: String,\n        typeName: String?,\n        comment: String?,\n        primaryKey: Boolean = false,\n        columnDefType: ColumnDefType\n    ) : this(columnName, typeName, comment, true, null, primaryKey, columnDefType)\n\n    constructor(\n        columnName: String,\n        typeName: String?,\n        comment: String?,\n        columnDefType: ColumnDefType\n    ) : this(columnName, typeName, comment, true, null, false, columnDefType)\n}\n\nenum class ColumnDefType {\n    PHYSICAL,\n    METADATA,\n    COMPUTED\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/table/RepairTable.kt",
    "content": "package io.github.melin.superior.common.relational.table\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\nclass RepairTable(override val tableId: TableId) : AbsTableStatement() {\n    override val statementType = StatementType.REPAIR_TABLE\n    override val privilegeType = PrivilegeType.ADMIN\n    override val sqlType = SqlType.DDL\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/table/TruncateTable.kt",
    "content": "package io.github.melin.superior.common.relational.table\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\nclass TruncateTable(override val tableId: TableId, tableIds: ArrayList<TableId> = ArrayList()) : AbsTableStatement() {\n    override val statementType = StatementType.TRUNCATE_TABLE\n    override val privilegeType = PrivilegeType.WRITE\n    override val sqlType = SqlType.DDL\n\n    init {\n        tableIds.add(tableId)\n    }\n\n    constructor(tableIds: ArrayList<TableId>) : this(tableIds.first(), tableIds)\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/type/AbsDataTimeType.kt",
    "content": "package io.github.melin.superior.common.type\n\nabstract class AbsDataTimeType : AbsType() {}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/type/AbsNumericType.kt",
    "content": "package io.github.melin.superior.common.type\n\nabstract class AbsNumericType : AbsType() {\n    var character: String? = null\n    var collate: String? = null\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/type/AbsStringType.kt",
    "content": "package io.github.melin.superior.common.type\n\nabstract class AbsStringType : AbsType() {\n    var character: String? = null\n    var collate: String? = null\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/type/AbsType.kt",
    "content": "package io.github.melin.superior.common.type\n\nabstract class AbsType : Type {\n    override val alias: String? = null\n    override val alias2: String? = null\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/type/Type.kt",
    "content": "package io.github.melin.superior.common.type\n\ninterface Type {\n    val name: String\n    val alias: String?\n    val alias2: String? // 有些有多个别名，例如mysql integer有int 和 int4 两种\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/util/CommonUtils.kt",
    "content": "package com.github.melin.superior.sql.parser.util\n\nimport org.antlr.v4.runtime.ParserRuleContext\nimport org.antlr.v4.runtime.Token\nimport org.antlr.v4.runtime.tree.ParseTree\nimport org.antlr.v4.runtime.tree.TerminalNodeImpl\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2017/4/10. */\nobject CommonUtils {\n\n    val KEYWORD_REGEX = \"'([A-Z_]+)'\".toRegex()\n\n    fun findShowStatementKeyWord(keyWords: ArrayList<String>, node: ParseTree) {\n        if (node is TerminalNodeImpl) {\n            val count = node.parent.childCount\n            for (i in 0 until count) {\n                val child = node.parent.getChild(i)\n                if (child is TerminalNodeImpl) {\n                    keyWords.add(child.text.uppercase())\n                }\n            }\n        } else {\n            findShowStatementKeyWord(keyWords, node.getChild(0))\n        }\n    }\n\n    fun subsql(sql: String?, context: ParserRuleContext): String {\n        val currSql = StringUtils.substring(sql, context.start.startIndex, context.stop.stopIndex + 1)\n        return cleanLastSemi(currSql)\n    }\n\n    fun subsql(sql: String?, start: Token, stop: Token): String {\n        val currSql = StringUtils.substring(sql, start.stopIndex + 1, stop.stopIndex + 1)\n        return cleanLastSemi(currSql)\n    }\n\n    private fun cleanLastSemi(text: String): String {\n        if (StringUtils.endsWith(text, \";\")) {\n            return StringUtils.substring(text, 0, text.length - 1)\n        }\n\n        return text\n    }\n\n    fun cleanQuote(value: String): String {\n        if (StringUtils.isBlank(value)) {\n            return value\n        }\n\n        var result = value\n        if (StringUtils.startsWith(result, \"'\") && StringUtils.endsWith(result, \"'\")) {\n            result = StringUtils.substring(result, 1, -1)\n        }\n\n        if (StringUtils.startsWith(result, \"\\\"\") && StringUtils.endsWith(result, \"\\\"\")) {\n            result = StringUtils.substring(result, 1, -1)\n        }\n\n        if (StringUtils.startsWith(value, \"`\") && StringUtils.endsWith(value, \"`\")) {\n            return StringUtils.substring(value, 1, -1)\n        }\n\n        return StringUtils.trim(result)\n    }\n}\n"
  },
  {
    "path": "superior-common-parser/src/main/kotlin/io/github/melin/superior/common/util/DateUtils.kt",
    "content": "package com.github.melin.superior.sql.parser.util\n\nimport java.time.DateTimeException\nimport java.time.LocalDateTime\nimport java.time.ZoneId\nimport java.time.format.DateTimeFormatter\nimport java.util.*\n\nobject DateUtils {\n    fun getCurrentDateTime(): String {\n        try {\n            val ldt = LocalDateTime.ofInstant(Date().toInstant(), ZoneId.systemDefault())\n            val format = DateTimeFormatter.ofPattern(\"yyyyMMddHHmmssSSS\")\n            return ldt.format(format)\n        } catch (ex: DateTimeException) {\n            throw RuntimeException(ex.message, ex)\n        }\n    }\n}\n"
  },
  {
    "path": "superior-dameng-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-dameng-parser</artifactId>\n    <name>superior-dameng-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "superior-dameng-parser/src/main/antlr4/io/github/melin/superior/parser/dameng/antlr4/DmSqlLexer.g4",
    "content": "lexer grammar DmSqlLexer;\n\n\n// Keywords\n\nABORT:                                 'ABORT';\nABSOLUTE:                              'ABSOLUTE';\nABSTRACT:                              'ABSTRACT';\nACCESSED:                              'ACCESSED';\nACCOUNT:                               'ACCOUNT';\nACROSS:                                'ACROSS';\nACTION:                                'ACTION';\nADD:                                   'ADD';\nADMIN:                                 'ADMIN';\nADVANCED:                              'ADVANCED';\nAFTER:                                 'AFTER';\nAGGREGATE:                             'AGGREGATE';\nALL:                                   'ALL';\nALLOW_DATETIME:                        'ALLOW_DATETIME';\nALLOW_IP:                              'ALLOW_IP';\nALTER:                                 'ALTER';\nALWAYS:                                'ALWAYS';\nANALYZE:                               'ANALYZE';\nAND:                                   'AND';\nANY:                                   'ANY';\nAPPLY:                                 'APPLY';\nAPR:                                   'APR';\nARCHIVE:                               'ARCHIVE';\nARCHIVEDIR:                            'ARCHIVEDIR';\nARCHIVELOG:                            'ARCHIVELOG';\nARCHIVESTYLE:                          'ARCHIVESTYLE';\nARRAY:                                 'ARRAY';\nARRAYLEN:                              'ARRAYLEN';\nAS:                                    'AS';\nASC:                                   'ASC';\nASCII:                                 'ASCII';\nASENSITIVE:                            'ASENSITIVE';\nASSIGN:                                'ASSIGN';\nASYNCHRONOUS:                          'ASYNCHRONOUS';\nATTACH:                                'ATTACH';\nAT_KEYWORD:                            'AT';\nAUDIT:                                 'AUDIT';\nAUG:                                   'AUG';\nAUTHID:                                'AUTHID';\nAUTHORIZATION:                         'AUTHORIZATION';\nAUTO:                                  'AUTO';\nAUTOEXTEND:                            'AUTOEXTEND';\nAUTONOMOUS_TRANSACTION:                'AUTONOMOUS_TRANSACTION';\nAUTO_INCREMENT:                        'AUTO_INCREMENT';\nAUTO_UPDATE:                           'AUTO_UPDATE';\nAVG:                                   'AVG';\nBACKED:                                'BACKED';\nBACKUP:                                'BACKUP';\nBACKUPDIR:                             'BACKUPDIR';\nBACKUPINFO:                            'BACKUPINFO';\nBACKUPSET:                             'BACKUPSET';\nBADFILE:                               'BADFILE';\nBAKFILE:                               'BAKFILE';\nBASE:                                  'BASE';\nBATCH:                                 'BATCH';\nBEFORE:                                'BEFORE';\nBEGIN:                                 'BEGIN';\nBETWEEN:                               'BETWEEN';\nBIGDATEDIFF:                           'BIGDATEDIFF';\nBIGINT:                                'BIGINT';\nBINARY_KEYWORD:                        'BINARY';\nBIT:                                   'BIT';\nBITMAP:                                'BITMAP';\nBLOB:                                  'BLOB';\nBLOCK:                                 'BLOCK';\nBODY:                                  'BODY';\nBOOL:                                  'BOOL';\nBOOLEAN:                               'BOOLEAN';\nBOTH:                                  'BOTH';\nBRANCH:                                'BRANCH';\nBREADTH:                               'BREADTH';\nBREAK:                                 'BREAK';\nBSTRING:                               'BSTRING';\nBTREE:                                 'BTREE';\nBUFFER:                                'BUFFER';\nBUILD:                                 'BUILD';\nBULK:                                  'BULK';\nBULK_EXCEPTION:                        'BULK_EXCEPTION';\nBULK_ROWCOUNT:                         'BULK_ROWCOUNT';\nBY:                                    'BY';\nBYDAY:                                 'BYDAY';\nBYHOUR:                                'BYHOUR';\nBYMINUTE:                              'BYMINUTE';\nBYMONTH:                               'BYMONTH';\nBYMONTHDAY:                            'BYMONTHDAY';\nBYSECOND:                              'BYSECOND';\nBYTE:                                  'BYTE';\nBYWEEKNO:                              'BYWEEKNO';\nBYYEARDAY:                             'BYYEARDAY';\nCACHE:                                 'CACHE';\nCALCULATE:                             'CALCULATE';\nCALL:                                  'CALL';\nCASCADE:                               'CASCADE';\nCASCADED:                              'CASCADED';\nCASE:                                  'CASE';\nCASE_SENSITIVE:                        'CASE_SENSITIVE';\nCAST:                                  'CAST';\nCATALOG:                               'CATALOG';\nCATCH:                                 'CATCH';\nCHAIN:                                 'CHAIN';\nCHANGE:                                'CHANGE';\nCHAR:                                  'CHAR';\nCHARACTER:                             'CHARACTER';\nCHARACTERISTICS:                       'CHARACTERISTICS';\nCHECK:                                 'CHECK';\nCHECKPOINT:                            'CHECKPOINT';\nCIPHER:                                'CIPHER';\nCLASS:                                 'CLASS';\nCLOB:                                  'CLOB';\nCLOSE:                                 'CLOSE';\nCLUSTER:                               'CLUSTER';\nCLUSTERBTR:                            'CLUSTERBTR';\nCOLLATE:                               'COLLATE';\nCOLLATION:                             'COLLATION';\nCOLLECT:                               'COLLECT';\nCOLUMN:                                'COLUMN';\nCOLUMNS:                               'COLUMNS';\nCOMMENT:                               'COMMENT';\nCOMMIT:                                'COMMIT';\nCOMMITTED:                             'COMMITTED';\nCOMMITWORK:                            'COMMITWORK';\nCOMPILE:                               'COMPILE';\nCOMPLETE:                              'COMPLETE';\nCOMPRESS:                              'COMPRESS';\nCOMPRESSED:                            'COMPRESSED';\nCONDITIONAL:                           'CONDITIONAL';\nCONNECT:                               'CONNECT';\nCONNECT_BY_IS_CYCLE:                   'CONNECT_BY_IS_CYCLE';\nCONNECT_BY_IS_LEAF:                    'CONNECT_BY_IS_LEAF';\nCONNECT_BY_ROOT:                       'CONNECT_BY_ROOT';\nCONNECT_IDLE_TIME:                     'CONNECT_IDLE_TIME';\nCONNECT_TIME:                          'CONNECT_TIME';\nCONST:                                 'CONST';\nCONSTANT:                              'CONSTANT';\nCONSTRAINT:                            'CONSTRAINT';\nCONSTRAINTS:                           'CONSTRAINTS';\nCONSTRUCTOR:                           'CONSTRUCTOR';\nCONSTR_OP:                             'CONSTR_OP';\nCONTAINS:                              'CONTAINS';\nCONTEXT:                               'CONTEXT';\nCONTINUE:                              'CONTINUE';\nCONVERT:                               'CONVERT';\nCOPY:                                  'COPY';\nCORRESPONDING:                         'CORRESPONDING';\nCORRUPT:                               'CORRUPT';\nCOUNT:                                 'COUNT';\nCOUNTER:                               'COUNTER';\nCPU_PER_CALL:                          'CPU_PER_CALL';\nCPU_PER_SESSION:                       'CPU_PER_SESSION';\nCREATE:                                'CREATE';\nCROSS:                                 'CROSS';\nCRYPTO:                                'CRYPTO';\nCTLFILE:                               'CTLFILE';\nCUBE:                                  'CUBE';\nCUMULATIVE:                            'CUMULATIVE';\nCURRENT:                               'CURRENT';\nCURRENT_SCHEMA:                        'CURRENT_SCHEMA';\nCURRENT_USER:                          'CURRENT_USER';\nCURSOR:                                'CURSOR';\nCYCLE:                                 'CYCLE';\nDAILY:                                 'DAILY';\nDANGLING:                              'DANGLING';\nDATA:                                  'DATA';\nDATABASE:                              'DATABASE';\nDATAFILE:                              'DATAFILE';\nDATE:                                  'DATE';\nDATEADD:                               'DATEADD';\nDATEDIFF:                              'DATEDIFF';\nDATEPART:                              'DATEPART';\nDATETIME:                              'DATETIME';\nDAY:                                   'DAY';\nDBFILE:                                'DBFILE';\nDDL:                                   'DDL';\nDDL_CLONE:                             'DDL_CLONE';\nDEBUG:                                 'DEBUG';\nDEC:                                   'DEC';\nDECIMAL:                               'DECIMAL';\nDECLARE:                               'DECLARE';\nDECODE:                                'DECODE';\nDEFAULT:                               'DEFAULT';\nDEFERRABLE:                            'DEFERRABLE';\nDEFERRED:                              'DEFERRED';\nDEFINER:                               'DEFINER';\nDELETE:                                'DELETE';\nDELETING:                              'DELETING';\nDELIMITED:                             'DELIMITED';\nDELTA:                                 'DELTA';\nDEMAND:                                'DEMAND';\nDENSE_RANK:                            'DENSE_RANK';\nDEPTH:                                 'DEPTH';\nDEREF:                                 'DEREF';\nDESC:                                  'DESC';\nDETACH:                                'DETACH';\nDETERMINISTIC:                         'DETERMINISTIC';\nDEVICE:                                'DEVICE';\nDIAGNOSTICS:                           'DIAGNOSTICS';\nDICTIONARY:                            'DICTIONARY';\nDIRECTORY:                             'DIRECTORY';\nDISABLE:                               'DISABLE';\nDISCONNECT:                            'DISCONNECT';\nDISKGROUP:                             'DISKGROUP';\nDISKSPACE:                             'DISKSPACE';\nDISTINCT:                              'DISTINCT';\nDISTRIBUTED:                           'DISTRIBUTED';\nDML:                                   'DML';\nDO:                                    'DO';\nDOMAIN:                                'DOMAIN';\nDOUBLE:                                'DOUBLE';\nDOWN:                                  'DOWN';\nDROP:                                  'DROP';\nDUMP:                                  'DUMP';\nEACH:                                  'EACH';\nEDITIONABLE:                           'EDITIONABLE';\nELSE:                                  'ELSE';\nELSEIF:                                ('ELSEIF' | 'ELSIF');\nEMPTY:                                 'EMPTY';\nENABLE:                                'ENABLE';\nENCRYPT:                               'ENCRYPT';\nENCRYPTION:                            'ENCRYPTION';\nEND:                                   'END';\nEQU:                                   'EQU';\nERROR:                                 'ERROR';\nERRORS:                                'ERRORS';\nESCAPE:                                'ESCAPE';\nEVALNAME:                              'EVALNAME';\nEVENTINFO:                             'EVENTINFO';\nEVENTS:                                'EVENTS';\nEVERY:                                 'EVERY';\nEXCEPT:                                'EXCEPT';\nEXCEPTION:                             'EXCEPTION';\nEXCEPTIONS:                            'EXCEPTIONS';\nEXCEPTION_INIT:                        'EXCEPTION_INIT';\nEXCHANGE:                              'EXCHANGE';\nEXCLUDE:                               'EXCLUDE';\nEXCLUDING:                             'EXCLUDING';\nEXCLUSIVE:                             'EXCLUSIVE';\nEXECUTE:                               'EXECUTE';\nEXISTS:                                'EXISTS';\nEXIT:                                  'EXIT';\nEXPIRE:                                'EXPIRE';\nEXPLAIN:                               'EXPLAIN';\nEXTENDS:                               'EXTENDS';\nEXTERN:                                'EXTERN';\nEXTERNAL:                              'EXTERNAL';\nEXTERNALLY:                            'EXTERNALLY';\nEXTRACT:                               'EXTRACT';\nFAILED_LOGIN_ATTEMPS:                  'FAILED_LOGIN_ATTEMPS';\nFAILED_LOGIN_ATTEMPTS:                 'FAILED_LOGIN_ATTEMPTS';\nFALSE:                                 'FALSE';\nFAST:                                  'FAST';\nFEB:                                   'FEB';\nFETCH:                                 'FETCH';\nFIELDS:                                'FIELDS';\nFILE:                                  'FILE';\nFILEGROUP:                             'FILEGROUP';\nFILESIZE:                              'FILESIZE';\nFILLFACTOR:                            'FILLFACTOR';\nFINAL:                                 'FINAL';\nFINALLY:                               'FINALLY';\nFIRST:                                 'FIRST';\nFLASHBACK:                             'FLASHBACK';\nFLOAT:                                 'FLOAT';\nFOLLOWING:                             'FOLLOWING';\nFOR:                                   'FOR';\nFORALL:                                'FORALL';\nFORCE:                                 'FORCE';\nFOREIGN:                               'FOREIGN';\nFORMAT:                                'FORMAT';\nFOUND:                                 'FOUND';\nFREQ:                                  'FREQ';\nFREQUENCE:                             'FREQUENCE';\nFRI:                                   'FRI';\nFROM:                                  'FROM';\nFULL:                                  'FULL';\nFULLY:                                 'FULLY';\nFUNCTION:                              'FUNCTION';\nGENERATE:                              'GENERATE';\nGENERATED:                             'GENERATED';\nGET:                                   'GET';\nGLOBAL:                                'GLOBAL';\nGLOBALLY:                              'GLOBALLY';\nGOTO:                                  'GOTO';\nGRANT:                                 'GRANT';\nGREAT:                                 'GREAT';\nGROUP:                                 'GROUP';\nGROUPING:                              'GROUPING';\nHASH:                                  'HASH';\nHASHPARTMAP:                           'HASHPARTMAP';\nHAVING:                                'HAVING';\nHEXTORAW:                              'HEXTORAW';\nHIDDEN_KEYWORD:                        'HIDDEN';\nHIGH:                                  'HIGH';\nHOLD:                                  'HOLD';\nHOUR:                                  'HOUR';\nHOURLY:                                'HOURLY';\nHUGE:                                  'HUGE';\nIDENTIFIED:                            'IDENTIFIED';\nIDENTIFIER_KEYWORD:                    'IDENTIFIER';\nIDENTITY:                              'IDENTITY';\nIDENTITY_INSERT:                       'IDENTITY_INSERT';\nIF:                                    'IF';\nIFNULL:                                'IFNULL';\nIGNORE:                                'IGNORE';\nIGNORE_ROW_ON_DUPKEY_INDEX:            'IGNORE_ROW_ON_DUPKEY_INDEX';\nIMAGE:                                 'IMAGE';\nIMMEDIATE:                             'IMMEDIATE';\nIN:                                    'IN';\nINCLUDE:                               'INCLUDE';\nINCLUDING:                             'INCLUDING';\nINCREASE:                              'INCREASE';\nINCREMENT:                             'INCREMENT';\nINDEX:                                 'INDEX';\nINDEXES:                               'INDEXES';\nINDICES:                               'INDICES';\nINITIAL:                               'INITIAL';\nINITIALIZED:                           'INITIALIZED';\nINITIALLY:                             'INITIALLY';\nINLINE:                                'INLINE';\nINNER:                                 'INNER';\nINNERID:                               'INNERID';\nINPUT:                                 'INPUT';\nINSENSITIVE:                           'INSENSITIVE';\nINSERT:                                'INSERT';\nINSERTING:                             'INSERTING';\nINSTANCE:                              'INSTANCE';\nINSTANTIABLE:                          'INSTANTIABLE';\nINSTEAD:                               'INSTEAD';\nINT:                                   'INT';\nINTEGER:                               'INTEGER';\nINTENT:                                'INTENT';\nINTERSECT:                             'INTERSECT';\nINTERVAL:                              'INTERVAL';\nINTO:                                  'INTO';\nINVISIBLE:                             'INVISIBLE';\nIS:                                    'IS';\nISOLATION:                             'ISOLATION';\nJAN:                                   'JAN';\nJAVA:                                  'JAVA';\nJOB:                                   'JOB';\nJOIN:                                  'JOIN';\nJSON:                                  'JSON';\nJSON_TABLE:                            'JSON_TABLE';\nJUL:                                   'JUL';\nJUN:                                   'JUN';\nKEEP:                                  'KEEP';\nKEY:                                   'KEY';\nKEYS:                                  'KEYS';\nLABEL:                                 'LABEL';\nLARGE:                                 'LARGE';\nLAST:                                  'LAST';\nLAST2:                                 'LAST2';\nLAX:                                   'LAX';\nLEAD:                                  'LEADING';\nLEFT:                                  'LEFT';\nLEFTARG:                               'LEFTARG';\nLESS:                                  'LESS';\nLEVEL:                                 'LEVEL';\nLEVELS:                                'LEVELS';\nLEXER:                                 'LEXER';\nLIKE:                                  'LIKE';\nLIMIT:                                 'LIMIT';\nLINK:                                  'LINK';\nLIST:                                  'LIST';\nLNNVL:                                 'LNNVL';\nLOB:                                   'LOB';\nLOCAL:                                 'LOCAL';\nLOCALLY:                               'LOCALLY';\nLOCAL_OBJECT:                          'LOCAL_OBJECT';\nLOCATION:                              'LOCATION';\nLOCK:                                  'LOCK';\nLOCKED:                                'LOCKED';\nLOG:                                   'LOG';\nLOGFILE:                               'LOGFILE';\nLOGGING:                               'LOGGING';\nLOGIC:                                 'LOGIC';\nLOGIN:                                 'LOGIN';\nLOGOFF:                                'LOGOFF';\nLOGON:                                 'LOGON';\nLOGOUT:                                'LOGOUT';\nLONG:                                  'LONG';\nLONGVARBINARY:                         'LONGVARBINARY';\nLONGVARCHAR:                           'LONGVARCHAR';\nLOOP:                                  'LOOP';\nLSN:                                   'LSN';\nMANUAL:                                'MANUAL';\nMAP:                                   'MAP';\nMAPPED:                                'MAPPED';\nMAR:                                   'MAR';\nMATCH:                                 'MATCH';\nMATCHED:                               'MATCHED';\nMATERIALIZED:                          'MATERIALIZED';\nMAX:                                   'MAX';\nMAXPIECESIZE:                          'MAXPIECESIZE';\nMAXSIZE:                               'MAXSIZE';\nMAXVALUE:                              'MAXVALUE';\nMAX_RUN_DURATION:                      'MAX_RUN_DURATION';\nMAY:                                   'MAY';\nMEMBER:                                'MEMBER';\nMEMORY:                                'MEMORY';\nMEM_SPACE:                             'MEM_SPACE';\nMERGE:                                 'MERGE';\nMICRO:                                 'MICRO';\nMIN:                                   'MIN';\nMINEXTENTS:                            'MINEXTENTS';\nMINUS:                                 'MINUS';\nMINUTE:                                'MINUTE';\nMINUTELY:                              'MINUTELY';\nMINVALUE:                              'MINVALUE';\nMIRROR:                                'MIRROR';\nMOD:                                   'MOD';\nMODE:                                  'MODE';\nMODIFY:                                'MODIFY';\nMON:                                   'MON';\nMONEY:                                 'MONEY';\nMONITORING:                            'MONITORING';\nMONTH:                                 'MONTH';\nMONTHLY:                               'MONTHLY';\nMOUNT:                                 'MOUNT';\nMOVE:                                  'MOVE';\nMOVEMENT:                              'MOVEMENT';\nMULTISET:                              'MULTISET';\nNATIONAL:                              'NATIONAL';\nNATURAL:                               'NATURAL';\nNCHAR:                                 'NCHAR';\nNCHARACTER:                            'NCHARACTER';\nNESTED_PATH:                           'NESTED_PATH';\nNEVER:                                 'NEVER';\nNEW:                                   'NEW';\nNEXT:                                  'NEXT';\nNO:                                    'NO';\nNOARCHIVELOG:                          'NOARCHIVELOG';\nNOAUDIT:                               'NOAUDIT';\nNOBRANCH:                              'NOBRANCH';\nNOCACHE:                               'NOCACHE';\nNOCOPY:                                'NOCOPY';\nNOCYCLE:                               'NOCYCLE';\nNODE:                                  'NODE';\nNOLOCK:                                'NOLOCK';\nNOLOGGING:                             'NOLOGGING';\nNOMAXVALUE:                            'NOMAXVALUE';\nNOMINVALUE:                            'NOMINVALUE';\nNOMONITORING:                          'NOMONITORING';\nNONE:                                  'NONE';\nNONEDITIONABLE:                        'NONEDITIONABLE';\nNOORDER:                               'NOORDER';\nNOPARALLEL:                            'NOPARALLEL';\nNORMAL:                                'NORMAL';\nNOROWDEPENDENCIES:                     'NOROWDEPENDENCIES';\nNOSORT:                                'NOSORT';\nNOT:                                   'NOT';\nNOTFOUND:                              'NOT_FOUND';\nNOT_ALLOW_DATETIME:                    'NOT_ALLOW_DATETIME';\nNOT_ALLOW_IP:                          'NOT_ALLOW_IP';\nNOV:                                   'NOV';\nNOVALIDATE:                            'NOVALIDATE';\nNOWAIT:                                'NOWAIT';\nNULL:                                  'NULL';\nNULLS:                                 'NULLS';\nNUMBER:                                'NUMBER';\nNUMERIC:                               'NUMERIC';\nOBJECT:                                'OBJECT';\nOCT:                                   'OCT';\nOF:                                    'OF';\nOFF:                                   'OFF';\nOFFLINE:                               'OFFLINE';\nOFFSET:                                'OFFSET';\nOIDINDEX:                              'OIDINDEX';\nOLD:                                   'OLD';\nON:                                    'ON';\nONCE:                                  'ONCE';\nONLINE:                                'ONLINE';\nONLY:                                  'ONLY';\nOPEN:                                  'OPEN';\nOPERATOR:                              'OPERATOR';\nOPTIMIZE:                              'OPTIMIZE';\nOPTION:                                'OPTION';\nOR:                                    'OR';\nORDER:                                 'ORDER';\nORDINALITY:                            'ORDINALITY';\nOUT:                                   'OUT';\nOUTER:                                 'OUTER';\nOVER:                                  'OVER';\nOVERLAPS:                              'OVERLAPS';\nOVERLAY:                               'OVERLAY';\nOVERRIDE:                              'OVERRIDE';\nOVERRIDING:                            'OVERRIDING';\nPACKAGE:                               'PACKAGE';\nPAD:                                   'PAD';\nPAGE:                                  'PAGE';\nPARALLEL:                              'PARALLEL';\nPARALLEL_ENABLE:                       'PARALLEL_ENABLE';\nPARMS:                                 'PARMS';\nPARTIAL:                               'PARTIAL';\nPARTITION:                             'PARTITION';\nPARTITIONS:                            'PARTITIONS';\nPASSING:                               'PASSING';\nPASSWORD:                              'PASSWORD';\nPASSWORD_GRACE_TIME:                   'PASSWORD_GRACE_TIME';\nPASSWORD_LIFE_TIME:                    'PASSWORD_LIFE_TIME';\nPASSWORD_LOCK_TIME:                    'PASSWORD_LOCK_TIME';\nPASSWORD_POLICY:                       'PASSWORD_POLICY';\nPASSWORD_REUSE_MAX:                    'PASSWORD_REUSE_MAX';\nPASSWORD_REUSE_TIME:                   'PASSWORD_REUSE_TIME';\nPATH:                                  'PATH';\nPENDANT:                               'PENDANT';\nPERCENT:                               'PERCENT';\nPIPE:                                  'PIPE';\nPIPELINED:                             'PIPELINED';\nPIVOT:                                 'PIVOT';\nPLACING:                               'PLACING';\nPRAGMA:                                'PRAGMA';\nPREBUILT:                              'PREBUILT';\nPRECEDING:                             'PRECEDING';\nPRECISION:                             'PRECISION';\nPRESERVE:                              'PRESERVE';\nPRETTY:                                'PRETTY';\nPRIMARY:                               'PRIMARY';\nPRINT:                                 'PRINT';\nPRIOR:                                 'PRIOR';\nPRIVATE:                               'PRIVATE';\nPRIVILEGE:                             'PRIVILEGE';\nPRIVILEGES:                            'PRIVILEGES';\nPROCEDURE:                             'PROCEDURE';\nPROFILE:                               'PROFILE';\nPROTECTED:                             'PROTECTED';\nPT_BULK_ROWCOUNT:                      'PT_BULK_ROWCOUNT';\nPT_ROWCOUNT:                           'PT_ROWCOUNT';\nPT_ROWCOUNT2:                          'PT_ROWCOUNT2';\nPUBLIC:                                'PUBLIC';\nPURGE:                                 'PURGE';\nQUERY:                                 'QUERY';\nQUERY_REWRITE_INTEGRITY:               'QUERY_REWRITE_INTEGRITY';\nQUOTA:                                 'QUOTA';\nRAISE:                                 'RAISE';\nRANDOMLY:                              'RANDOMLY';\nRANGE:                                 'RANGE';\nRAWTOHEX:                              'RAWTOHEX';\nREAD:                                  'READ';\nREADONLY:                              'READONLY';\nREAD_PER_CALL:                         'READ_PER_CALL';\nREAD_PER_SESSION:                      'READ_PER_SESSION';\nREAL:                                  'REAL';\nREBUILD:                               'REBUILD';\nRECORD:                                'RECORD';\nRECORDS:                               'RECORDS';\nRECURSIVE:                             'RECURSIVE';\nREDUCED:                               'REDUCED';\nREF:                                   'REF';\nREFERENCE:                             'REFERENCE';\nREFERENCES:                            'REFERENCES';\nREFERENCING:                           'REFERENCING';\nREFRESH:                               'REFRESH';\nREJECT:                                'REJECT';\nRELATED:                               'RELATED';\nRELATIVE:                              'RELATIVE';\nRENAME:                                'RENAME';\nREPEAT:                                'REPEAT';\nREPEATABLE:                            'REPEATABLE';\nREPLACE:                               'REPLACE';\nREPLAY:                                'REPLAY';\nREPLICATE:                             'REPLICATE';\nRESPECT:                               'RESPECT';\nRESIZE:                                'RESIZE';\nRESTORE:                               'RESTORE';\nRESTRICT:                              'RESTRICT';\nRESTRICT_REFERENCES:                   'RESTRICT_REFERENCES';\nRESULT:                                'RESULT';\nRESULT_CACHE:                          'RESULT_CACHE';\nRETURN:                                'RETURN';\nRETURNING:                             'RETURNING';\nREUSE:                                 'REUSE';\nREVERSE:                               'REVERSE';\nREVOKE:                                'REVOKE';\nREWRITE:                               'REWRITE';\nRIGHT:                                 'RIGHT';\nRIGHTARG:                              'RIGHTARG';\nROLE:                                  'ROLE';\nROLLBACK:                              'ROLLBACK';\nROLLFILE:                              'ROLLFILE';\nROLLUP:                                'ROLLUP';\nROOT:                                  'ROOT';\nROW:                                   'ROW';\nROWCOUNT:                              'ROWCOUNT';\nROWCOUNT2:                             'ROWCOUNT2';\nROWDEPENDENCIES:                       'ROWDEPENDENCIES';\nROWID:                                 'ROWID';\nROWNUM:                                'ROWNUM';\nROWS:                                  'ROWS';\nROWTYPE:                               'ROWTYPE';\nRULE:                                  'RULE';\nSALT:                                  'SALT';\nSAMPLE:                                'SAMPLE';\nSAT:                                   'SAT';\nSAVE:                                  'SAVE';\nSAVEPOINT:                             'SAVEPOINT';\nSBYTE:                                 'SBYTE';\nSCHEMA:                                'SCHEMA';\nSCHEMABINDING:                         'SCHEMABINDING';\nSCN:                                   'SCN';\nSCOPE:                                 'SCOPE';\nSCROLL:                                'SCROLL';\nSEALED:                                'SEALED';\nSEARCH:                                'SEARCH';\nSECOND:                                'SECOND';\nSECONDLY:                              'SECONDLY';\nSECTION:                               'SECTION';\nSEED:                                  'SEED';\nSELECT:                                'SELECT';\nSELF:                                  'SELF';\nSENSITIVE:                             'SENSITIVE';\nSEP:                                   'SEP';\nSEQUENCE:                              'SEQUENCE';\nSERERR:                                'SERERR';\nSERIALIZABLE:                          'SERIALIZABLE';\nSERVER:                                'SERVER';\nSESSION:                               'SESSION';\nSESSION_PER_USER:                      'SESSION_PER_USER';\nSET:                                   'SET';\nSETS:                                  'SETS';\nSHADOW:                                'SHADOW';\nSHARE:                                 'SHARE';\nSHORT:                                 'SHORT';\nSHUTDOWN:                              'SHUTDOWN';\nSIBLINGS:                              'SIBLINGS';\nSIMPLE:                                'SIMPLE';\nSINCE:                                 'SINCE';\nSIZE:                                  'SIZE';\nSIZEOF:                                'SIZEOF';\nSKIP_KEYWORD:                          'SKIP';\nSMALLINT:                              'SMALLINT';\nSNAPSHOT:                              'SNAPSHOT';\nSOME:                                  'SOME';\nSOUND:                                 'SOUND';\nSPACE_KEYWORD:                         'SPACE';\nSPAN:                                  'SPAN';\nSPATIAL:                               'SPATIAL';\nSPEED:                                 'SPEED';\nSPFILE:                                'SPFILE';\nSPLIT:                                 'SPLIT';\nSQL:                                   'SQL';\nSTANDBY:                               'STANDBY';\nSTART:                                 'START';\nSTARTUP:                               'STARTUP';\nSTAT:                                  'STAT';\nSTATEMENT:                             'STATEMENT';\nSTATIC:                                'STATIC';\nSTDDEV:                                'STDDEV';\nSTOP:                                  'STOP';\nSTORAGE:                               'STORAGE';\nSTORE:                                 'STORE';\nSTRICT:                                'STRICT';\nSTRING:                                'STRING';\nSTRIPING:                              'STRIPING';\nSTRUCT:                                'STRUCT';\nSTYLE:                                 'STYLE';\nSUBPARTITION:                          'SUBPARTITION';\nSUBPARTITIONS:                         'SUBPARTITIONS';\nSUBSCRIBE:                             'SUBSCRIBE';\nSUBSTITUTABLE:                         'SUBSTITUTABLE';\nSUBSTRING:                             'SUBSTRING';\nSUBTYPE:                               'SUBTYPE';\nSUCCESSFUL:                            'SUCCESSFUL';\nSUM:                                   'SUM';\nSUN:                                   'SUN';\nSUSPEND:                               'SUSPEND';\nSWITCH:                                'SWITCH';\nSYNC:                                  'SYNC';\nSYNCHRONOUS:                           'SYNCHRONOUS';\nSYNONYM:                               'SYNONYM';\nSYSTEM:                                'SYSTEM';\nSYS_CONNECT_BY_PATH:                   'SYS_CONNECT_BY_PATH';\nTABLE:                                 'TABLE';\nTABLESPACE:                            'TABLESPACE';\nTABLESPACESET:                         'TABLESPACESET';\nTASK:                                  'TASK';\nTEMPLATE:                              'TEMPLATE';\nTEMPORARY:                             'TEMPORARY';\nTEXT:                                  'TEXT';\nTHAN:                                  'THAN';\nTHEN:                                  'THEN';\nTHREAD:                                'THREAD';\nTHROUGH:                               'THROUGH';\nTHROW:                                 'THROW';\nTHU:                                   'THU';\nTIES:                                  'TIES';\nTIME:                                  'TIME';\nTIMER:                                 'TIMER';\nTIMES:                                 'TIMES';\nTIMESTAMP:                             'TIMESTAMP';\nTIMESTAMPADD:                          'TIMESTAMPADD';\nTIMESTAMPDIFF:                         'TIMESTAMPDIFF';\nTIME_ZONE:                             'TIME_ZONE';\nTINYINT:                               'TINYINT';\nTO:                                    'TO';\nTOP:                                   'TOP';\nTRACE:                                 'TRACE';\nTRACKING:                              'TRACKING';\nTRAIL:                                 'TRAILING';\nTRANSACTION:                           'TRANSACTION';\nTRANSACTIONAL:                         'TRANSACTIONAL';\nTRIGGER:                               'TRIGGER';\nTRIGGERS:                              'TRIGGERS';\nTRIM:                                  'TRIM';\nTRUE:                                  'TRUE';\nTRUNCATE:                              'TRUNCATE';\nTRUNCSIZE:                             'TRUNCSIZE';\nTRXID:                                 'TRXID';\nTRY:                                   'TRY';\nTUE:                                   'TUE';\nTYPE:                                  'TYPE';\nTYPEDEF:                               'TYPEDEF';\nTYPEOF:                                'TYPEOF';\nUINT:                                  'UINT';\nULONG:                                 'ULONG';\nUNBOUNDED:                             'UNBOUNDED';\nUNCOMMITTED:                           'UNCOMMITTED';\nUNCONDITIONAL:                         'UNCONDITIONAL';\nUNDER:                                 'UNDER';\nUNION:                                 'UNION';\nUNIQUE:                                'UNIQUE';\nUNLIMITED:                             'UNLIMITED';\nUNLOCK:                                'UNLOCK';\nUNPIVOT:                               'UNPIVOT';\nUNTIL:                                 'UNTIL';\nUNUSABLE:                              'UNUSABLE';\nUP:                                    'UP';\nUPDATE:                                'UPDATE';\nUPDATING:                              'UPDATING';\nUSAGE:                                 'USAGE';\nUSER:                                  'USER';\nUSE_HASH:                              'USE_HASH';\nUSE_MERGE:                             'USE_MERGE';\nUSE_NL:                                'USE_NL';\nUSE_NL_WITH_INDEX:                     'USE_NL_WITH_INDEX';\nUSHORT:                                'USHORT';\nUSING:                                 'USING';\nVALUE:                                 'VALUE';\nVALUES:                                'VALUES';\nVARBINARY_KEYWORD:                     'VARBINARY';\nVARCHAR:                               'VARCHAR';\nVARCHAR2:                              'VARCHAR2';\nVARIANCE:                              'VARIANCE';\nVARRAY:                                'VARRAY';\nVARYING:                               'VARYING';\nVERIFY:                                'VERIFY';\nVERSIONS:                              'VERSIONS';\nVERSIONS_ENDTIME:                      'VERSIONS_ENDTIME';\nVERSIONS_ENDTRXID:                     'VERSIONS_ENDTRXID';\nVERSIONS_OPERATION:                    'VERSIONS_OPERATION';\nVERSIONS_STARTTIME:                    'VERSIONS_STARTTIME';\nVERSIONS_STARTTRXID:                   'VERSIONS_STARTTRXID';\nVERTICAL:                              'VERTICAL';\nVIEW:                                  'VIEW';\nVIRTUAL:                               'VIRTUAL';\nVISIBLE:                               'VISIBLE';\nVOID:                                  'VOID';\nVSIZE:                                 'VSIZE';\nWAIT:                                  'WAIT';\nWED:                                   'WED';\nWEEK:                                  'WEEK';\nWEEKLY:                                'WEEKLY';\nWHEN:                                  'WHEN';\nWHENEVER:                              'WHENEVER';\nWHERE:                                 'WHERE';\nWHILE:                                 'WHILE';\nWITH:                                  'WITH';\nWITHIN:                                'WITHIN';\nWITHOUT:                               'WITHOUT';\nWORK:                                  'WORK';\nWRAPPED:                               'WRAPPED';\nWRAPPER:                               'WRAPPER';\nWRITE:                                 'WRITE';\nXML:                                   'XML';\nXMLAGG:                                'XMLAGG';\nXMLATTRIBUTES:                         'XMLATTRIBUTES';\nXMLELEMENT:                            'XMLELEMENT';\nXMLPARSE:                              'XMLPARSE';\nXMLTABLE:                              'XMLTABLE';\nYEAR:                                  'YEAR';\nYEARLY:                                'YEARLY';\nZONE:                                  'ZONE';\n\n\n// Skip\nWHILE_SPACE:                           [ \\t\\r\\n]+    -> skip;\nWHILE_COMMENT:                         '/*' (COMMENT | .)*? '*/' -> channel(HIDDEN);\nLINE_COMMENT:                          '--' ~[\\r\\n]* -> channel(HIDDEN);\n\n\n// Operators\nOP_ASSIGN:                             ':=';\nOP_ADD_ASSIGN:                         '+=';\nOP_SUB_ASSIGN:                         '-=';\nOP_MULT_ASSIGN:                        '*=';\nOP_DIV_ASSIGN:                         '/=';\nOP_MOD_ASSIGN:                         '%=';\nOP_AND_ASSIGN:                         '&=';\nOP_XOR_ASSIGN:                         '^=';\nOP_OR_ASSIGN:                          '|=';\nOP_CONSTR:                             '||';\nOP_CAST:                               '::';\nOP_SHIFT_LEFT:                         '<<';\nOP_SHIFT_RIGHT:                        '>>';\n\nOPR_NE:                                ('!='| '<>');\nOPR_LE:                                '<=';\nOPR_GE:                                '>=';\nOPR_EQ:                                '==';\nOPR_AEQ:                               '=>';\nOPR_INC:                               '++';\nOPR_DEC:                               '--';\n//OPR_EQ_RIGHT_JOIN:                     '=*';\n\nOP_SHIFT_RIGHT_ASSIGN:                 '>>=';\nOP_SHIFT_LEFT_ASSIGN:                  '<<=';\n\nOP_EQUAL:                              '=';\nOP_NOT:                                '!';\nOP_PLUS:                               '+';\nOP_MINUS:                              '-';\nOP_STAR:                               '*';\nOP_DIVIDE:                             '/';\nOP_MOD:                                '%';\nOP_GREATER:                            '>';\nOP_LESS:                               '<';\nOP_BIT_NOT:                            '~';\nOP_BIT_OR:                             '|';\nOP_BIT_AND:                            '&';\nOP_BIT_XOR:                            '^';\n\n\n// Symbols\nBOUNDARY:                              '..';\nDOT:                                   '.';\nUNDERLINE:                             '_';\nAT:                                    '@';\nSHARP:                                 '#';\nDOLLAR:                                '$';\nLR_BRACKET:                            '(';\nRR_BRACKET:                             ')';\nLR_SQUARE_BRACKET:                     '[';\nRR_SQUARE_BRACKET:                     ']';\nLR_BRACES:                             '{';\nRR_BRACES:                             '}';\nCOMMA:                                 (',' | '\\uff0c');\nSEMI:                                  (';' | '\\uff1b');\nCOLON:                                 ':';\nPLACEHOLDER:                           '?';\n\nOP_U_OPRT:                             OP_CHARS+?;\n\n// Var\nLT_GLOBAL_VAR:                         '@''@' IDENTIFIER;\nLT_IDENTIFIER:                         ( IDENTIFIERX | IDENTIFIER | LT_DQUOTE_STRING );\n\n// Const\nLT_STRING:                             'N'? '\\'' (~'\\'' | '\\'\\'')* '\\'';\nLT_BITSTRING:                          [B] '\\''  [^']*  '\\'';\nLT_INTEGER:                            DIGIT+;\nLT_BINTEGER:                           '0' [X] (DIGIT|[A-F])+;\n//LT_BIGINTEGER:                         DIGIT {20,};\n//LT_DECIMAL:                            ( (DIGIT* '.' DIGIT+)|(DIGIT+ '.' DIGIT*) );\nLT_DECIMAL:                            (DIGIT* '.' DIGIT+) ;\n//LT_REAL:                              ((((DIGIT* '.' DIGIT+)|(DIGIT+ '.' DIGIT*)|(DIGIT+))([E][-+]? DIGIT+))|((DIGIT* '.' DIGIT+)|(DIGIT+ '.' DIGIT*)|(DIGIT+))) ([DF])?|{BINARY_FLOAT_INFINITY}|{BINARY_FLOAT_NAN}|{binary_double_infinity}|{binary_double_nan};\nLT_REAL:                               (DIGIT+ | LT_DECIMAL)('E'([+-]? DIGIT+)?);\n\n\n// frament\nfragment DIGIT:                        [0-9];\n//fragment DIGIT_PARAM:                  '@' DIGIT+;\nfragment CLETTER_H:                    [\\u0080-\\u00FF];\nfragment CLETTER_T:                    [\\u0000-\\u00FF];\nfragment CLETTER:                      [\\u4e00-\\u9fa5];\n\nfragment LETTER1:                      (CLETTER | [_A-Z$#]);\nfragment LETTER_OR_DIGIT1:             (CLETTER | [_A-Z0-9$#]);\nfragment LETTER2:                      (CLETTER_H | [_A-Z$#]);\nfragment LETTER_OR_DIGIT2:             (CLETTER_H | [_A-Z0-9$#]);\n\nfragment IDENTIFIERX:                  LETTER1 LETTER_OR_DIGIT1*;\nfragment IDENTIFIER:                   LETTER2 LETTER_OR_DIGIT2*;\n\nfragment LT_DQUOTE_STRING:             '\"' ~'\"'+ '\"';\n//fragment LT_BQUOTE_STRING:             '`' ~'`'+ '`';\n//fragment LT_BRACKET_STRING:            '[' (~']' | ']' ']')* ']';\n\nfragment NOLETERDIGIT:                 [^_A-Z#$0-9];\n\nfragment OP_CHARS:                     [<>=+\\-&|*%/^?@!~`];\n\nfragment BINARY_FLOAT_INFINITY:        'BINARY_FLOAT_INFINITY';\nfragment BINARY_FLOAT_NAN:             'BINARY_FLOAT_NAN';\nfragment BINARY_DOUBLE_INFINITY:       'BINARY_DOUBLE_INFINITY';\nfragment BINARY_DOUBLE_NAN:            'BINARY_DOUBLE_NAN';\n"
  },
  {
    "path": "superior-dameng-parser/src/main/antlr4/io/github/melin/superior/parser/dameng/antlr4/DmSqlParser.g4",
    "content": "parser grammar DmSqlParser;\n\noptions { tokenVocab=DmSqlLexer; }\n\n\ndmprogram :\n    sql_clauses (SEMI sql_clauses)* SEMI? EOF\n    ;\n\nsql_clauses :\n    ddlsql\n    | dmlsql\n    | privsql\n    | othersql\n    | utilsql\n    | explainsql\n    | declare_block\n    ;\n\nddlsql :\n    alter_proc_stmt\n    | alter_func_stmt\n    | alter_package_stmt\n    | alter_table_stmt\n    | alter_index_stmt\n    | comment_stmt\n    | alter_trigger_stmt\n    | alter_view_stmt\n    | alter_materialized_view_stmt\n    | refresh_materialized_view_stmt\n    | create_tablespace_stmt\n    | create_func_stmt\n    | create_proc_stmt\n    | create_trigger_stmt\n    | create_view_stmt\n    | create_materialized_view_stmt\n    | create_materialized_view_log_stmt\n    | alter_database_stmt\n    | alter_tablespace_stmt\n    | create_user_stmt\n    | alter_user_stmt\n    | create_profile_stmt\n    | alter_profile_stmt\n    | create_role_stmt\n    | create_sequence_stmt\n    | create_contextindex_stmt\n    | drop_contextindex_stmt\n    | alter_contextindex_stmt\n    | create_audit_rule_stmt\n    | create_dblink_stmt\n    | create_package_stmt\n    | create_package_body_stmt\n    | create_type_stmt\n    | create_type_body_stmt\n    | create_synonym_stmt\n    | create_crypto_stmt\n    | alter_crypto_stmt\n    | alter_session_stmt\n    | create_domain_stmt\n    | create_character_set_stmt\n    | create_collation_stmt\n    | alter_system_set_stmt\n    | create_context_stmt\n    | create_directory_stmt\n    | create_tablespace_set_stmt\n    | alter_tablespace_set_stmt\n    | create_operator_stmt\n    | drop_operator_stmt\n    | flashback_tab_stmt\n    ;\n\ndmlsql :\n    call_proc_stmt\n    | delete_stmt\n    | insert_stmt\n    | select_stmt ur_option?\n    | update_stmt\n    | merge_into_stmt\n    | trunc_table_stmt\n    | create_table_stmt\n    | drop_stmt\n    | begin_trans_stmt\n    | commit_trans_stmt\n    | rollback_stmt\n    | savepoint_stmt\n    | create_index_stmt\n    | set_trans_stmt\n    | lock_table_stmt\n    | set_identins_stmt\n    | set_session_stmt\n    | stat_on_org_stmt\n    | create_partition_group_stmt\n    | fetch_stmt\n    | open_stmt\n    | close_cursor_stmt\n    ;\n\nprivsql :\n    grant_stmt\n    | revoke_stmt\n    ;\n\nothersql :\n    connect_stmt\n    | disconnect_stmt\n    | set_schema_stmt\n    | backup_stmt\n    | restore_stmt\n    ;\n\nutilsql :\n    alter_diskgroup_stmt\n    | shutdown_stmt\n    | repeat_interval_stmt\n    | create_schema_stmt\n    | assign_stmt\n;\n\nexplainsql :\n    EXPLAIN (dmlsql | assign_stmt) (COMMA (dmlsql | assign_stmt))*\n    | EXPLAIN (AS raw_id)? FOR (dmlsql | ddlsql | privsql |othersql) \n;\n   \n\nshutdown_stmt :\n    SHUTDOWN ABORT\n    | SHUTDOWN IMMEDIATE\n    | SHUTDOWN NORMAL\n    | SHUTDOWN TRANSACTIONAL local?\n    | STOP INSTANCE\n    ;\n\nalter_diskgroup_stmt :\n    alter_tag DISKGROUP LT_STRING pathname CORRUPT\n    ;\n\nlocal :\n    LOCAL\n    ;\n\ndmsubprogram :\n    label_list_options? decl_var_cur_list_options? BEGIN plbody except_option? blk_end_option\n    ;\n\ndeclare_block :\n    label_list_options? decl_var_cur_list_1? BEGIN plbody except_option? blk_end_option\n    ;\n\ndecl_var_cur_list_options :\n    DECLARE\n    | DECLARE decl_var_cur_list\n    | decl_var_cur_list\n    ;\n\ndecl_var_cur_list_1 :\n    DECLARE\n    | DECLARE decl_var_cur_list\n    ;\n\ndecl_var_cur_list :\n    ( decl_variable | decl_except | pragma_def | (decl_cursor SEMI) | decl_plsql_type | package_body_def | subpg_decl_stmt )+\n    ;\n\ndecl_plsql_type :\n    TYPE variable_name IS plsql_type_def SEMI\n    | SUBTYPE variable_name IS sub_plsql_datatype not_null? SEMI\n    ;\n\nplsql_type_def :\n    RECORD '(' rec_item_def_list ')'\n    | REF CURSOR\n    | REF CURSOR RETURN plsql_datatype\n    | ARRAY plsql_datatype rank_specifiers\n    | REF CURSOR '(' param_def_list ')'\n    | REF CURSOR '(' param_def_list ')' RETURN plsql_datatype\n    | ARRAY plsql_datatype '[' lt_int_lst ']'\n    | plsql_datatype\n    | TABLE OF plsql_datatype not_null?\n    | TABLE OF plsql_datatype not_null? INDEX BY plsql_datatype\n    | VARRAY '(' LT_INTEGER ')' OF plsql_datatype not_null?\n    ;\n\nlt_int_lst :\n    LT_INTEGER\n    | lt_int_lst COMMA LT_INTEGER\n    ;\n\nrec_item_def_list :\n    rec_item_def (COMMA rec_item_def)*\n    ;\n\nrec_item_def :\n    id plsql_datatype opt_rank_specifier2 not_null? default_clause_option?\n    ;\n\ndecl_variable :\n    variable_name_list plsql_datatype not_null? default_clause_option? SEMI\n    | variable_name_list AS plsql_datatype not_null? default_clause_option? SEMI\n    | variable_name_list CONSTANT plsql_datatype not_null? default_clause_option? SEMI\n    ;\n\nnot_null :\n    NOT NULL\n    ;\n\nplsql_datatype :\n    datatype\n    | qualified_name dblink_clause? '%' TYPE\n    | qualified_name dblink_clause? '%' ROWTYPE\n    | REF qualified_name\n    | CURSOR\n    ;\n\ndefault_clause_option :\n    DEFAULT default_exp\n    | assign_op default_exp\n    ;\n\nvariable_name_list :\n    variable_name (COMMA variable_name)*\n    ;\n\ndecl_except :\n    variable_name_list EXCEPTION FOR '-' LT_INTEGER SEMI\n    | variable_name_list EXCEPTION FOR '-' LT_INTEGER COMMA LT_STRING SEMI\n    ;\n\npragma_def :\n    PRAGMA pragma SEMI\n    ;\n\npragma :\n    EXCEPTION_INIT '(' except_name COMMA '-' LT_INTEGER ')'\n    | AUTONOMOUS_TRANSACTION\n    ;\n\nplbody :\n    (plsql SEMI)+\n    ;\n\nss_plbody :\n    plblock\n    ;\n\nlabel :\n    label_demiliter_l label_name label_demiliter_r\n    ;\n\nlabel_list :\n    label+\n    ;\n\nlabel_list_options :\n    label_list\n    ;\n\nlabel_demiliter_l :\n    OP_SHIFT_LEFT\n    ;\n\nlabel_demiliter_r :\n    OP_SHIFT_RIGHT\n    ;\n\nplsql :\n    dmlsql\n    | if_stmt\n    | assign_stmt\n    | goto_stmt\n    | while_stmt\n    | loop_stmt\n    | repeat_stmt\n    | for_stmt\n    | return_stmt\n    | plblock\n    | raise_stmt\n    | exit_stmt\n    | print_stmt\n    | execute_stmt\n    | continue_stmt\n    | case_stmt\n    | null_stmt\n    | label plsql\n    | forall_stmt\n    | pipe_row_stmt\n    ;\n\nur_option :\n    WITH id\n    ;\n\nflashback_trig_enable :\n    ENABLE TRIGGERS\n    | DISABLE TRIGGERS\n    ;\n\nscn_or_lsn :\n    SCN\n    | LSN\n    ;\n\nfull_table_name_list :\n    full_table_name (COMMA full_table_name)*\n    ;\n\nflashback_tab_stmt :\n    FLASHBACK TABLE full_table_name_list TO BEFORE DROP rename?\n    | FLASHBACK TABLE full_table_name_list TO BEFORE TRUNCATE\n    | FLASHBACK TABLE full_table_name_list TO TIMESTAMP exp flashback_trig_enable?\n    | FLASHBACK TABLE full_table_name_list TO scn_or_lsn trxid flashback_trig_enable?\n    ;\n\nrename :\n    RENAME TO id\n    ;\n\nalter_system_set_stmt :\n    alter_tag SYSTEM SET LT_STRING '=' raw_exp defer? scope?\n    ;\n\ndefer :\n    DEFERRED\n    ;\n\nscope :\n    MEMORY\n    | BOTH\n    | SPFILE\n    ;\n\nalter_session_stmt :\n    alter_tag SESSION sess_id? SET QUERY_REWRITE_INTEGRITY assign_op exp\n    | alter_tag SESSION sess_id? SET EVENTS LT_STRING\n    | alter_tag SESSION sess_id? SET TIME_ZONE assign_op set_time_zone_string\n    | alter_tag SESSION sess_id? SET LT_STRING '=' raw_exp purge?\n    | alter_tag SESSION sess_id? SET CASE_SENSITIVE assign_op exp\n    | alter_tag SESSION sess_id? SET CASE_SENSITIVE assign_op DEFAULT\n    | alter_tag SESSION sess_id? SET CURRENT_SCHEMA '=' qualified_name\n    | alter_tag SESSION sess_id? SET sess_attr '=' sess_attr_val\n    | alter_tag SESSION sess_id? ENABLE PARALLEL parallel_mode\n    | alter_tag SESSION sess_id? DISABLE PARALLEL parallel_mode\n    | alter_tag SESSION sess_id? FORCE PARALLEL parallel_mode parallel_degree?\n    ;\n\nparallel_mode :\n    DML\n    | QUERY\n    | DDL\n    ;\n\nparallel_degree :\n    PARALLEL LT_INTEGER\n    ;\n\npurge :\n    PURGE\n    ;\n\nsess_id :\n    LT_INTEGER\n    | LT_DECIMAL\n    ;\n\nset_time_zone_string :\n    LOCAL\n    | LT_STRING\n    ;\n\nsess_attr :\n    raw_id\n    ;\n\nsess_attr_val :\n    raw_id\n    | LT_STRING\n    ;\n\nset_schema_stmt :\n    SET SCHEMA qualified_name\n    ;\n\nplblock :\n    decl_var_cur_list_1? BEGIN plbody except_option? blk_end_option\n    ;\n\nexcept_option :\n    EXCEPTION except_handler_list finally_option?\n    | FINALLY finally_tail\n    ;\n\nfinally_option :\n    FINALLY finally_tail\n    ;\n\nfinally_tail :\n    plbody\n    ;\n\nexcept_handler_list :\n    except_handler+\n    ;\n\nexcept_handler :\n    WHEN except_list THEN plbody\n    ;\n\nexcept_name :\n    variable_name\n    ;\n\nexcept_list :\n    qualified_name (OR qualified_name)*\n    ;\n\nif_stmt :\n    if_stmt_clause elseif_lst_option? else_option? END IF\n    | ss_if_stmt_clause ss_elseif_lst_option? ss_else_option?\n    ;\n\nif_stmt_clause :\n    if_condition_clause if_then_clause\n    ;\n\nif_condition_clause :\n    IF bool_exp\n    ;\n\nif_then_clause :\n    THEN plbody\n    ;\n\nelseif_lst_option :\n    elseif_clause elseif_lst_option?\n    ;\n\nelseif_clause :\n    ELSEIF bool_exp THEN plbody\n    ;\n\nelse_option :\n    ELSE plbody\n    ;\n\nss_if_stmt_clause :\n    if_condition_clause ss_plbody\n    ;\n\nss_elseif_lst_option :\n    ss_elseif_clause ss_elseif_lst_option?\n    ;\n\nss_elseif_clause :\n    ELSEIF bool_exp ss_plbody\n    ;\n\nss_else_option :\n    ELSE ss_plbody\n    ;\n\ncase_stmt :\n    CASE plsearched_when_list else_option? END case_option? label_name_options?\n    | CASE bool_exp plsearched_when_list else_option? END case_option? label_name_options?\n    ;\n\nplsearched_when_clause :\n    WHEN bool_exp THEN plbody\n    ;\n\nplsearched_when_list :\n    plsearched_when_clause+\n    ;\n\ncase_option :\n    CASE\n    ;\n\nassign_stmt :\n    assign_obj2 assign_op bool_exp\n    | SET assign_obj assign_op bool_exp\n    ;\n\nassign_obj :\n    assignment_obj\n    ;\n\nassign_obj2 :\n    pexp_pfx2\n    | stm_param_name\n    ;\n\nassign_op :\n    ASSIGN\n    | OP_ASSIGN\n    | '='\n    ;\n\ngoto_stmt :\n    GOTO id\n    ;\n\nwhile_stmt :\n    WHILE bool_exp LOOP plbody end_loop_label_null\n    ;\n\nloop_stmt :\n    LOOP plbody end_loop_label_null\n    ;\n\nrepeat_stmt :\n    REPEAT plbody UNTIL bool_exp\n    ;\n\nfor_stmt :\n    FOR id in_option for_condition LOOP plbody end_loop_label_null\n    ;\n\nforall_stmt :\n    forall_start for_condition forall_save_exception_option? forall_dml_stmt\n    | forall_start forall_index_values OF pexp forall_between_option? forall_save_exception_option? forall_dml_stmt\n    ;\n\nforall_between_option :\n    BETWEEN exp AND exp\n    ;\n\nforall_save_exception_option :\n    SAVE EXCEPTIONS\n    ;\n\nforall_index_values :\n    INDICES\n    | VALUES\n    ;\n\nforall_start :\n    FORALL id IN\n    ;\n\nforall_dml_stmt :\n    delete_stmt\n    | insert_stmt\n    | update_stmt\n    | merge_into_stmt\n    | query_exp\n    | execute_stmt\n    ;\n\nin_option :\n    IN REVERSE?\n    ;\n\nfor_condition :\n    exp '..' exp\n    | exp\n    ;\n\npipe_row_stmt :\n    PIPE ROW '(' exp ')'\n    ;\n\nexit_stmt :\n    EXIT\n    | EXIT WHEN bool_exp\n    | EXIT id\n    | EXIT id WHEN bool_exp\n    ;\n\ncontinue_stmt :\n    CONTINUE\n    | CONTINUE WHEN bool_exp\n    | CONTINUE id\n    | CONTINUE id WHEN bool_exp\n    ;\n\nnull_stmt :\n    NULL\n    ;\n\nprint_stmt :\n    PRINT exp\n    ;\n\nexecute_stmt :\n    EXECUTE IMMEDIATE exp bulk_or_single_into? using_clause? dyn_return?\n    ;\n\ndyn_return :\n    return_option bulk_or_single_into?\n    ;\n\nusing_clause :\n    USING using_exp_list\n    ;\n\nusing_exp_list :\n    using_exp (COMMA using_exp)*\n    ;\n\nusing_exp :\n    param_in_out_option? exp\n    ;\n\nalter_proc_stmt :\n    alter_tag PROCEDURE full_proc_name COMPILE cascade_opt? debug_tag?\n    ;\n\nalter_func_stmt :\n    alter_tag FUNCTION full_fun_name COMPILE cascade_opt? debug_tag?\n    ;\n\nalter_package_stmt :\n    alter_tag pkg_type full_proc_name COMPILE declare_opt? cascade_opt? debug_tag?\n    ;\n\npkg_type :\n    PACKAGE\n    | TYPE\n    | CLASS\n    ;\n\ndeclare_opt :\n    DECLARE\n    ;\n\nalter_table_stmt :\n    alter_tag TABLE full_table_name alter_table_action\n    ;\n\nalter_tag :\n    ALTER\n    ;\n\nalter_index_stmt :\n    alter_tag INDEX full_index_name alter_index_action\n    ;\n\nfull_index_name :\n    qualified_name\n    ;\n\nalter_index_action :\n    RENAME TO index_name\n    | visible_clause\n    | rebuild_clause\n    | UNUSABLE\n    | MONITORING USAGE\n    | NOMONITORING USAGE\n    ;\n\nrebuild_clause :\n    REBUILD storage_tag? index_no_sort? online_options? exclusive_options? asynchronous_options?\n    ;\n\nexclusive_options :\n    SHARE\n    | EXCLUSIVE\n    ;\n\nasynchronous_options :\n    ASYNCHRONOUS\n    | ASYNCHRONOUS LT_INTEGER\n    ;\n\nvisible_clause :\n    VISIBLE\n    | INVISIBLE\n    ;\n\ncolumn_def_list :\n    column_def (COMMA column_def_list)*\n    ;\n\nlock :\n    NO LOCK\n    ;\n\nalter_table_partition_action :\n    ADD range_partition lock?\n    | ADD list_partition\n    | ADD hash_partition\n    | DROP PARTITION exist? full_partition_name\n    | DROP PARTITION exist? FOR '(' exp_list ')'\n    | EXCHANGE PARTITION full_partition_name WITH TABLE full_table_name including_indexes?\n    | EXCHANGE SUBPARTITION full_partition_name WITH TABLE full_table_name including_indexes?\n    | SPLIT PARTITION full_partition_name AT_KEYWORD '(' range_partition_exp_list ')' INTO '(' split_partition_list ')'\n    | SPLIT PARTITION full_partition_name VALUES '(' list_partition_exp_list ')' INTO '(' split_partition_list ')'\n    | SPLIT PARTITION full_partition_name INTO '(' list_partition_list COMMA hash_partition ')'\n    | SPLIT PARTITION full_partition_name INTO '(' range_partition_list COMMA hash_partition ')'\n    | MERGE PARTITIONS partition_no? COMMA partition_no? INTO PARTITION full_partition_name\n    | MERGE PARTITIONS full_partition_name COMMA full_partition_name INTO PARTITION full_partition_name\n    | SET SUBPARTITION TEMPLATE template_info\n    | DROP SUBPARTITION exist? full_partition_name\n    | DROP SUBPARTITION exist? FOR '(' exp_list ')'\n    | MODIFY PARTITION full_partition_name ADD add_subpartition_desc\n    | MODIFY SUBPARTITION full_partition_name ADD add_subpartition_desc\n    | MODIFY PARTITION full_partition_name ADD VALUES '(' list_partition_value_list ')'\n    | MODIFY PARTITION full_partition_name DROP VALUES '(' list_partition_value_list ')'\n    | RENAME PARTITION full_partition_name TO full_partition_name\n    | RENAME SUBPARTITION full_partition_name TO full_partition_name\n    | MODIFY SUBPARTITION full_partition_name ADD VALUES '(' list_partition_value_list ')'\n    | MODIFY SUBPARTITION full_partition_name DROP VALUES '(' list_partition_value_list ')'\n    | MOVE PARTITION full_partition_name TABLESPACE tablespace_name\n    | MOVE SUBPARTITION full_partition_name TABLESPACE tablespace_name\n    | MOVE TABLESPACE tablespace_name\n    | LOCK PARTITIONS\n    | LOCK ROOT\n    ;\n\ntemplate_info :\n    '(' template_item_1? ')'\n    | template_item_2\n    ;\n\ntemplate_item_2 :\n    SUBPARTITIONS LT_INTEGER storage_hash_tag?\n    | LT_INTEGER storage_hash_tag?\n    ;\n\ntemplate_item_1 :\n    range_subpartition_list\n    | hash_subpartition_list\n    | list_subpartition_list\n    ;\n\nincluding_indexes :\n    INCLUDING INDEXES\n    | EXCLUDING INDEXES\n    ;\n\ntruncate_partition_name :\n    full_partition_name\n    | '(' full_partition_name ')'\n    ;\n\ncons_enable :\n    ENABLE\n    | DISABLE\n    ;\n\nreuse_storage_option :\n    REUSE STORAGE\n    | DROP STORAGE\n    ;\n\nalter_table_action :\n    ADD column_tag? not_exist? '(' column_def_list ')'\n    | ALTER column_tag? column_name SET DEFAULT default_exp\n    | ALTER column_tag? column_name SET DEFAULT ON NULL default_exp\n    | ALTER column_tag? column_name DROP DEFAULT\n    | ADD CONSTRAINT constraint_name_options? table_constraint_clause check_option_def_true? cons_enable?\n    | ADD table_constraint_clause check_option_def_true? cons_enable?\n    | DROP constraint_name_def restrict_cascade?\n    | ALTER column_tag? column_name RENAME TO column_name\n    | RENAME COLUMN column_name TO column_name\n    | RENAME TO table_name\n    | MODIFY mdf_column_def\n    | MODIFY CONSTRAINT constraint_name ENABLE\n    | MODIFY CONSTRAINT constraint_name DISABLE restrict_cascade?\n    | REBUILD MODIFY mdf_column_def\n    | MODIFY '(' mdf_column_def_list ')'\n    | ADD column_tag? not_exist? column_def\n    | DROP column_tag? exist? '(' drop_column_list ')'\n    | DROP column_tag? exist? column_name restrict_cascade?\n    | ENABLE ALL TRIGGERS\n    | DISABLE ALL TRIGGERS\n    | MODIFY constraint_name_def TO table_constraint_clause check_option_def_true? restrict_cascade?\n    | MODIFY space_limit_1\n    | alter_table_partition_action\n    | DROP IDENTITY\n    | DROP AUTO_INCREMENT\n    | ADD column_tag? not_exist? column_name identity_clause\n    | ENABLE ata_lock_option\n    | DISABLE ata_lock_option\n    | ENABLE CONSTRAINT constraint_name check_option_def_true?\n    | DISABLE CONSTRAINT constraint_name restrict_cascade?\n    | ALTER column_tag? column_name SET not_null_spec\n    | MODIFY ERROR TO ctab_error_option\n    | MODIFY LOG TO ctab_log_option\n    | ALTER column_tag? '(' column_list ')' SET STAT\n    | ALTER column_tag? '(' column_list ')' SET STAT NONE\n    | ALTER column_tag? column_name SET STAT NONE\n    | WITH COUNTER\n    | WITHOUT COUNTER\n    | LOGGING\n    | NOLOGGING\n    | REBUILD COLUMNS\n    | TRUNCATE PARTITION truncate_partition_name reuse_storage_option?\n    | TRUNCATE PARTITION FOR '(' exp_list ')' reuse_storage_option?\n    | TRUNCATE SUBPARTITION truncate_partition_name reuse_storage_option?\n    | TRUNCATE SUBPARTITION FOR '(' exp_list ')' reuse_storage_option?\n    | ALTER column_tag? column_name SET not_tag? VISIBLE\n    | ENABLE ROW MOVEMENT\n    | DISABLE ROW MOVEMENT\n    | MODIFY PATH pathname\n    | LOCATION '(' pathname ')'\n    | DEFAULT DIRECTORY id\n    | DEFAULT DIRECTORY id LOCATION '(' pathname ')'\n    | ENABLE USING LONG ROW\n    | WITH DELTA\n    | WITHOUT DELTA\n    | FORCE COLUMN STORAGE\n    | REBUILD hfs_rebuild_level\n    | REFRESH STAT\n    | SET STAT storage_stat_flag? storage_stat_cols?\n    | WITH ADVANCED LOG\n    | WITHOUT ADVANCED LOG\n    | TRUNCATE ADVANCED LOG\n    | ADD LOGIC LOG\n    | DROP LOGIC LOG\n    | DROP PRIMARY KEY restrict_cascade?\n    | DROP PARTITION GROUP full_table_name\n    | read_only_flag_not_null\n    | MOVE PARTITION full_partition_name TO raft_name fast_flag?\n    | MOVE TO full_grp_name fast_flag?\n    | increment_set\n    | ALTER column_tag? column_name ADD user_clause\n    | ALTER column_tag? column_name DROP user_clause\n    | RENAME constraint_name_def TO constraint_name\n    | PARALLEL LT_INTEGER\n    ;\n\nfast_flag :\n    FAST\n    ;\n\nstorage_stat_flag :\n    NONE\n    | ASYNCHRONOUS\n    | SYNCHRONOUS\n    ;\n\nstorage_stat_cols :\n    ON '(' column_list ')'\n    | EXCEPT '(' column_list ')'\n    ;\n\nhfs_rebuild_level :\n    SECTION\n    | TABLE\n    ;\n\nata_lock_option :\n    PAGE LOCK\n    | ROW LOCK\n    | PAGE ROW LOCK\n    | ROW PAGE LOCK\n    ;\n\nmdf_column_def_list :\n    mdf_column_def (COMMA mdf_column_def)*\n    ;\n\nmdf_column_def :\n    column_def_low\n    | virtual_column_def\n    | column_name column_def_4_option?\n    ;\n\ncolumn_def :\n    column_def_low\n    | virtual_column_def\n    ;\n\ncolumn_def_ex :\n    column_def comment_clause?\n    ;\n\ncolumn_def_low :\n    column_name datatype charset_option? collate_clause_option? column_def_4_option? storage_tag? encrypt_clause_options? compress_clause_opt?\n    ;\n\nvirtual_column_datatype :\n    datatype\n    ;\n\nvirtual_column_generated :\n    GENERATED ALWAYS\n    ;\n\nvirtual_column_virtual :\n    VIRTUAL\n    ;\n\nvirtual_column_visible :\n    VISIBLE\n    ;\n\nvirtual_column_def :\n    column_name virtual_column_datatype? virtual_column_generated? AS '(' exp ')' virtual_column_virtual? charset_option? collate_clause_option? column_def_4_option? storage_tag? encrypt_clause_options? virtual_column_visible?\n    ;\n\ncharset_option :\n    CHARACTER SET qualified_name\n    ;\n\ncolumn_def_4_option :\n    identity_clause\n    | column_constraint_def\n    | auto_update_clause\n    | default_clause_with_on_null_opt (identity_clause | column_constraint_def | auto_update_clause)?\n    | identity_clause default_clause_with_on_null_opt\n    | identity_clause column_constraint_def\n    | identity_clause auto_update_clause\n    | column_constraint_def default_clause_with_on_null_opt\n    | column_constraint_def auto_update_clause\n    | column_constraint_def identity_clause\n    | auto_update_clause default_clause_with_on_null_opt\n    | auto_update_clause column_constraint_def\n    | auto_update_clause identity_clause\n    | default_clause_with_on_null_opt auto_update_clause column_constraint_def\n    | default_clause_with_on_null_opt column_constraint_def auto_update_clause\n    | default_clause_with_on_null_opt identity_clause column_constraint_def\n    | default_clause_with_on_null_opt column_constraint_def identity_clause\n    | default_clause_with_on_null_opt identity_clause auto_update_clause\n    | default_clause_with_on_null_opt auto_update_clause identity_clause\n    | identity_clause auto_update_clause column_constraint_def\n    | identity_clause column_constraint_def auto_update_clause\n    | identity_clause auto_update_clause default_clause_with_on_null_opt\n    | identity_clause default_clause_with_on_null_opt auto_update_clause\n    | identity_clause default_clause_with_on_null_opt column_constraint_def\n    | identity_clause column_constraint_def default_clause_with_on_null_opt\n    | column_constraint_def default_clause_with_on_null_opt auto_update_clause\n    | column_constraint_def auto_update_clause default_clause_with_on_null_opt\n    | column_constraint_def default_clause_with_on_null_opt identity_clause\n    | column_constraint_def identity_clause default_clause_with_on_null_opt\n    | column_constraint_def identity_clause auto_update_clause\n    | column_constraint_def auto_update_clause identity_clause\n    | auto_update_clause column_constraint_def default_clause_with_on_null_opt\n    | auto_update_clause default_clause_with_on_null_opt column_constraint_def\n    | auto_update_clause identity_clause column_constraint_def\n    | auto_update_clause column_constraint_def identity_clause\n    | auto_update_clause identity_clause default_clause_with_on_null_opt\n    | auto_update_clause default_clause_with_on_null_opt identity_clause\n    | default_clause_with_on_null_opt identity_clause auto_update_clause column_constraint_def\n    | default_clause_with_on_null_opt identity_clause column_constraint_def auto_update_clause\n    | default_clause_with_on_null_opt auto_update_clause identity_clause column_constraint_def\n    | default_clause_with_on_null_opt auto_update_clause column_constraint_def identity_clause\n    | default_clause_with_on_null_opt column_constraint_def identity_clause auto_update_clause\n    | default_clause_with_on_null_opt column_constraint_def auto_update_clause identity_clause\n    | identity_clause default_clause_with_on_null_opt auto_update_clause column_constraint_def\n    | identity_clause default_clause_with_on_null_opt column_constraint_def auto_update_clause\n    | identity_clause auto_update_clause default_clause_with_on_null_opt column_constraint_def\n    | identity_clause auto_update_clause column_constraint_def default_clause_with_on_null_opt\n    | identity_clause column_constraint_def default_clause_with_on_null_opt auto_update_clause\n    | identity_clause column_constraint_def auto_update_clause default_clause_with_on_null_opt\n    | auto_update_clause default_clause_with_on_null_opt identity_clause column_constraint_def\n    | auto_update_clause default_clause_with_on_null_opt column_constraint_def identity_clause\n    | auto_update_clause identity_clause default_clause_with_on_null_opt column_constraint_def\n    | auto_update_clause identity_clause column_constraint_def default_clause_with_on_null_opt\n    | auto_update_clause column_constraint_def identity_clause default_clause_with_on_null_opt\n    | auto_update_clause column_constraint_def default_clause_with_on_null_opt identity_clause\n    | column_constraint_def default_clause_with_on_null_opt identity_clause auto_update_clause\n    | column_constraint_def default_clause_with_on_null_opt auto_update_clause identity_clause\n    | column_constraint_def identity_clause default_clause_with_on_null_opt auto_update_clause\n    | column_constraint_def identity_clause auto_update_clause default_clause_with_on_null_opt\n    | column_constraint_def auto_update_clause identity_clause default_clause_with_on_null_opt\n    | column_constraint_def auto_update_clause default_clause_with_on_null_opt identity_clause\n    ;\n\nauto_update_clause :\n    ON UPDATE update_exp\n    ;\n\nupdate_exp :\n    exp\n    ;\n\nidentity_clause :\n    IDENTITY '(' exp COMMA exp ')'\n    | IDENTITY\n    | AUTO_INCREMENT\n    ;\n\ndefault_clause_with_on_null_opt :\n    default_clause\n    | DEFAULT ON NULL default_exp\n    ;\n\ndefault_clause :\n    DEFAULT default_exp\n    ;\n\ndefault_exp :\n    exp\n    ;\n\ncolumn_constraint_def :\n    column_constraints constraint_attributes_options?\n    ;\n\nconstraint_name_def_options :\n    constraint_name_def\n    ;\n\nconstraint_name_def :\n    CONSTRAINT constraint_name\n    ;\n\ncolumn_constraints :\n    column_constraint+\n    ;\n\ncolumn_constraint :\n    constraint_name_def_options? column_constraint_action cons_enable?\n    ;\n\ncolumn_constraint_action :\n    not_null_spec\n    | NOT VISIBLE\n    | unique_spec using_index_clause?\n    | refs_spec\n    | check_constraint_def\n    ;\n\nnot_null_spec :\n    not_tag? NULL\n    ;\n\nunique_spec :\n    UNIQUE\n    | PRIMARY KEY\n    | CLUSTER PRIMARY KEY\n    | NOT CLUSTER PRIMARY KEY\n    | CLUSTER KEY\n    | CLUSTER UNIQUE KEY\n    ;\n\nrefs_spec :\n    refs_spec_action (WITH INDEX)?\n    ;\n\nrefs_spec_action :\n    foreign_key? REFERENCES pendant_tag? refd_table_and_columns match_option? ref_triggered_action?\n    ;\n\nforeign_key :\n    FOREIGN KEY\n    ;\n\nrefd_table_and_columns :\n    full_table_name\n    | full_table_name '(' ref_column_list ')'\n    ;\n\nref_column_list :\n    column_list\n    ;\n\ncolumn_list :\n    column_name compress_level? compress_type? (COMMA column_name compress_level? compress_type?)*\n    ;\n\ncolumn_list2 :\n    exp compress_level? compress_type? (COMMA exp compress_level? compress_type?)*\n    ;\n\nfull_column_list :\n    full_column_name (COMMA full_column_name)*\n    ;\n\ncolumn_list_list :\n    '(' column_list ')' as_alias? storage_tag?\n    | '(' column_list ')' as_alias? storage_tag? COMMA column_list_list\n    ;\n\ndrop_column_list :\n    column_name restrict_cascade? (COMMA column_name restrict_cascade?)*\n    ;\n\nmatch_option :\n    MATCH match_type\n    ;\n\nmatch_type :\n    FULL\n    | PARTIAL\n    | SIMPLE\n    ;\n\nref_triggered_action :\n    update_rule\n    | delete_rule\n    | update_rule delete_rule\n    | delete_rule update_rule\n    ;\n\nupdate_rule :\n    ON UPDATE ref_action\n    ;\n\ndelete_rule :\n    ON DELETE ref_action\n    ;\n\nref_action :\n    CASCADE\n    | SET NULL\n    | SET DEFAULT\n    | NO ACTION\n    | RESTRICT\n    ;\n\ncheck_constraint_def :\n    CHECK '(' check_condition ')'\n    ;\n\ncheck_condition :\n    bool_exp\n    ;\n\nrestrict_cascade :\n    RESTRICT\n    | CASCADE CONSTRAINTS?\n    ;\n\ncascade_opt :\n    CASCADE\n    ;\n\nconstraint_name_options :\n    constraint_name\n    ;\n\ncheck_option_def_true :\n    NOT? CHECK\n    ;\n\nconstraint_attributes_options :\n    constraint_attributes\n    ;\n\nconstraint_attributes :\n    constraint_check_time\n    | deferrable_option\n    | constraint_check_time deferrable_option\n    | deferrable_option constraint_check_time\n    ;\n\ndeferrable_option :\n    DEFERRABLE\n    ;\n\nconstraint_check_time :\n    INITIALLY DEFERRED\n    | INITIALLY IMMEDIATE\n    ;\n\ntable_constraint_clause :\n    table_constraint constraint_attributes_options?\n    ;\n\ntable_constraint :\n    unique_spec '(' column_list ')' using_index_clause?\n    | foreign_key_clause\n    | check_constraint_def\n    ;\n\nusing_index_clause :\n    USING INDEX TABLESPACE (id | DEFAULT)\n    ;\n\nforeign_key_clause :\n    FOREIGN KEY '(' ref_column_list ')' refs_spec\n    ;\n\nalter_trigger_stmt :\n    alter_tag TRIGGER full_trigger_name (alter_trigger_option | RENAME TO trigger_name)\n    ;\n\nalter_trigger_option :\n    ENABLE\n    | DISABLE\n    | COMPILE debug_tag?\n    | COMPILE AUTO\n    ;\n\nalter_table_partition_action_options :\n    alter_table_partition_action\n    ;\n\nrefresh_materialized_view_stmt :\n    REFRESH MATERIALIZED VIEW full_view_name force? refresh_complete_del?\n    | REFRESH MATERIALIZED VIEW full_view_name COMPLETE refresh_complete_del?\n    | REFRESH MATERIALIZED VIEW full_view_name FAST\n    ;\n\ncomplete_del_null :\n    USING DEFAULT\n    | USING TRUNCATE\n    | USING DELETE\n    ;\n\nrefresh_complete_del :\n    complete_del_null\n    ;\n\nalter_materialized_view_stmt :\n    alter_tag MATERIALIZED VIEW full_view_name alter_table_partition_action_options? mv_refresh_clause? query_rewrite?\n    ;\n\nalter_view_stmt :\n    alter_tag VIEW full_view_name alter_view_action\n    ;\n\nalter_view_action :\n    COMPILE\n    | ADD CONSTRAINT constraint_name_options? view_constraint_clause DISABLE cons_novalidate?\n    | ADD view_constraint_clause DISABLE cons_novalidate?\n    | DROP constraint_name_def\n    ;\n\ncons_novalidate :\n    NOVALIDATE\n    ;\n\nview_constraint_clause :\n    view_constraint\n    ;\n\nview_constraint :\n    view_unique_spec '(' column_list ')'\n    | FOREIGN KEY '(' ref_column_list ')' view_refs_spec\n    ;\n\nview_unique_spec :\n    UNIQUE\n    | PRIMARY KEY\n    ;\n\nview_refs_spec :\n    view_refs_spec_action\n    ;\n\nview_refs_spec_action :\n    foreign_key? REFERENCES refd_table_and_columns\n    ;\n\ncall_proc_stmt :\n    raw_call_proc_stmt\n    | call_proc_stmt_2\n    ;\n\nraw_call_proc_stmt :\n    member_access2\n    | member2\n    | invocation_expression2\n    ;\n\ncall_proc_stmt_2 :\n    CALL raw_call_proc_stmt\n    | exec_proc_stmt\n    ;\n\nexec_proc_stmt :\n    EXECUTE full_proc_name dblink_clause?\n    | EXECUTE full_proc_name dblink_clause? raw_exp_list\n    | EXECUTE full_proc_name dblink_clause? param_list\n    ;\n\ndblink_clause :\n    '@' id\n    ;\n\ndblink_clause2 :\n    '@' qualified_name\n    ;\n\nparam_list :\n    param (COMMA param)*\n    ;\n\nparam :\n    param_name OPR_AEQ bool_exp\n    ;\n\nraw_exp_list :\n    raw_exp (COMMA raw_exp)*\n    ;\n\nexp_list_2 :\n    exp (COMMA exp)+\n    ;\n\nexp_list :\n    exp\n    | exp_list_2\n    ;\n\nins_exp_list :\n    (exp | DEFAULT) (COMMA(exp | DEFAULT))*\n    ;\n\nlt_exp :\n    op=('-' | '+') lt_exp\n    | LT_INTEGER\n    | LT_DECIMAL\n    | LT_REAL\n    | LT_STRING\n    | member_access LT_STRING\n    | member LT_STRING\n    | LT_BITSTRING\n    | INTERVAL '+' LT_STRING interval_qualifier\n    | INTERVAL '-' LT_STRING interval_qualifier\n    | INTERVAL LT_STRING interval_qualifier\n    ;\n\nrange_partition_exp :\n    lt_exp\n    | MAXVALUE\n    | null_value\n    | invocation_expression\n    ;\n\nrange_partition_exp_list :\n    range_partition_exp (COMMA range_partition_exp)*\n    ;\n\nlist_partition_exp :\n    lt_exp\n    | null_value\n    | invocation_expression\n    ;\n\nlist_partition_exp_list :\n    list_partition_exp (COMMA list_partition_exp)*\n    ;\n\nlist_partition_value_list :\n    list_partition_exp_list\n    | DEFAULT\n    ;\n\nclose_cursor_stmt :\n    CLOSE assign_obj2\n    ;\n\nclose_cursor_statement :\n    CLOSE CURSOR assign_obj\n    ;\n\nbegin_trans_stmt :\n    BEGIN TRANSACTION\n    ;\n\ncommit_trans_stmt :\n    commit_head commit_tail?\n    ;\n\ncommit_head :\n    COMMIT work_tag?\n    | COMMITWORK\n    ;\n\ncommit_tail :\n    AND CHAIN\n    | AND NO CHAIN\n    | WRITE\n    | WRITE commit_wait_immed_option\n    | commit_wait_immed_option\n    ;\n\ncommit_wait_immed_option :\n    WAIT\n    | NOWAIT\n    | IMMEDIATE\n    | WAIT IMMEDIATE\n    | NOWAIT IMMEDIATE\n    | IMMEDIATE WAIT\n    | BATCH WAIT\n    | IMMEDIATE NOWAIT\n    | BATCH NOWAIT\n    | AUTO\n    ;\n\nconnect_stmt :\n    CONNECT user_name password\n    ;\n\npassword :\n    id\n    | LT_BINTEGER\n    | LT_DECIMAL\n    | LT_INTEGER\n    | LT_REAL\n    ;\n\nts_storage :\n    ON id\n    | ON LT_INTEGER\n    | ON LT_INTEGER FOR RESTORE\n    ;\n\nts_storage_clause :\n    STORAGE '(' ts_storage ')'\n    ;\n\ncreate_tablespace_stmt :\n    CREATE TABLESPACE not_exist? tablespace_name DATAFILE file_list cache? copy_num? region_size? striping_clause? redundancy_clause? with_huge_clause? ts_storage_clause?\n    | CREATE TABLESPACE not_exist? tablespace_name DATAFILE file_list cache? ENCRYPT WITH cipher_name copy_num? region_size? striping_clause? redundancy_clause? with_huge_clause? ts_storage_clause?\n    | CREATE TABLESPACE not_exist? tablespace_name DATAFILE file_list cache? ENCRYPT WITH cipher_name BY password copy_num? region_size? striping_clause? redundancy_clause? with_huge_clause? ts_storage_clause?\n    | CREATE HUGE TABLESPACE not_exist? tablespace_name PATH pathname copy_num? region_size? striping_clause? redundancy_clause? ts_storage_clause?\n    ;\n\nctss_with_clause :\n    WITH '(' id_list ')'\n    ;\n\ncreate_tablespace_set_stmt :\n    CREATE TABLESPACE SET id ctss_with_clause?\n    ;\n\nalter_tablespace_set_stmt :\n    alter_tag TABLESPACE SET id ADD '(' id_list ')'\n    | alter_tag TABLESPACE SET id DELETE '(' id_list ')'\n    ;\n\ncache :\n    CACHE '=' id\n    ;\n\nalter_tablespace_stmt :\n    alter_tag TABLESPACE tablespace_name alter_tablespace_action\n    | alter_tag HUGE TABLESPACE tablespace_name ADD PATH pathname\n    ;\n\nkeep :\n    KEEP\n    ;\n\nalter_tablespace_action :\n    RENAME TO tablespace_name\n    | RENAME DATAFILE pathname_list TO pathname_list\n    | ADD DATAFILE file_list\n    | DROP DATAFILE pathname\n    | ONLINE\n    | OFFLINE\n    | CACHE '=' id\n    | RESIZE DATAFILE pathname TO LT_INTEGER on_raft?\n    | DATAFILE pathname_list autoextend?\n    | CORRUPT\n    | OPTIMIZE LT_INTEGER\n    | MOVE TO raft_name read_only_flag? keep?\n    | ADD HUGE PATH pathname region_size?\n    ;\n\nfile_list :\n    file (COMMA file)*\n    ;\n\npathname_list :\n    pathname (COMMA pathname)*\n    ;\n\ninteger_list :\n    LT_INTEGER (COMMA LT_INTEGER)*\n    ;\n\nfile :\n    pathname mirror? SIZE LT_INTEGER autoextend?\n    ;\n\nmirror :\n    MIRROR pathname\n    ;\n\nautoextend_nextsize :\n    NEXT LT_INTEGER\n    ;\n\nautoextend_maxsize :\n    MAXSIZE LT_INTEGER\n    | MAXSIZE UNLIMITED\n    ;\n\nautoextend :\n    AUTOEXTEND OFF\n    | AUTOEXTEND ON autoextend_nextsize? autoextend_maxsize?\n    ;\n\non_raft :\n    ON id\n    ;\n\narchfile :\n    archflag? archstyle_options? archdir?\n    ;\n\narchflag :\n    ARCHIVELOG\n    | NOARCHIVELOG\n    ;\n\narchstyle_options :\n    ARCHIVESTYLE archstyle\n    ;\n\narchstyle :\n    LT_STRING\n    ;\n\narchdir :\n    ARCHIVEDIR pathname\n    ;\n\nbakfile :\n    BACKUPDIR pathname\n    ;\n\nparameters_option_list :\n    PARMS '(' parameter_option_list ')'\n    ;\n\nparameter_option_list :\n    parameter_option (COMMA parameter_option)*\n    ;\n\nparameter_option :\n    id DELIMITED BY exp\n    | id exp\n    ;\n\npathname :\n    LT_STRING\n    ;\n\npathname_options :\n    pathname\n    ;\n\nbackup_stmt :\n    BACKUP back_range_option with_bak_dir_list? backup_to_options? backup_path_null backup_desc_options? backup_maxsize? backup_limit? backup_identified? backup_compressed? backup_without? backup_trace_file_level? backup_tsk_thread_num_null backup_parallel_dir?\n    ;\n\nback_range_option :\n    DATABASE backup_options?\n    | TABLESPACE tablespace_name backup_options?\n    | TABLE full_table_name\n    | ARCHIVE LOG back_archive_spec_null\n    | ARCHIVELOG back_archive_spec_null\n    ;\n\nback_archive_spec_null :\n    archive_spec? not_backed_up? backup_delete_archive?\n    ;\n\nnot_backed_up :\n    NOT BACKED UP\n    | NOT BACKED UP LT_INTEGER TIMES\n    | NOT BACKED UP SINCE TIME LT_STRING\n    ;\n\narchive_spec :\n    ALL\n    | FROM LSN spec_lsn\n    | UNTIL LSN spec_lsn\n    | LSN BETWEEN spec_lsn AND spec_lsn\n    | FROM TIME LT_STRING\n    | UNTIL TIME LT_STRING\n    | TIME BETWEEN LT_STRING AND LT_STRING\n    ;\n\nspec_lsn :\n    LT_INTEGER\n    ;\n\nbackup_delete_archive :\n    DELETE INPUT\n    ;\n\nbackup_options :\n    FULL\n    | FULL DDL_CLONE\n    | DDL_CLONE\n    | FULL SHADOW\n    | SHADOW\n    | INCREMENT FROM LSN LT_INTEGER\n    | INCREMENT cumulative? base_on_backup?\n    ;\n\ncumulative :\n    CUMULATIVE\n    ;\n\nwith_bak_dir_list :\n    WITH BACKUPDIR pathname_list\n    ;\n\nbase_on_backup :\n    BASE ON BACKUPSET pathname\n    ;\n\nbackup_to_options :\n    TO backup_name\n    ;\n\nbackup_path_null :\n    device_type? parms_command?\n    | BAKFILE pathname\n    | BACKUPSET pathname_options? device_type? parms_command?\n    ;\n\ndevice_type :\n    DEVICE TYPE media_name\n    ;\n\nparms_command :\n    PARMS LT_STRING\n    ;\n\nmedia_name :\n    id\n    ;\n\nbackup_desc_options :\n    BACKUPINFO backup_desc\n    ;\n\nbackup_desc :\n    LT_STRING\n    ;\n\nbackup_maxsize :\n    MAXSIZE LT_INTEGER\n    | MAXPIECESIZE LT_INTEGER\n    ;\n\nbackup_limit :\n    LIMIT READ SPEED LT_INTEGER\n    | LIMIT WRITE SPEED LT_INTEGER\n    | LIMIT READ SPEED LT_INTEGER WRITE SPEED LT_INTEGER\n    ;\n\nbackup_identified :\n    IDENTIFIED BY password\n    | IDENTIFIED BY password ENCRYPT WITH cipher_name\n    | IDENTIFIED BY password WITH ENCRYPTION LT_INTEGER\n    | IDENTIFIED BY password WITH ENCRYPTION LT_INTEGER ENCRYPT WITH cipher_name\n    ;\n\nbackup_compressed :\n    COMPRESSED\n    | COMPRESSED LEVEL LT_INTEGER\n    ;\n\nbackup_without :\n    WITHOUT LOG\n    | WITHOUT MIRROR\n    | WITHOUT LOG WITHOUT MIRROR\n    ;\n\nbackup_tsk_thread_num_null :\n    tsk_thread_num?\n    ;\n\nbackup_parallel_dir :\n    PARALLEL pathname\n    | PARALLEL\n    | PARALLEL LT_INTEGER\n    | PARALLEL READ SIZE LT_INTEGER\n    | PARALLEL LT_INTEGER READ SIZE LT_INTEGER\n    ;\n\nbackup_trace_file_level :\n    TRACE FILE pathname\n    | TRACE LEVEL LT_INTEGER\n    | TRACE FILE pathname TRACE LEVEL LT_INTEGER\n    | TRACE LEVEL LT_INTEGER TRACE FILE pathname\n    ;\n\nrestore_stmt :\n    RESTORE DATABASE FROM restore_from restore_identified? with_bak_arch_dir_list? res_until? restore_file_list_options? mirror_file_list_options? archfile bakfile? restore_parallel?\n    | RESTORE TABLE full_table_name_options? res_struct? res_without_index_constraint? FROM restore_from restore_identified? restore_trace_file_level?\n    | RESTORE TABLESPACE tablespace_name restore_datafile_lst FROM restore_from restore_identified? with_bak_arch_dir_list? restore_file_list_options? mirror_file_list_options? restore_mapped_file? restore_trace_file_level? restore_tsk_thread_num_null restore_parallel?\n    | RESTORE TABLESPACE tablespace_name FROM restore_from restore_identified? with_bak_arch_dir_list? restore_file_list_options? mirror_file_list_options? restore_mapped_file? restore_trace_file_level? restore_tsk_thread_num_null restore_parallel? res_until?\n    ;\n\nrestore_datafile_lst :\n    DATAFILE pathname_list\n    | DATAFILE integer_list\n    ;\n\nrestore_mapped_file :\n    mapped_file\n    ;\n\nmapped_file :\n    MAPPED FILE LT_STRING\n    ;\n\nres_struct :\n    STRUCT\n    ;\n\ntsk_thread_num :\n    TASK THREAD LT_INTEGER\n    ;\n\nrestore_tsk_thread_num_null :\n    tsk_thread_num?\n    ;\n\nrestore_parallel :\n    NOT PARALLEL\n    ;\n\nfull_table_name_options :\n    full_table_name\n    ;\n\nres_without_index_constraint :\n    WITH INDEX\n    | WITH INDEX WITH CONSTRAINT\n    | WITH INDEX WITHOUT CONSTRAINT\n    | WITHOUT INDEX\n    | WITHOUT INDEX WITH CONSTRAINT\n    | WITHOUT INDEX WITHOUT CONSTRAINT\n    | WITH CONSTRAINT\n    | WITHOUT CONSTRAINT\n    ;\n\nrestore_from :\n    pathname\n    | BACKUP backup_name\n    | BACKUPSET pathname device_type? parms_command?\n    ;\n\nres_until :\n    UNTIL TIME LT_STRING\n    | UNTIL LSN LT_INTEGER\n    | UNTIL TIME LT_STRING UNTIL LSN LT_INTEGER\n    | UNTIL LSN LT_INTEGER UNTIL TIME LT_STRING\n    ;\n\nrestore_file_list_options :\n    restore_file_list\n    ;\n\nmirror_file_list_options :\n    mirror_file_list\n    ;\n\nrestore_trace_file_level :\n    TRACE FILE pathname\n    | TRACE LEVEL LT_INTEGER\n    | TRACE FILE pathname TRACE LEVEL LT_INTEGER\n    | TRACE LEVEL LT_INTEGER TRACE FILE pathname\n    ;\n\nrestore_file_list :\n    restore_file (COMMA restore_file)*\n    ;\n\nrestore_file :\n    DBFILE LT_INTEGER TO pathname\n    ;\n\nmirror_file_list :\n    mirror_file (COMMA mirror_file)*\n    ;\n\nmirror_file :\n    MIRROR LT_INTEGER TO pathname\n    ;\n\nwith_bak_arch_dir_list :\n    WITH BACKUPDIR pathname_list\n    | WITH ARCHIVEDIR pathname_list\n    | WITH BACKUPDIR pathname_list WITH ARCHIVEDIR pathname_list\n    ;\n\nrestore_identified :\n    IDENTIFIED BY password\n    | IDENTIFIED BY password ENCRYPT WITH cipher_name\n    ;\n\ncreate_func_stmt :\n    CREATE replace_option? FUNCTION not_exist? full_func_name (func_def_inner | (WRAPPED LT_STRING))\n    ;\n\nfunc_aggr_clause :\n    AGGREGATE USING plsql_datatype\n    ;\n\npipelined_options :\n    PIPELINED\n    ;\n\nreplace_option :\n    OR REPLACE\n    ;\n\nedit_options :\n    EDITIONABLE\n    | NONEDITIONABLE\n    ;\n\nencryption_option :\n    WITH ENCRYPTION\n    ;\n\ncalc_option :\n    FOR CALCULATE\n    ;\n\nfunc_action :\n    is_as dmsubprogram\n    | EXTERNAL pathname inner_fun_name? USING platform_type\n    | func_aggr_clause\n    | PIPELINED is_as dmsubprogram\n    | PIPELINED USING plsql_datatype\n    ;\n\nfunc_call_options :\n    func_call_option_list\n    ;\n\nfunc_call_option_list :\n    func_call_option+\n    ;\n\nfunc_call_option :\n    invoker_rights_clause\n    | deterministic_clause\n    | PARALLEL_ENABLE\n    | result_cache_clause\n    ;\n\ninvoker_rights_clause_options :\n    invoker_rights_clause\n    ;\n\ninvoker_rights_clause :\n    AUTHID DEFINER\n    | AUTHID CURRENT_USER\n    ;\n\ndeterministic_clause_options :\n    deterministic_clause\n    ;\n\ndeterministic_clause :\n    DETERMINISTIC\n    ;\n\nfunc_call_option2_options :\n    func_call_option_list2\n    ;\n\nfunc_call_option_list2 :\n    func_call_option2+\n    ;\n\nfunc_call_option2 :\n    deterministic_clause\n    | result_cache_clause\n    | PARALLEL_ENABLE\n    ;\n\nresult_cache_clause :\n    RESULT_CACHE\n    ;\n\ninner_fun_name :\n    qualified_name\n    ;\n\nplatform_type :\n    id\n    ;\n\nparam_def_list_option :\n    '(' ')'\n    | '(' param_def_list ')'\n    ;\n\nparam_def_list :\n    param_def\n    | param_def COMMA param_def_list\n    ;\n\nparam_def :\n    param_name param_in_out_option? plsql_datatype default_clause_option?\n    ;\n\nparam_in_out_option :\n    IN\n    | OUT\n    | IN OUT\n    | OUT IN\n    | OUT NOCOPY\n    | IN OUT NOCOPY\n    | OUT IN NOCOPY\n    ;\n\nis_as :\n    IS\n    | AS\n    ;\n\n\n\nstat_on_org_stmt :\n    STAT stat_para stat_size? ON qualified_name '(' column_list ')' global_tag?\n    | STAT stat_para stat_size? ON INDEX qualified_name global_tag?\n    | STAT ON qualified_name global_tag?\n    ;\n\nstat_size :\n    SIZE LT_INTEGER\n    ;\n\nstat_para :\n    LT_INTEGER\n    | LT_DECIMAL\n    | LT_REAL\n    ;\n\nstat_summarize :\n    COLUMN LT_INTEGER LT_REAL LT_INTEGER LT_REAL\n    | COLUMN stm_param stm_param stm_param stm_param\n    ;\n\n\nmstat_ex :\n    BY without_into_select\n    ;\n\nindexid :\n    LT_INTEGER\n    ;\n\nglobal_tag :\n    GLOBAL\n    ;\n\nbm_join_index_clause :\n    from_clause WHERE search_condition\n    ;\n\nparallel_stmt :\n    NOPARALLEL\n    | PARALLEL\n    | PARALLEL LT_INTEGER\n    ;\n\ncreate_index_stmt :\n    CREATE replace_option? partition_tag? unique_tag? INDEX not_exist? index_name with_inner? ON full_table_name '(' index_column_list ')' bm_join_index_clause? global_tag? partition_clause? storage_tag? index_no_sort? online_options? reverse_options? unusable_options? parallel_stmt?\n    ;\n\nwith_inner :\n    WITH INNER\n    ;\n\nindex_no_sort :\n    NOSORT\n    ;\n\nonline_options :\n    ONLINE\n    ;\n\nunusable_options :\n    UNUSABLE\n    ;\n\nreverse_options :\n    REVERSE\n    ;\n\nindex_column_list :\n    index_column_name (COMMA index_column_name)*\n    ;\n\nindex_column_name :\n    exp asc_desc_option?\n    ;\n\nstorage_hash_tag :\n    STORE IN storage_hash\n    ;\n\nstorage_hash :\n    '(' id_list ')'\n    ;\n\nstorage_tag :\n    storage_tag_nn\n    | tablespace_clause\n    | tablespace_clause storage_tag_nn\n    | storage_tag_nn tablespace_clause\n    ;\n\nstorage_tag_nn :\n    STORAGE '(' storage_list ')'\n    ;\n\ntablespace_clause :\n    TABLESPACE id local_option?\n    ;\n\nobject_table_substitution_clause :\n    object_table_substitution\n    ;\n\nobject_table_substitution :\n    SUBSTITUTABLE AT_KEYWORD ALL LEVELS\n    | NOT SUBSTITUTABLE AT_KEYWORD ALL LEVELS\n    ;\n\noid_clause :\n    OBJECT IDENTIFIER_KEYWORD IS oid_gen_type\n    ;\n\noid_gen_type :\n    SYSTEM GENERATED\n    | PRIMARY KEY\n    ;\n\noid_index_clause :\n    OIDINDEX id\n    | OIDINDEX id oid_tablespace_clause\n    | OIDINDEX oid_tablespace_clause\n    ;\n\noid_tablespace_clause :\n    '(' oid_tablespace_name? ')'\n    ;\n\noid_tablespace_name :\n    TABLESPACE id\n    \n    ;\n\nlocal_option :\n    LOCAL\n    ;\n\nstorage_list :\n    storage (COMMA storage)*\n    ;\n\nstorage_hashpartmap :\n    HASHPARTMAP '(' LT_INTEGER ')'\n    ;\n\nstorage :\n    INITIAL LT_INTEGER\n    | NEXT LT_INTEGER\n    | MINEXTENTS LT_INTEGER\n    | ON PRIMARY\n    | ON id\n    | FILLFACTOR LT_INTEGER\n    | CACHE '=' id\n    | BRANCH LT_INTEGER\n    | BRANCH '(' LT_INTEGER COMMA LT_INTEGER ')'\n    | NOBRANCH\n    | CLUSTERBTR\n    | SECTION '(' LT_INTEGER ')'\n    | STAT storage_stat_flag? storage_stat_cols?\n    | FILESIZE '(' LT_INTEGER ')'\n    | WITH COUNTER\n    | WITHOUT COUNTER\n    | WITH DELTA\n    | WITHOUT DELTA\n    | USING LONG ROW\n    | storage_hashpartmap\n    ;\n\nid_list :\n    PRIMARY\n    | id\n    | id COMMA id_list\n    | PRIMARY COMMA id_list\n    ;\n\ncreate_proc_stmt :\n    CREATE replace_option? PROCEDURE not_exist? full_proc_name2 (WITH ENCRYPTION)? param_def_list_option? invoker_rights_clause_options? func_action\n    | CREATE replace_option? PROCEDURE not_exist? full_proc_name2 WRAPPED LT_STRING\n    ;\n\ncreate_package_stmt :\n    CREATE replace_option? edit_options? pkg_cls_flag not_exist? full_proc_name2 encryption_option? under_option? final_inst_list_options? invoker_rights_clause_options? is_as package_def_list_options? blk_end_option\n    | CREATE replace_option? edit_options? pkg_cls_flag not_exist? full_proc_name2 WRAPPED LT_STRING\n    ;\n\npkg_cls_flag :\n    PACKAGE\n    | CLASS\n    ;\n\nblk_end_option :\n    blk_end_option_low\n    ;\n\nblk_end_option_low :\n    END\n    | END id\n    ;\n\npackage_def_list_options :\n    package_def_list\n    ;\n\npackage_def_list :\n    package_def+\n    ;\n\npackage_def :\n    decl_variable\n    | decl_cursor SEMI\n    | decl_except\n    | pragma_def\n    | PRAGMA RESTRICT_REFERENCES '(' restrict_param_lst ')' SEMI\n    | decl_plsql_type\n    | method_inherit_options? method_attr_options? member_static? PROCEDURE id param_def_list_option? SEMI\n    | method_inherit_options? method_attr_options? member_static? FUNCTION id param_def_list_option? RETURN plsql_datatype func_call_option2_options? pipelined_options? SEMI\n    | method_inherit_options? method_attr_options? member_static? FUNCTION id param_def_list_option? RETURN plsql_datatype func_call_option2_options? PIPELINED USING plsql_datatype SEMI\n    ;\n\nrestrict_param_lst :\n    id_list\n    | DEFAULT COMMA id_list\n    ;\n\ncreate_package_body_stmt :\n    create_pkg_body_header encryption_option? is_as package_body_def_list package_body_init_option? blk_end_option\n    | create_pkg_body_header encryption_option? is_as package_body_init_option? blk_end_option\n    | create_pkg_body_header WRAPPED LT_STRING\n    ;\n\ncreate_pkg_body_header :\n    CREATE replace_option? edit_options? pkg_cls_body_flag full_proc_name2\n    ;\n\npkg_cls_body_flag :\n    PACKAGE BODY\n    | CLASS BODY\n    ;\n\npackage_body_init_option :\n    decl_var_cur_list_1? BEGIN plbody except_option?\n    ;\n\npackage_body_def_list :\n    package_def\n    | package_body_def\n    | package_def package_body_def_list\n    | package_body_def package_body_def_list\n    ;\n\npackage_body_def :\n    method_inherit_options? method_attr_options? member_static? PROCEDURE id param_def_list_option? check_exec_options? is_as dmsubprogram SEMI\n    | method_inherit_options? method_attr_options? member_static? FUNCTION id param_def_list_option? RETURN plsql_datatype func_call_option2_options? pipelined_options? check_exec_options? is_as dmsubprogram SEMI\n    ;\n\npackage_body_def2 :\n    PROCEDURE id param_def_list_option? check_exec_options? is_as dmsubprogram SEMI\n    | FUNCTION id param_def_list_option? RETURN plsql_datatype deterministic_clause_options? pipelined_options? check_exec_options? is_as dmsubprogram SEMI\n    ;\n\ncheck_exec_options :\n    EXECUTE CHECK\n    | EXECUTE NOT CHECK\n    ;\n\nsubpg_decl_stmt :\n    method_inherit_options? method_attr_options? member_static? PROCEDURE id param_def_list_option? SEMI\n    | method_inherit_options? method_attr_options? member_static? FUNCTION id param_def_list_option? RETURN plsql_datatype SEMI\n    ;\n\ncreate_type_stmt :\n    CREATE replace_option? TYPE full_proc_name2 encryption_option? invoker_rights_clause_options? force_option? object_option '(' object_def_list_options? ')' final_inst_list_options?\n    | CREATE replace_option? TYPE full_proc_name2 encryption_option? invoker_rights_clause_options? force_option? is_as plsql_type_def\n    | CREATE replace_option? TYPE full_proc_name2 WRAPPED LT_STRING\n    ;\n\nforce_option :\n    FORCE\n    ;\n\nobject_option :\n    is_as OBJECT\n    | UNDER full_proc_name\n    ;\n\nunder_option :\n    UNDER full_proc_name\n    ;\n\nobject_def_list_options :\n    object_def_list\n    ;\n\nobject_def_list :\n    object_def (COMMA object_def)*\n    ;\n\nobject_def :\n    variable_name_list plsql_datatype\n    | method_inherit_options? method_attr_options? member_static? PROCEDURE id param_def_list_option?\n    | method_inherit_options? method_attr_options? member_static? FUNCTION id param_def_list_option? RETURN plsql_datatype deterministic_clause_options? pipelined_options?\n    | method_inherit_options? method_attr_options? member_static? FUNCTION id param_def_list_option? RETURN plsql_datatype deterministic_clause_options? PIPELINED USING plsql_datatype\n    | method_inherit_options? CONSTRUCTOR FUNCTION id param_def_list_option? RETURN SELF AS RESULT\n    | PRAGMA RESTRICT_REFERENCES '(' restrict_param_lst ')'\n    ;\n\nmember_static :\n    MEMBER\n    | STATIC\n    ;\n\nmethod_inherit_options :\n    method_inherit_option\n    ;\n\nmethod_inherit_option :\n    overriding_option\n    | final_inst_list\n    | overriding_option final_inst_list\n    ;\n\nfinal_inst_list_options :\n    final_inst_list\n    ;\n\nfinal_inst_list :\n    final_inst\n    | final_inst final_inst_list\n    ;\n\nfinal_inst :\n    FINAL\n    | INSTANTIABLE\n    | NOT FINAL\n    | NOT INSTANTIABLE\n    ;\n\noverriding_option :\n    OVERRIDING\n    | NOT OVERRIDING\n    ;\n\nmethod_attr_options :\n    method_attr\n    ;\n\nmethod_attr :\n    MAP\n    | ORDER\n    ;\n\ncreate_type_body_stmt :\n    CREATE replace_option? TYPE BODY full_proc_name2 encryption_option? is_as object_body_def_list END\n    | CREATE replace_option? TYPE BODY full_proc_name2 WRAPPED LT_STRING\n    ;\n\nobject_body_def_list :\n    object_body_def\n    | object_body_def object_body_def_list\n    ;\n\nobject_body_def :\n    method_inherit_options? method_attr_options? member_static? PROCEDURE id param_def_list_option? is_as dmsubprogram SEMI\n    | method_inherit_options? method_attr_options? member_static? FUNCTION id param_def_list_option? RETURN plsql_datatype deterministic_clause_options? pipelined_options? is_as dmsubprogram SEMI\n    | method_inherit_options? CONSTRUCTOR FUNCTION id param_def_list_option? RETURN SELF AS RESULT is_as dmsubprogram SEMI\n    ;\n\ncreate_context_stmt :\n    CREATE replace_option? CONTEXT not_exist? namespace USING full_object_name initialized?\n    ;\n\nnamespace :\n    id\n    ;\n\ninitialized :\n    ACCESSED LOCALLY\n    | ACCESSED GLOBALLY\n    | INITIALIZED EXTERNALLY\n    | INITIALIZED GLOBALLY\n    ;\n\ncreate_directory_stmt :\n    CREATE replace_option? DIRECTORY not_exist? id AS LT_STRING\n    ;\n\ncreate_crypto_stmt :\n    CREATE CRYPTO crypto_name pathname\n    ;\n\nalter_crypto_stmt :\n    alter_tag CRYPTO crypto_name alter_crypto_action\n    ;\n\nalter_crypto_action :\n    RENAME TO crypto_name\n    | ADD BLOCK ENCRYPT CIPHER cipher_name INNERID LT_INTEGER BLOCK SIZE LT_INTEGER KEY SIZE LT_INTEGER\n    | ADD ENCRYPT CIPHER cipher_name INNERID LT_INTEGER KEY SIZE LT_INTEGER\n    | ADD HASH CIPHER cipher_name INNERID LT_INTEGER HASH SIZE LT_INTEGER\n    | MODIFY CIPHER cipher_name RENAME TO cipher_name\n    | DROP CIPHER cipher_name\n    | ADD CRYPTO HASH LT_STRING\n    | DROP CRYPTO HASH LT_STRING\n    ;\n\ncomment_stmt :\n    comment_tag ON TABLE full_table_name IS LT_STRING\n    | comment_tag ON COLUMN full_column_name IS LT_STRING\n    | comment_tag ON VIEW full_view_name IS LT_STRING\n    ;\n\ncomment_tag :\n    COMMENT\n    ;\n\ncreate_partition_group_stmt :\n    CREATE PARTITION GROUP full_table_name PARTITION BY horizon_partition_act_datatype storage_act_datatype?\n    ;\n\nstorage_act_datatype :\n    STORAGE '(' pg_storage_lst ')'\n    | STORAGE '(' ON full_column_list ')'\n    ;\n\npg_storage_lst :\n    pg_storage (COMMA pg_storage)*\n    ;\n\npg_storage :\n    ON '(' full_column_list ')'\n    | storage_hashpartmap\n    ;\n\ncreate_table_stmt :\n    CREATE table_temp_option? table_type_option? TABLE not_exist? create_table_action\n    | CREATE HUGE TABLE not_exist? create_table_action\n    | CREATE SNAPSHOT TABLE not_exist? full_table_name FROM full_table_name\n    ;\n\nctab_append_attr_clause :\n    ctab_append_attr_list\n    ;\n\nctab_append_attr_list :\n    ctab_append_attr+\n    ;\n\ncobjtab_append_attr_clause :\n    cobjtab_append_attr_list\n    ;\n\ncobjtab_append_attr_list :\n    cobjtab_append_attr\n    | cobjtab_append_attr cobjtab_append_attr_list\n    ;\n\nctab_append_attr :\n    on_commit_option_nn\n    | logging_option_nn\n    | partition_clause_nn\n    | space_limit_nn\n    | storage_tag_nn\n    | tablespace_clause\n    ;\n\ncobjtab_append_attr :\n    oid_clause\n    | oid_index_clause\n    ;\n\ncreate_table_action :\n    full_table_name '(' table_element_list ')' ctab_append_attr_clause? compress_tag? rowdependencies_clause? ctab_row_movement_clause? ctab_log_options? advance_log_clause? add_log_clause? ctab_error_options? distribute_by? increment?\n    | full_table_name '(' table_element_list ')' FROM DEFAULT DIRECTORY id LOCATION '(' pathname ')'\n    | full_table_name '(' table_element_list ')' FROM DATAFILE? pathname parameters_option_list?\n    | full_table_name '(' table_element_list ')' FROM DATAFILE DEFAULT DIRECTORY id LOCATION '(' pathname ')' parameters_option_list?\n    | full_table_name on_commit_option? logging_option? (PARTITION BY horizon_partition_act)? space_limit? storage_tag? compress_tag? rowdependencies_clause? ctab_log_options? advance_log_clause? add_log_clause? ctab_error_options? AS without_into_select2 distribute_by? increment?\n    | full_table_name on_commit_option? logging_option? space_limit? storage_tag? compress_tag? rowdependencies_clause? ctab_log_options? advance_log_clause? add_log_clause? ctab_error_options? LIKE normal_tv increment?\n    | full_table_name '(' table_element_list ')' USING PARTITION GROUP full_table_name BY '(' column_list ')' pg_sub_partition? lock_partitions_clause? storage_tag? compress_tag? rowdependencies_clause? ctab_row_movement_clause? ctab_log_options? advance_log_clause? add_log_clause? ctab_error_options?\n    | full_table_name OF qualified_name object_table_substitution_clause? objtab_elem_constraint? cobjtab_append_attr_clause? ctab_append_attr_clause? compress_tag? rowdependencies_clause? ctab_row_movement_clause? ctab_log_options? advance_log_clause? add_log_clause? ctab_error_options? distribute_by? increment?\n    ;\n\nctab_log_options :\n    LOG ctab_log_option\n    ;\n\nctab_log_option :\n    ALL\n    | NONE\n    | LOB NONE\n    | LAST\n    ;\n\nctab_error_options :\n    WHEN ERROR ctab_error_option\n    ;\n\nadvance_log_clause :\n    WITH ADVANCED LOG\n    ;\n\nadd_log_clause :\n    ADD LOGIC LOG\n    ;\n\nctab_error_option :\n    TRUNCATE\n    | DISABLE\n    ;\n\nctab_row_movement_clause :\n    ENABLE ROW MOVEMENT\n    | DISABLE ROW MOVEMENT\n    ;\n\nrange_distribute_act :\n    VALUES LESS THAN '(' range_partition_exp_list ')' ON id\n    | VALUES EQU OR LESS THAN '(' range_partition_exp_list ')' ON id\n    ;\n\nrange_distribute_act_lst :\n    range_distribute_act\n    | range_distribute_act_lst COMMA range_distribute_act\n    ;\n\nlist_distribute_act :\n    VALUES '(' list_partition_value_list ')' ON id\n    ;\n\nlist_distribute_act_list :\n    list_distribute_act (COMMA list_distribute_act)*\n    ;\n\ndistribute_by_option :\n    DISTRIBUTED\n    | DISTRIBUTED FULLY\n    | DISTRIBUTED RANDOMLY\n    | DISTRIBUTED BY '(' column_list ')'\n    | DISTRIBUTED BY HASH '(' column_list ')'\n    | DISTRIBUTED BY RANGE '(' column_list ')' '(' range_distribute_act_lst ')'\n    | DISTRIBUTED BY LIST '(' column_list ')' '(' list_distribute_act_list ')'\n    ;\n\ndistribute_by :\n    distribute_by_option\n    ;\n\nincrement_set :\n    AUTO_INCREMENT '=' LT_INTEGER\n    | AUTO_INCREMENT LT_INTEGER\n    ;\n\nincrement :\n    increment_set\n    ;\n\nrowdependencies_clause :\n    ROWDEPENDENCIES\n    | NOROWDEPENDENCIES\n    ;\n\npg_sub_partition :\n    SUBPARTITION BY '(' column_list ')'\n    ;\n\ntable_type_option :\n    VERTICAL\n    | EXTERNAL\n    ;\n\ntable_temp_option :\n    GLOBAL TEMPORARY\n    | LOCAL TEMPORARY\n    | TEMPORARY\n    | SHARE TEMPORARY\n    ;\n\nobjtab_elem_constraint :\n    '(' objtab_element_cons_list ')'\n    ;\n\nobjtab_element_cons_list :\n    objtab_element_cons (COMMA objtab_element_cons_list)*\n    ;\n\nobjtab_element_cons :\n    objcol_constraint\n    | table_constraint_def\n    ;\n\nobjcol_constraint :\n    column_name charset_option? collate_clause_option? column_def_4_option? storage_tag? encrypt_clause_options? compress_clause_opt?\n    ;\n\ntable_element_list :\n    table_element (COMMA table_element)*\n    ;\n\ntable_element :\n    column_def_ex\n    | table_constraint_def\n    ;\n\ntable_constraint_def :\n    constraint_name_def_options? table_constraint_clause cons_enable?\n    ;\n\non_commit_option :\n    on_commit_option_nn\n    ;\n\non_commit_option_nn :\n    ON COMMIT del_res ROWS\n    ;\n\nlogging_option :\n    logging_option_nn\n    ;\n\nlogging_option_nn :\n    LOGGING\n    | NOLOGGING\n    ;\n\npartition_clause :\n    partition_clause_nn\n    ;\n\npartition_clause_nn :\n    PARTITION BY partition_act\n    ;\n\nhorizon_partition_clause :\n    PARTITION BY horizon_partition_act\n    ;\n\ncompress_tag_hdr :\n    COMPRESS compress_level? compress_type?\n    ;\n\ncompress_clause_opt :\n    compress_tag_hdr\n    ;\n\ncompress_tag :\n    compress_tag_hdr\n    | compress_tag_hdr '(' column_list ')'\n    | compress_tag_hdr EXCEPT '(' column_list ')'\n    ;\n\ncompress_level :\n    LEVEL LT_INTEGER\n    ;\n\ncompress_type :\n    FOR LT_STRING\n    ;\n\nrange_partition :\n    PARTITION full_partition_name VALUES LESS THAN '(' range_partition_exp_list ')' storage_tag? subpartition_desc_option?\n    | PARTITION full_partition_name VALUES EQU OR LESS THAN '(' range_partition_exp_list ')' storage_tag? subpartition_desc_option?\n    ;\n\nrange_partition_list :\n    range_partition (COMMA range_partition)*\n    ;\n\nhash_partition :\n    PARTITION full_partition_name storage_tag? subpartition_desc_option?\n    ;\n\nhash_partition_list :\n    hash_partition (COMMA hash_partition)*\n    ;\n\nlist_partition :\n    PARTITION full_partition_name VALUES '(' list_partition_value_list ')' storage_tag? subpartition_desc_option?\n    ;\n\nlist_partition_list :\n    list_partition (COMMA list_partition)*\n    ;\n\nsplit_partition_list :\n    hash_partition (COMMA hash_partition)*\n    ;\n\npartition_act :\n    horizon_partition_act\n    | vertical_partition_act\n    ;\n\nvertical_partition_act :\n    COLUMN '(' column_list ')' as_alias?\n    | COLUMN '(' column_list_list ')'\n    ;\n\ninterval_item :\n    INTERVAL '(' exp ')'\n    ;\n\nhorizon_partition_act_datatype :\n    RANGE '(' datatype_list ')' subpartion_template_list_datatype_options? '(' range_partition_list ')'\n    | HASH '(' datatype_list ')' subpartion_template_list_datatype_options? PARTITIONS (LT_INTEGER | DEFAULT) storage_hash_tag?\n    | HASH '(' datatype_list ')' subpartion_template_list_datatype_options? '(' hash_partition_list ')'\n    | LIST '(' datatype_list ')' subpartion_template_list_datatype_options? '(' list_partition_list ')'\n    ;\n\nhorizon_partition_act :\n    RANGE '(' column_list ')' interval_item? subpartion_template_list_options? '(' range_partition_list ')' lock_partitions_clause?\n    | HASH '(' column_list ')' subpartion_template_list_options? PARTITIONS (LT_INTEGER | DEFAULT) storage_hash_tag? lock_partitions_clause?\n    | HASH '(' column_list ')' subpartion_template_list_options? '(' hash_partition_list ')' lock_partitions_clause?\n    | LIST '(' column_list ')' subpartion_template_list_options? '(' list_partition_list ')' lock_partitions_clause?\n    | REFERENCE '(' constraint_name ')'\n    ;\n\nlock_partitions_clause :\n    LOCK ROOT\n    | LOCK PARTITIONS\n    ;\n\nsubpartion_template_list_datatype_options :\n    subpartion_template_list_datatype\n    ;\n\nsubpartion_template_list_datatype :\n    subpartion_template_datatype (COMMA subpartion_template_datatype)*\n    ;\n\nsubpartion_template_list_options :\n    subpartion_template_list\n    ;\n\nsubpartion_template_list :\n    subpartion_template (COMMA subpartion_template)*\n    ;\n\nsubpartion_template_datatype :\n    range_subpartion_template_datatype\n    | hash_subpartion_template_datatype\n    | list_subpartion_template_datatype\n    ;\n\nrange_subpartion_template_datatype :\n    SUBPARTITION BY RANGE '(' datatype_list ')'\n    | SUBPARTITION BY RANGE '(' datatype_list ')' SUBPARTITION TEMPLATE '(' range_subpartition_list ')'\n    ;\n\nhash_subpartion_template_datatype :\n    SUBPARTITION BY HASH '(' datatype_list ')' ((SUBPARTITION TEMPLATE)? hash_subpartions_template_datatype_option)?\n    | SUBPARTITION BY HASH '(' datatype_list ')' SUBPARTITION TEMPLATE '(' hash_subpartition_list ')'\n    ;\n\nhash_subpartions_template_datatype_option :\n    SUBPARTITIONS (LT_INTEGER | DEFAULT) storage_hash_tag?\n    ;\n\nlist_subpartion_template_datatype :\n    SUBPARTITION BY LIST '(' datatype_list ')'\n    | SUBPARTITION BY LIST '(' datatype_list ')' SUBPARTITION TEMPLATE '(' list_subpartition_list ')'\n    ;\n\nsubpartion_template :\n    range_subpartion_template\n    | hash_subpartion_template\n    | list_subpartion_template\n    ;\n\nrange_subpartion_template :\n    SUBPARTITION BY RANGE '(' column_list ')'\n    | SUBPARTITION BY RANGE '(' column_list ')' SUBPARTITION TEMPLATE '(' range_subpartition_list ')'\n    ;\n\nhash_subpartion_template :\n    SUBPARTITION BY HASH '(' column_list ')' ((SUBPARTITION TEMPLATE)? hash_subpartions_template_option)?\n    | SUBPARTITION BY HASH '(' column_list ')' SUBPARTITION TEMPLATE '(' hash_subpartition_list ')'\n    ;\n\nhash_subpartions_template_option :\n    SUBPARTITIONS (LT_INTEGER | DEFAULT) storage_hash_tag?\n    ;\n\nlist_subpartion_template :\n    SUBPARTITION BY LIST '(' column_list ')' (SUBPARTITION TEMPLATE '(' list_subpartition_list ')')?\n    ;\n\nrange_subpartition :\n    SUBPARTITION full_partition_name VALUES LESS THAN '(' range_partition_exp_list ')' storage_tag?\n    | SUBPARTITION full_partition_name VALUES EQU OR LESS THAN '(' range_partition_exp_list ')' storage_tag?\n    ;\n\nhash_subpartition :\n    SUBPARTITION full_partition_name storage_tag?\n    ;\n\nlist_subpartition :\n    SUBPARTITION full_partition_name VALUES '(' list_partition_value_list ')' storage_tag?\n    ;\n\nrange_subpartition_list :\n    range_subpartition (COMMA range_subpartition)*\n    ;\n\nhash_subpartition_list :\n    hash_subpartition (COMMA hash_subpartition)*\n    ;\n\nlist_subpartition_list :\n    list_subpartition (COMMA list_subpartition)*\n    ;\n\nsubpartition_hash_desc :\n    hash_subpartition subpartition_desc_option?\n    ;\n\nsubpartition_range_desc :\n    range_subpartition subpartition_desc_option?\n    ;\n\nsubpartition_list_desc :\n    list_subpartition subpartition_desc_option?\n    ;\n\nsubpartition_hash_desc_list :\n    subpartition_hash_desc (COMMA subpartition_hash_desc)*\n    ;\n\nsubpartition_range_desc_list :\n    subpartition_range_desc (COMMA subpartition_range_desc)*\n    ;\n\nsubpartition_list_desc_list :\n    subpartition_list_desc (COMMA subpartition_list_desc)*\n    ;\n\nsubpartition_desc :\n    '(' subpartition_range_desc_list ')'\n    | '(' subpartition_hash_desc_list ')'\n    | '(' subpartition_list_desc_list ')'\n    | SUBPARTITIONS LT_INTEGER storage_hash_tag?\n    ;\n\nsubpartition_desc_option :\n    subpartition_desc\n    ;\n\nadd_subpartition_desc :\n    subpartition_range_desc_list\n    | subpartition_hash_desc_list\n    | subpartition_list_desc_list\n    ;\n\npartition_no :\n    RANGE LT_INTEGER\n    | LT_INTEGER\n    ;\n\ncomment_clause :\n    COMMENT LT_STRING\n    ;\n\nencrypt_clause_options :\n    encrypt_clause\n    ;\n\nencrypt_clause :\n    NO ENCRYPT\n    | ENCRYPT\n    | ENCRYPT encrypt_cipher\n    | ENCRYPT encrypt_cipher hash_cipher\n    | FULL ENCRYPT WITH full_cipher_name\n    ;\n\nencrypt_cipher :\n    WITH full_cipher_name\n    | WITH full_cipher_name encrypt_type\n    | encrypt_type\n    ;\n\ncrypto_name :\n    id\n    ;\n\ncipher_name :\n    id\n    ;\n\nfull_cipher_name :\n    id\n    ;\n\nencrypt_type :\n    MANUAL\n    | MANUAL manual_clause\n    | AUTO\n    | AUTO BY password\n    | AUTO BY WRAPPED LT_STRING\n    ;\n\nmanual_clause :\n    user_clause\n    | BY password user_clause_options?\n    | BY WRAPPED LT_STRING user_clause_options?\n    ;\n\nuser_clause_options :\n    user_clause\n    ;\n\nuser_clause :\n    USER '(' user_list_option? ')'\n    ;\n\nuser_list_option :\n    user_list\n    ;\n\nuser_list :\n    user_name (COMMA user_list)*\n    ;\n\nhash_cipher :\n    HASH WITH full_cipher_name\n    | HASH WITH full_cipher_name hash_type\n    ;\n\nhash_type :\n    SALT\n    | NO SALT\n    ;\n\nspace_limit :\n    space_limit_nn\n    ;\n\nspace_limit_nn :\n    DISKSPACE LIMIT LT_INTEGER\n    | DISKSPACE UNLIMITED\n    ;\n\nspace_limit_1 :\n    DISKSPACE LIMIT LT_INTEGER\n    | DISKSPACE UNLIMITED\n    ;\n\nspace_limit2 :\n    DISKSPACE LIMIT LT_INTEGER\n    | DISKSPACE UNLIMITED\n    ;\n\ndel_res :\n    DELETE\n    | PRESERVE\n    ;\n\ntrig_enable :\n    ENABLE\n    | DISABLE\n    ;\n\nat_raft :\n    EXECUTE AT_KEYWORD id\n    | EXECUTE AT_KEYWORD LT_INTEGER\n    ;\n\ncreate_trigger_stmt :\n    CREATE replace_option? TRIGGER full_trigger_name2 (WITH ENCRYPTION)?  before_after\n    ((trig_del_ins_upd_list local? ON full_table_name2) | (trig_event_list local? ON event_object at_raft?))\n    trig_referencing_def_options? trig_for_each_option? trig_when_option? trig_enable? dmsubprogram\n    | CREATE replace_option? TRIGGER full_trigger_name2 WRAPPED LT_STRING\n    ;\n\nbefore_after :\n    BEFORE\n    | AFTER\n    | INSTEAD OF\n    ;\n\ntrig_del_ins_upd_list :\n    (trig_del_ins_upd (OF column_list)?) (OR (trig_del_ins_upd (OF column_list)?))*\n    ;\n\ntrig_del_ins_upd :\n    DELETE\n    | INSERT\n    | UPDATE\n    ;\n\nupdate_of_option :\n    UPDATE nowait?\n    | UPDATE OF full_column_list nowait?\n    ;\n\nnowait :\n    NOWAIT\n    | WAIT LT_INTEGER\n    | SKIP_KEYWORD LOCKED\n    | LT_INTEGER SKIP_KEYWORD LOCKED\n    ;\n\ntrig_event_list :\n    trig_event (OR trig_event)*\n    ;\n\ntrig_event :\n    CREATE\n    | ALTER\n    | DROP\n    | AUDIT\n    | NOAUDIT\n    | GRANT\n    | REVOKE\n    | TRUNCATE\n    | ANALYZE\n    | LOGIN\n    | LOGON\n    | LOGOUT\n    | LOGOFF\n    | SERERR\n    | BACKUP DATABASE\n    | RESTORE DATABASE\n    | TIMER\n    | STARTUP\n    | SHUTDOWN\n    | COMMENT\n    | DDL\n    | CHECKPOINT\n    ;\n\nevent_object :\n    qualified_name '.' SCHEMA\n    | SCHEMA\n    | DATABASE\n    ;\n\ntrig_referencing_def_options :\n    trig_referencing_def\n    ;\n\ntrig_referencing_def :\n    REFERENCING trig_referencing_list\n    ;\n\ntrig_referencing_list :\n    trig_referencing_old\n    | trig_referencing_new\n    | trig_referencing_old trig_referencing_new\n    ;\n\ntrig_referencing_old :\n    OLD row_tag? as_tag? trig_old_name\n    ;\n\ntrig_referencing_new :\n    NEW row_tag? as_tag? trig_new_name\n    ;\n\ntrig_for_each_option :\n    FOR EACH ROW\n    | FOR EACH STATEMENT\n    | trig_timer_rate\n    ;\n\ntrig_timer_rate :\n    FOR ONCE AT_KEYWORD DATETIME LT_STRING max_run_duration? exec_ep_seqno?\n    | rate_over_day rate_in_day duaring_date? max_run_duration? exec_ep_seqno?\n    | repeat_interval duaring_date? max_run_duration? exec_ep_seqno?\n    ;\n\nexec_ep_seqno :\n    EXECUTE AT_KEYWORD LT_INTEGER\n    ;\n\nrate_over_day :\n    month_rate\n    | week_rate\n    | day_rate\n    ;\n\nmonth_rate :\n    FOR EACH LT_INTEGER MONTH day_in_month\n    | FOR EACH LT_INTEGER MONTH day_in_month_week\n    ;\n\nday_in_month :\n    DAY LT_INTEGER\n    ;\n\nday_in_month_week :\n    DAY LT_INTEGER OF WEEK LT_INTEGER\n    | DAY LT_INTEGER OF WEEK LAST\n    ;\n\nweek_rate :\n    FOR EACH LT_INTEGER WEEK day_of_week_list\n    ;\n\nday_of_week_list :\n    LT_INTEGER (COMMA LT_INTEGER)*\n    ;\n\nday_rate :\n    FOR EACH LT_INTEGER DAY\n    ;\n\nrate_in_day :\n    once_in_day\n    | times_in_day\n    ;\n\nonce_in_day :\n    AT_KEYWORD TIME LT_STRING\n    ;\n\ntimes_in_day :\n    duaring_time? FOR EACH LT_INTEGER MINUTE\n    | duaring_time? FOR EACH LT_INTEGER SECOND\n    ;\n\nduaring_time :\n    FROM TIME LT_STRING\n    | FROM TIME LT_STRING TO TIME LT_STRING\n    ;\n\nduaring_date :\n    FROM DATETIME LT_STRING\n    | FROM DATETIME LT_STRING TO DATETIME LT_STRING\n    ;\n\ntrig_when_option :\n    WHEN '(' trig_when_condition ')'\n    ;\n\ntrig_when_condition :\n    bool_exp\n    ;\n\nrepeat_interval_stmt :\n    repeat_interval\n    ;\n\nmax_run_duration :\n    MAX_RUN_DURATION LT_INTEGER\n    ;\n\nrepeat_interval :\n    frequency_clause (SEMI interval_clause_single*)?\n    ;\n\nfrequency_clause :\n    FREQ '=' frequency_define\n    ;\n\nfrequency_define :\n    predefined_frequency\n    ;\n\npredefined_frequency :\n    YEARLY\n    | MONTHLY\n    | WEEKLY\n    | DAILY\n    | HOURLY\n    | MINUTELY\n    | SECONDLY\n    ;\n\ninterval_clause_list :\n    interval_clause_single (SEMI interval_clause_single)*\n    ;\n\ninterval_clause_single :\n    interval_clause\n    | bymonth_clause\n    | byweekno_clause\n    | byyearday_clause\n    | bymonthday_clause\n    | byday_clause\n    | byhour_clause\n    | byminute_clause\n    | bysecond_clause\n    ;\n\ninterval_clause :\n    INTERVAL '=' intervalnum\n    ;\n\nintervalnum :\n    LT_INTEGER\n    ;\n\nbymonth_clause :\n    BYMONTH '=' monthlist\n    ;\n\nmonthlist :\n    month\n    | monthlist COMMA month\n    ;\n\nmonth :\n    numeric_month\n    | char_month\n    ;\n\nnumeric_month :\n    LT_INTEGER\n    ;\n\nchar_month :\n    JAN\n    | FEB\n    | MAR\n    | APR\n    | MAY\n    | JUN\n    | JUL\n    | AUG\n    | SEP\n    | OCT\n    | NOV\n    | DEC\n    ;\n\nbyweekno_clause :\n    BYWEEKNO '=' weekno_list\n    ;\n\nweekno_list :\n    weekno (COMMA weekno)*\n    ;\n\nweekno :\n    lt_integer_negative\n    ;\n\nbyyearday_clause :\n    BYYEARDAY '=' yearday_list\n    ;\n\nyearday_list :\n    yearday (COMMA yearday)*\n    ;\n\nyearday :\n    lt_integer_negative\n    ;\n\nbymonthday_clause :\n    BYMONTHDAY '=' monthday_list\n    ;\n\nmonthday_list :\n    monthday (COMMA monthday)*\n    ;\n\nmonthday :\n    lt_integer_negative\n    ;\n\nbyday_clause :\n    BYDAY '=' byday_list\n    ;\n\nbyday_list :\n    byday (COMMA byday)*\n    ;\n\nbyday :\n    weekdaynum_options? day\n    ;\n\nweekdaynum_options :\n    weekdaynum\n    ;\n\nweekdaynum :\n    lt_integer_negative\n    ;\n\nday :\n    MON\n    | TUE\n    | WED\n    | THU\n    | FRI\n    | SAT\n    | SUN\n    ;\n\nbyhour_clause :\n    BYHOUR '=' hour_list\n    ;\n\nhour_list :\n    hour (COMMA hour)*\n    ;\n\nhour :\n    LT_INTEGER\n    ;\n\nbyminute_clause :\n    BYMINUTE '=' minute_list\n    ;\n\nminute_list :\n    minute (COMMA minute)*\n    ;\n\nminute :\n    LT_INTEGER\n    ;\n\nbysecond_clause :\n    BYSECOND '=' second_list\n    ;\n\nsecond_list :\n    second (COMMA second)*\n    ;\n\nsecond :\n    LT_INTEGER\n    ;\n\nquery_rewrite :\n    ENABLE QUERY REWRITE\n    | DISABLE QUERY REWRITE\n    ;\n\nbuild_clause :\n    BUILD IMMEDIATE\n    | BUILD DEFERRED\n    ;\n\nmv_refresh_option :\n    ON DEMAND\n    | ON COMMIT\n    | WITH PRIMARY KEY\n    | WITH ROWID\n    | START WITH exp\n    | NEXT exp\n    | FAST\n    | COMPLETE\n    | FORCE\n    | complete_del_null\n    ;\n\nmv_refresh_option_list :\n    mv_refresh_option+\n    ;\n\nmv_refresh_clause :\n    REFRESH mv_refresh_option_list\n    | NEVER REFRESH\n    ;\n\nmv_log_purge_syn_asyn_clause :\n    SYNCHRONOUS\n    | ASYNCHRONOUS\n    ;\n\nmv_log_purge_clause :\n    PURGE REPEAT exp\n    | PURGE START WITH exp REPEAT exp\n    | PURGE IMMEDIATE mv_log_purge_syn_asyn_clause?\n    | PURGE START WITH exp NEXT exp\n    | PURGE START WITH exp\n    | PURGE NEXT exp\n    ;\n\nmv_log_with_syntax_item :\n    PRIMARY KEY\n    | ROWID\n    | SEQUENCE\n    ;\n\nmv_log_with_syntax_item_list :\n    mv_log_with_syntax_item\n    | mv_log_with_syntax_item COMMA mv_log_with_syntax_item\n    | mv_log_with_syntax_item COMMA mv_log_with_syntax_item COMMA mv_log_with_syntax_item\n    ;\n\nmv_log_including_new_values :\n    INCLUDING NEW VALUES\n    | EXCLUDING NEW VALUES\n    ;\n\nmv_log_with_clause_null :\n    mv_log_including_new_values?\n    | WITH mv_log_with_syntax_item_list? column_list_options? mv_log_including_new_values?\n    ;\n\ncreate_materialized_view_log_stmt :\n    CREATE MATERIALIZED VIEW LOG ON full_table_name horizon_partition_clause? space_limit? storage_tag? compress_tag? ctab_log_options? mv_log_with_clause_null mv_log_purge_clause?\n    ;\n\nprebuilt_table_clause_null :\n    ON PREBUILT TABLE\n    | ON PREBUILT TABLE WITHOUT REDUCED PRECISION\n    | ON PREBUILT TABLE WITH REDUCED PRECISION\n    ;\n\ncreate_materialized_view_stmt :\n    CREATE MATERIALIZED VIEW full_view_name2 column_list_options? build_clause? horizon_partition_clause? storage_tag? compress_tag? ctab_log_options? mv_refresh_clause? query_rewrite? AS select_stmt\n    | CREATE MATERIALIZED VERTICAL VIEW full_view_name2 column_list_options? build_clause? horizon_partition_clause? storage_tag? compress_tag? ctab_log_options? mv_refresh_clause? query_rewrite? AS select_stmt\n    | CREATE MATERIALIZED VIEW FOR full_table_name mv_refresh_clause? AS select_stmt\n    | CREATE MATERIALIZED VIEW full_view_name2 FOR full_table_name prebuilt_table_clause_null mv_refresh_clause? query_rewrite? AS select_stmt\n    ;\n\ncreate_view_stmt :\n    CREATE replace_option? force? VIEW not_exist? create_view_stmt_body\n    ;\n\ncreate_view_stmt_body :\n    full_view_name2 column_list3_options? with_schemabinding? AS (without_into_select2 with_check_or_readonly_option? | joined_table | TABLE full_tv_name)\n    ;\n\ncolumn_list3_options :\n    '(' column_list3 ')'\n    ;\n\ncolumn_list3 :\n    column_name compress_level? compress_type?\n    | column_list3 COMMA column_name compress_level? compress_type?\n    | column_list3 COMMA view_constraint_def\n    | column_name view_column_constraint_def\n    | column_list3 COMMA column_name view_column_constraint_def\n    ;\n\nview_column_constraint_def :\n    view_column_constraints constraint_attributes_options?\n    ;\n\nview_column_constraints :\n    view_column_constraint\n    ;\n\nview_column_constraint :\n    constraint_name_def_options? view_column_constraint_action DISABLE cons_novalidate?\n    ;\n\nview_column_constraint_action :\n    view_unique_spec\n    | view_refs_spec\n    ;\n\nview_constraint_def :\n    constraint_name_def_options? view_constraint_clause DISABLE cons_novalidate?\n    ;\n\nwith_schemabinding :\n    WITH SCHEMABINDING\n    ;\n\ncolumn_list_options :\n    '(' column_list ')'\n    ;\n\nwith_check_or_readonly_option :\n    WITH check_level_option? CHECK OPTION\n    | WITH READ ONLY\n    ;\n\ncheck_level_option :\n    LOCAL\n    | CASCADED\n    ;\n\ndecl_cursor :\n    cursor_declaration_2\n    ;\n\ndelete_stmt :\n    with_option? DELETE delete_stmt_body\n    ;\n\ndelete_stmt_body :\n    from_tag? from_tv where_current_option return_into_obj? limit_option? check_limit_option? log_errors?\n    | from_tag? full_tv_name delete_multi_tv_option where_current_option return_into_obj? limit_option? check_limit_option? log_errors?\n    ;\n\ndelete_multi_tv_option :\n    FROM from_tv_list\n    | USING from_tv_list\n    ;\n\ncheck_limit_option :\n    CHECK LIMIT LT_INTEGER\n    ;\n\nwhere_current_option :\n    where_clause?\n    | WHERE CURRENT OF qualified_name\n    | WHERE CURRENT OF CURSOR\n    ;\n\nwhere_clause :\n    WHERE search_condition\n    ;\n\nstart_with_clause_null :\n    START WITH search_condition\n    ;\n\nconnect_by_item :\n    CONNECT BY nocycle_flag? search_condition\n    ;\n\nconnect_by_clause :\n    connect_by_item+\n    ;\n\nhierarchical_query_clause :\n    connect_by_clause start_with_clause_null?\n    | start_with_clause_null connect_by_clause\n    ;\n\nnocycle_flag :\n    NOCYCLE\n    ;\n\nsearch_condition :\n    bool_exp\n    ;\n\ndisconnect_stmt :\n    DISCONNECT disconnect_option\n    ;\n\ndisconnect_option :\n    CURRENT\n    | ALL\n    ;\n\ndrop_stmt :\n    DROP drop_db_object drop_stmt_body_1\n    | drop_stmt_2\n    ;\n\ndrop_stmt_body_1 :\n    full_object_name restrict_cascade? purge_option? is_detach?\n    | LOG ON full_table_name\n    ;\n\ndrop_stmt_2 :\n    DROP drop_id_db_object full_object_name restrict_cascade? is_detach?\n    | DROP PUBLIC drop_db_object full_object_name restrict_cascade? is_detach?\n    | DROP PUBLIC drop_id_db_object full_object_name restrict_cascade? is_detach?\n    | DROP TABLESPACE exist? tablespace_name\n    | DROP HUGE TABLESPACE exist? full_object_name\n    | DROP PARTITION GROUP full_object_name force_option?\n    ;\n\ndrop_id_db_object :\n    id_db_object exist?\n    ;\n\nid_db_object :\n    ROLE\n    | TYPE\n    | SEQUENCE\n    | DIRECTORY\n    | PACKAGE\n    | LINK\n    | PROFILE\n    ;\n\ndrop_db_object :\n    db_object exist?\n    ;\n\nexist :\n    IF EXISTS\n    ;\n\nnot_exist :\n    IF NOT EXISTS\n    ;\n\ndb_object :\n    FUNCTION\n    | INDEX\n    | PROCEDURE\n    | TABLE\n    | TRIGGER\n    | VIEW\n    | MATERIALIZED VIEW\n    | USER\n    | SCHEMA\n    | LOGIN\n    | AUDIT RULE\n    | CRYPTO\n    | PACKAGE BODY\n    | TYPE BODY\n    | SYNONYM\n    | CLASS\n    | CLASS BODY\n    | DOMAIN\n    | CHARACTER SET\n    | COLLATION\n    | CONTEXT\n    | TABLESPACE SET\n    ;\n\nis_detach :\n    DETACH\n    ;\n\npurge_option :\n    PURGE\n    ;\n\nalter_database_stmt :\n    alter_tag DATABASE alter_database_action\n    | alter_tag DATABASE ADD NODE LOGFILE file_list\n    | alter_tag DATABASE ADD NODE\n    | alter_tag SYSTEM alter_system_action\n    ;\n\nalter_system_action :\n    ARCHIVE LOG CURRENT\n    | SWITCH LOGFILE\n    ;\n\nalter_database_action :\n    ADD LOGFILE file_list\n    | RENAME LOGFILE pathname_list TO pathname_list\n    | RESIZE LOGFILE pathname TO LT_INTEGER\n    | MOUNT\n    | OPEN force?\n    | SUSPEND\n    | NORMAL force?\n    | PRIMARY force?\n    | STANDBY force?\n    | ADD ARCHIVELOG LT_STRING\n    | DELETE ARCHIVELOG LT_STRING\n    | MODIFY ARCHIVELOG LT_STRING\n    | ARCHIVELOG\n    | NOARCHIVELOG\n    | ARCHIVELOG CURRENT\n    | ENABLE BLOCK CHANGE TRACKING\n    | DISABLE BLOCK CHANGE TRACKING\n    ;\n\nforce :\n    NO FORCE\n    | FORCE\n    ;\n\ntablespace_name :\n    id\n    ;\n\nraft_name :\n    id\n    ;\n\nfetch_into :\n    INTO assignment_obj_list\n    ;\n\nbulk_or_single_into :\n    fetch_into\n    | BULK COLLECT INTO assignment_obj_list\n    ;\n\nfetch_stmt :\n    FETCH fetch_tail\n    ;\n\nfetch_statement :\n    FETCH CURSOR fetch_tail\n    ;\n\nfetch_tail :\n    fetch_option? assign_obj bulk_or_single_into? fetch_limit_option?\n    ;\n\nfetch_limit_option :\n    LIMIT exp\n    ;\n\nfetch_option :\n    fetch_direct_option from_tag?\n    ;\n\nfetch_direct_option :\n    NEXT\n    | PRIOR\n    | FIRST\n    | LAST2\n    | ABSOLUTE top_exp\n    | RELATIVE top_exp\n    ;\n\nlog_errors_into :\n    INTO full_tv_name\n    ;\n\nlog_errors_expression :\n    '(' exp ')'\n    ;\n\nlog_errors_unlimited :\n    REJECT LIMIT UNLIMITED\n    | REJECT LIMIT LT_INTEGER\n    ;\n\nlog_errors :\n    LOG ERRORS log_errors_into? log_errors_expression? log_errors_unlimited\n    ;\n\ninsert_stmt :\n    INSERT insert_stmt_body\n    ;\n\ninsert_stmt_body :\n    into_tag? full_tv_name alias_option? insert_tail return_into_obj? log_errors?\n    | into_tag? select_with_paran alias_option? insert_tail return_into_obj? log_errors?\n    | multi_insert_stmt_body\n    ;\n\nfull_column_list_options :\n    '(' full_column_list ')'\n    ;\n\nins_value_options :\n    VALUES ins_value\n    ;\n\ninsert_into_single :\n    INTO full_tv_name alias_option? full_column_list_options? ins_value_options?\n    ;\n\nmulti_insert_into_list :\n    insert_into_single+\n    ;\n\nmulti_insert_tag :\n    ALL\n    | FIRST\n    ;\n\ninsert_into_single_condition :\n    WHEN bool_exp THEN multi_insert_into_list\n    ;\n\nmulti_insert_into_condition_list :\n    insert_into_single_condition+\n    ;\n\nmulti_insert_into_else :\n    ELSE multi_insert_into_list\n    ;\n\nmulti_insert_stmt_body :\n    ALL multi_insert_into_list without_into_select2 log_errors?\n    | multi_insert_tag? multi_insert_into_condition_list multi_insert_into_else? without_into_select2 log_errors?\n    ;\n\ninsert_tail :\n    insert_action\n    | '(' full_column_list ')' insert_action\n    ;\n\ninsert_action :\n    VALUES ins_value\n    | without_into_select2\n    | DEFAULT VALUES\n    | call_proc_stmt_2\n    | VALUES record_var_values\n    | TABLE full_tv_name\n    ;\n\nrecord_var_values :\n    record_var_value (COMMA record_var_value)*\n    ;\n\nrecord_var_value :\n    member\n    | invocation_expression\n    | element_access\n    | member_access\n    ;\n\nins_value :\n    '(' ')'\n    | '(' ins_value_list ')'\n    | ins_value COMMA '(' ins_value_list ')'\n    ;\n\nopen_stmt :\n    OPEN open_tail\n    ;\n\nopen_statement :\n    OPEN CURSOR open_tail\n    ;\n\nopen_tail :\n    assign_obj2\n    | assign_obj2 FOR without_into_select\n    | assign_obj2 FOR exp using_clause?\n    ;\n\nreturn_stmt :\n    RETURN\n    | RETURN bool_exp\n    ;\n\nraise_stmt :\n    RAISE exp\n    | RAISE\n    ;\n\nrollback_stmt :\n    ROLLBACK work_tag? commit_tail? to_savepoint?\n    ;\n\nto_savepoint :\n    TO SAVEPOINT savepoint_name\n    | TO savepoint_name\n    ;\n\nsavepoint_stmt :\n    SAVEPOINT savepoint_name\n    ;\n\nselect_stmt :\n    without_into_select2\n    ;\n\nall_distinct_option :\n    ALL\n    | DISTINCT\n    | UNIQUE\n    ;\n\nall_distinct_option_2 :\n    ALL\n    | DISTINCT\n    | UNIQUE\n    ;\n\ncorresponding_clause :\n    CORRESPONDING\n    | CORRESPONDING BY '(' column_list ')'\n    ;\n\ntop_option :\n    TOP top_exp PERCENT? (WITH TIES)?\n    | TOP top_exp COMMA top_exp\n    ;\n\nlimit_option :\n    limit_clause\n    | row_limiting_clause\n    ;\n\nlimit_clause :\n    LIMIT top_exp ((OFFSET | COMMA) top_exp)?\n    | OFFSET top_exp LIMIT top_exp\n    ;\n\nlimit_not_empty :\n    limit_clause\n    | row_limiting_clause\n    ;\n\nrow_limiting_clause :\n    FETCH first_next_desc row_num_desc ONLY\n    | FETCH first_next_desc top_exp row_num_desc ONLY\n    | FETCH first_next_desc row_num_desc WITH TIES\n    | FETCH first_next_desc top_exp row_num_desc WITH TIES\n    | FETCH first_next_desc top_exp PERCENT row_num_desc ONLY\n    | FETCH first_next_desc top_exp PERCENT row_num_desc WITH TIES\n    | OFFSET top_exp row_num_desc\n    | OFFSET top_exp row_num_desc FETCH first_next_desc row_num_desc ONLY\n    | OFFSET top_exp row_num_desc FETCH first_next_desc top_exp row_num_desc ONLY\n    | OFFSET top_exp row_num_desc FETCH first_next_desc row_num_desc WITH TIES\n    | OFFSET top_exp row_num_desc FETCH first_next_desc top_exp row_num_desc WITH TIES\n    | OFFSET top_exp row_num_desc FETCH first_next_desc top_exp PERCENT row_num_desc ONLY\n    | OFFSET top_exp row_num_desc FETCH first_next_desc top_exp PERCENT row_num_desc WITH TIES\n    ;\n\nrow_num_desc :\n    ROW\n    | ROWS\n    ;\n\nfirst_next_desc :\n    FIRST\n    | NEXT\n    ;\n\nselect_item_list :\n    select_item (COMMA select_item)*\n    ;\n\nselect_item :\n    exp (alias | AS alias_2)\n    | bool_exp\n    | '*'\n    ;\n\nas_alias :\n    AS alias_2\n    ;\n\nselect_tail :\n    from_clause? where_clause? hierarchical_query_clause? (group_by_clause having_clause? | having_clause group_by_clause?)?\n    ;\n\nfrom_clause :\n    FROM from_tv_list\n    ;\n\nfrom_tv_list :\n    from_tv (COMMA from_tv)*\n    ;\n\nfrom_tv :\n    normal_tv joined_table_element*\n    | '(' normal_tv joined_table_element+ ')'\n    ;\n\njoined_table :\n    normal_tv joined_table_element+\n    | '(' normal_tv joined_table_element+ ')'\n    ;\n\ntrxid :\n    LT_INTEGER\n    ;\n\nflashback_query_low :\n    WHEN TIMESTAMP exp\n    | WHEN TRXID trxid\n    | AS OF TIMESTAMP exp\n    | AS OF scn_or_lsn trxid\n    | VERSIONS BETWEEN TIMESTAMP exp AND exp\n    | VERSIONS BETWEEN TRXID trxid AND trxid\n    | VERSIONS BETWEEN scn_or_lsn trxid_option AND trxid_option\n    | AFTER OF TIMESTAMP exp\n    | AFTER OF scn_or_lsn trxid\n    ;\n\ntrxid_option :\n    trxid\n    | MINVALUE\n    | MAXVALUE\n    ;\n\nrange_from_to :\n    TOP LT_INTEGER\n    | FROM LT_INTEGER TO LT_INTEGER\n    ;\n\nsample_exp :\n    LT_DECIMAL\n    | LT_INTEGER\n    | LT_REAL\n    ;\n\npivot_sfun :\n    invocation_expression as_alias?\n    | invocation_expression alias\n    ;\n\npivot_sfun_lst :\n    pivot_sfun (COMMA pivot_sfun)*\n    ;\n\npivot_for_clause :\n    FOR '(' exp_list_2 ')'\n    | FOR exp\n    ;\n\npivot_in_clause1_expr :\n    exp as_alias?\n    | exp alias\n    | '(' exp_list_2 ')' as_alias?\n    | '(' exp_list_2 ')' alias\n    | ANY\n    ;\n\npivot_in_clause_low_1 :\n    pivot_in_clause1_expr\n    | pivot_in_clause_low_1 COMMA pivot_in_clause1_expr\n    ;\n\npivot_in_clause_low_2 :\n    without_into_select\n    ;\n\npivot_in_clause_low :\n    pivot_in_clause_low_1\n    | pivot_in_clause_low_2\n    ;\n\npivot_xml :\n    XML\n    ;\n\npivot_clause_low :\n    PIVOT pivot_xml? '(' pivot_sfun_lst pivot_for_clause IN '(' pivot_in_clause_low? ')' ')'\n    ;\n\nunpivot_val_col_lst :\n    exp\n    | '(' exp_list_2 ')'\n    ;\n\ninclude_clause :\n    INCLUDE NULLS\n    | EXCLUDE NULLS\n    ;\n\nunpivot_in_clause_expr :\n    exp AS exp\n    | exp\n    | '(' exp_list_2 ')' AS '(' exp_list_2 ')'\n    | '(' exp_list_2 ')' AS exp\n    | '(' exp_list_2 ')'\n    ;\n\nunpivot_in_clause_low :\n    unpivot_in_clause_expr (COMMA unpivot_in_clause_expr)*\n    ;\n\nunpivot_clause_low :\n    UNPIVOT include_clause? '(' unpivot_val_col_lst pivot_for_clause IN '(' unpivot_in_clause_low ')' ')'\n    ;\n\nsample_clause_low :\n    SAMPLE '(' sample_exp ')'\n    | SAMPLE '(' sample_exp ')' SEED '(' sample_exp ')'\n    | SAMPLE BLOCK '(' sample_exp ')'\n    | SAMPLE BLOCK '(' sample_exp ')' SEED '(' sample_exp ')'\n    ;\n\nnormal_tv_name :\n    full_tv_name\n    | '(' full_tv_name ')'\n    ;\n\nnormal_tv_tail :\n    normal_tv_tail_low (WITH '(' NOLOCK ')')?\n    | WITH '(' NOLOCK ')' normal_tv_tail_low?\n    ;\n\nnormal_tv_tail_low :\n    normal_tv_tail_low2 normal_alias?\n    | normal_alias\n    ;\n\nnormal_alias :\n    AS alias_2\n    | alias\n    ;\n\nnormal_tv_tail_low2 :\n    normal_tv_tail_low3+\n    ;\n\nnormal_tv_tail_low3 :\n    normal_alias? (pivot_clause_low | unpivot_clause_low)\n    | flashback_query_low\n    | sample_clause_low\n    ;\n\nnormal_tv_derived_table_options :\n    normal_tv_derived_table_low\n    ;\n\nnormal_tv_derived_table_low :\n    normal_tv_tail_low2 (normal_alias column_list_options?)?\n    | normal_alias column_list_options?\n    ;\n\nnormal_tv_derived_table :\n    select_with_paran\n    | select_with_paran_with_alias\n    ;\n\nselect_with_paran_with_alias :\n    select_with_paran normal_tv_derived_table_low\n    | '(' select_with_paran_with_alias ')' normal_alias ?\n    ;\n\nfrom_table_exp :\n    TABLE '(' exp ')'\n    | '(' from_table_exp ')'\n    ;\n\nfrom_table_select_with_paran :\n    TABLE select_with_paran\n    | '(' from_table_select_with_paran ')'\n    ;\n\nnormal_tv :\n    normal_tv_name normal_tv_tail?\n    | ARRAY pexp_pfx range_from_to? (as_alias | alias)?\n    | from_table_exp range_from_to? alias\n    | from_table_select_with_paran range_from_to? (as_alias | alias)?\n    | XMLTABLE '(' exp xml_passing? xmlcoldef_lst_options? ')' alias_option?\n    | JSON_TABLE '(' argument COMMA LT_STRING on_error? jsoncol_lst ')' (as_alias | alias)?\n    | normal_tv_derived_table\n    | full_tv_name '(' column_list2 ')' normal_tv_derived_table_options?\n    ;\n\nxml_passing :\n    PASSING exp\n    ;\n\nxmlcoldef_lst_options :\n    COLUMNS xmlcoldef_lst\n    ;\n\nxmlcoldef_lst :\n    xmlcoldef (COMMA xmlcoldef)*\n    ;\n\nxmlcoldef :\n    column_name datatype PATH exp\n    ;\n\non_error :\n    NULL ON ERROR\n    | ERROR ON ERROR\n    | DEFAULT exp ON ERROR\n    ;\n\njsoncol_lst :\n    COLUMNS '(' jsoncoldef_lst ')'\n    ;\n\njsoncoldef_lst :\n    jsoncoldef (COMMA jsoncoldef)*\n    ;\n\njsoncoldef :\n    json_exists_col\n    | json_qurey_col\n    | json_value_col\n    | json_nested_col\n    | ordinality_col\n    ;\n\njson_exists_col :\n    column_name datatype EXISTS PATH LT_STRING on_error?\n    ;\n\njson_qurey_col :\n    column_name datatype FORMAT JSON PATH LT_STRING on_error?\n    ;\n\njson_value_col :\n    column_name datatype PATH LT_STRING on_error?\n    ;\n\njson_nested_col :\n    NESTED_PATH LT_STRING jsoncol_lst\n    ;\n\nordinality_col :\n    column_name FOR ORDINALITY\n    ;\n\njoined_table_element :\n    cross_join\n    | qualified_join\n    | cross_outer_apply_join\n    ;\n\ncross_outer_apply_clause :\n    CROSS APPLY\n    | OUTER APPLY\n    ;\n\ncross_outer_apply_join :\n    cross_outer_apply_clause normal_tv\n    | cross_outer_apply_clause '(' joined_table ')'\n    ;\n\ncross_join :\n    CROSS JOIN normal_tv\n    | CROSS JOIN '(' joined_table ')'\n    ;\n\npartition_out_join :\n    PARTITION BY '(' exp_list ')'\n    ;\n\nqualified_join :\n    NATURAL JOIN normal_tv\n    | NATURAL JOIN '(' joined_table ')'\n    | NATURAL join_type JOIN normal_tv\n    | NATURAL join_type JOIN '(' joined_table ')'\n    | JOIN from_tv qualified_joinspec\n    | partition_out_join? join_type join_hint? JOIN from_tv partition_out_join? qualified_joinspec\n    ;\n\nqualified_joinspec :\n    ON join_condition\n    | named_columns_join\n    ;\n\nnamed_columns_join :\n    USING '(' column_list ')'\n    ;\n\njoin_hint :\n    HASH\n    | MERGE\n    ;\n\njoin_type :\n    INNER\n    | outer_join_type (INNER | OUTER)?\n    ;\n\nouter_join_type :\n    LEFT\n    | RIGHT\n    | FULL\n    ;\n\njoin_condition :\n    bool_exp\n    ;\n\ngroup_by_clause :\n    GROUP BY group_item\n    ;\n\ngroup_item :\n    exp_rollup_cube_item\n    | exp_rollup_cube_item2\n    ;\n\nexp_rollup_cube_item2 :\n    exp_rollup_cube_item COMMA exp_rollup_cube_item\n    | exp_rollup_cube_item2 COMMA exp_rollup_cube_item\n    ;\n\nexp_rollup_cube_item :\n    exp\n    | '(' ')'\n    | '(' exp_list_2 ')'\n    | ROLLUP '(' grouping_set_items ')'\n    | CUBE '(' grouping_set_items ')'\n    | GROUPING SETS '(' grouping_set_items ')'\n    ;\n\ngrouping_set_items :\n    grouping_set_item\n    | grouping_set_items COMMA grouping_set_item\n    ;\n\ngrouping_set_item :\n    exp\n    | '(' ')'\n    | '(' exp_list_2 ')'\n    ;\n\nhaving_clause :\n    HAVING search_condition\n    ;\n\nwithout_into_select :\n    (simple_select | select_with_paran) (sel_clause_app for_xml_path?)?\n    ;\n\nsel_clause_app :\n    order_by ((for_update limit_option?) | (limit_not_empty for_update_options?))?\n    | for_update order_by? limit_option?\n    | limit_not_empty order_by? for_update_options?\n    ;\n\nselect_clause :\n    query_exp\n    | select_with_paran\n    ;\n\nsimple_select :\n    select_clause ( (UNION | EXCEPT | MINUS | INTERSECT) all_distinct_option? corresponding_clause? select_clause)*\n    ;\n\nselect_with_paran :\n    '(' without_into_select ')'\n    | '(' select_with_paran ')'\n    ;\n\nquery_exp :\n    with_option? SELECT all_distinct_option? top_option? select_item_list bulk_or_single_into? select_tail for_xml_path?\n    ;\n\nfor_xml_path :\n    FOR XML PATH '(' LT_STRING ')'\n    ;\n\nwith_tag :\n    WITH\n    | WITH RECURSIVE\n    ;\n\nwith_option :\n    with_tag with_clause\n    ;\n\nwith_clause :\n    with_function_list\n    | with_view_list\n    | with_function_list with_view_list\n    ;\n\nwith_function_list :\n    with_function_list_element+\n    ;\n\nfunc_def_inner :\n    encryption_option? calc_option? param_def_list_option? RETURN plsql_datatype func_call_options? func_action\n    ;\n\nwith_function_list_element :\n    FUNCTION id func_def_inner SEMI\n    ;\n\nwith_view_list :\n    with_view_list_element (COMMA with_view_list_element)*\n    ;\n\ndepth_type_option :\n    DEPTH FIRST BY\n    | BREADTH FIRST BY\n    ;\n\nsearch_clause :\n    SEARCH depth_type_option order_by_list SET full_column_name\n    ;\n\ncycle_clause :\n    CYCLE full_column_list SET full_column_name TO default_exp DEFAULT default_exp\n    ;\n\nwith_view_list_element :\n    id column_list_options? AS select_with_paran search_clause? cycle_clause?\n    ;\n\nassignment_obj_list :\n    assignment_obj (COMMA assignment_obj)*\n    ;\n\nassignment_obj :\n    pexp_pfx\n    | stm_param_name\n    ;\n\norder_by_options :\n    order_by\n    ;\n\norder_by :\n    ORDER BY order_by_list\n    | ORDER SIBLINGS BY order_by_list\n    ;\n\nasc_desc_option :\n    ASC\n    | DESC\n    ;\n\nnulls_last_option :\n    NULLS FIRST\n    | NULLS LAST\n    ;\n\ncollate_option :\n    COLLATE id\n    ;\n\norder_by_list :\n    order_by_item (COMMA order_by_item)*\n    ;\n\norder_by_item :\n    bool_exp collate_option? asc_desc_option? nulls_last_option?\n    ;\n\nfor_update_options :\n    for_update\n    ;\n\nfor_update :\n    FOR READ ONLY\n    | FOR update_of_option\n    ;\n\nset_session_stmt :\n    SET SESSION CHARACTERISTICS AS trans_mode_lst\n    ;\n\nset_trans_stmt :\n    SET TRANSACTION trans_mode_lst\n    | SET TIME ZONE exp\n    | START TRANSACTION trans_mode_lstl?\n    ;\n\ntrans_mode_lstl :\n    trans_mode_lst\n    ;\n\ntrans_mode_lst :\n    trans_mode (COMMA trans_mode)*\n    ;\n\ntrans_mode :\n    trans_rw_option\n    | ISOLATION LEVEL trans_level_option\n    | DIAGNOSTICS SIZE LT_INTEGER\n    ;\n\ntime_zone_exp_new :\n    AT LOCAL\n    | AT TIME ZONE exp\n    ;\n\ntrans_rw_option :\n    READ ONLY\n    | READ WRITE\n    ;\n\ntrans_level_option :\n    READ COMMITTED\n    | SERIALIZABLE\n    | REPEATABLE READ\n    | READ UNCOMMITTED\n    ;\n\nlock_table_stmt :\n    LOCK TABLE full_tv_name IN lock_mode_option MODE\n    | LOCK TABLE full_tv_name IN lock_mode_option MODE NOWAIT\n    ;\n\nlock_mode_option :\n    SHARE\n    | EXCLUSIVE\n    | INTENT SHARE\n    | INTENT EXCLUSIVE\n    | SHARE INTENT EXCLUSIVE\n    | ROW SHARE\n    | SHARE UPDATE\n    | ROW EXCLUSIVE\n    | SHARE ROW EXCLUSIVE\n    ;\n\nset_identins_stmt :\n    SET IDENTITY_INSERT full_table_name set_identins_option\n    ;\n\nset_identins_option :\n    OFF\n    | ON\n    | ON WITH REPLACE NULL\n    ;\n\ntrunc_table_stmt :\n    TRUNCATE TABLE full_table_name reuse_storage_option? cascade_opt?\n    | TRUNCATE TABLE full_table_name PARTITION truncate_partition_name reuse_storage_option? cascade_opt?\n    ;\n\nupdate_stmt :\n    with_option? UPDATE update_stmt_body\n    ;\n\nupdate_stmt_body :\n    update_tv_list SET set_value_list update_from_clause? where_current_option collect_into_rset? return_into_obj? limit_option? check_limit_option? log_errors?\n    ;\n\nupdate_tv_list :\n    from_tv_list\n    ;\n\nreturn_item :\n    exp\n    ;\n\nreturn_item_list :\n    return_item (COMMA return_item)*\n    ;\n\nreturn_option :\n    RETURN\n    | RETURNING\n    ;\n\nreturn_into_obj :\n    return_option return_item_list INTO assignment_obj_list\n    | return_option return_item_list BULK COLLECT INTO assignment_obj_list\n    ;\n\ncollect_into_rset :\n    INTO assignment_obj\n    ;\n\nalias_option :\n    alias\n    | AS alias_2\n    ;\n\nset_value_list :\n    set_value_node (COMMA set_value_node)*\n    ;\n\nset_value_node :\n    full_column_name assign_op DEFAULT\n    | full_column_name assign_op exp\n    | '(' set_col_list ')' assign_op select_with_paran\n    | '(' set_col_list ')' assign_op record_var_value\n    | ROW assign_op record_var_value\n    ;\n\nset_col_list :\n    full_column_name (COMMA full_column_name)*\n    ;\n\nupdate_from_clause :\n    from_clause\n    ;\n\nmerge_into_stmt :\n    MERGE merge_into_stmt_body\n    ;\n\nmerge_into_stmt_body :\n    INTO full_tv_name alias_option? USING from_tv ON bool_exp merge_into_sub_clause log_errors?\n    | INTO select_with_paran alias_option? USING from_tv ON bool_exp merge_into_sub_clause log_errors?\n    ;\n\nmerge_into_sub_clause :\n    merge_update_clause merge_insert_clause\n    | merge_insert_clause merge_update_clause\n    | merge_update_clause\n    | merge_insert_clause\n    ;\n\nmerge_update_clause :\n    WHEN MATCHED THEN UPDATE SET set_value_list where_clause?\n    | WHEN MATCHED THEN UPDATE SET set_value_list where_clause? DELETE where_clause?\n    ;\n\nmerge_insert_clause :\n    WHEN NOT MATCHED THEN INSERT full_column_list_options? VALUES '(' ins_value_list ')' where_clause?\n    ;\n\ncreate_profile_stmt :\n    CREATE PROFILE not_exist? profile_name resource_limit_options?\n    ;\n\nalter_profile_stmt :\n    alter_tag PROFILE profile_name resource_limit_options?\n    ;\n\ncreate_user_stmt :\n    CREATE USER not_exist? user_name\n    | CREATE USER not_exist? user_name IDENTIFIED authent_type pwd_policy? account_lock? user_encrypt_options? space_limit? read_only_flag? resource? expire? allow_ip_list? not_allow_ip_list? allow_dt_list? not_allow_dt_list? default_ts_name? quota_ts?\n    ;\n\ndefault_ts_name :\n    default_ts_name_lst\n    ;\n\ndefault_ts_name_lst :\n    default_ts_name_node+\n    ;\n\ndefault_ts_name_node :\n    default_ts_name_low\n    | temp_ts_name\n    | default_idx_ts_name\n    | default_ts_group_name_low\n    ;\n\ndefault_idx_ts_name :\n    DEFAULT INDEX TABLESPACE tablespace_name\n    ;\n\ndefault_ts_name_low :\n    DEFAULT TABLESPACE tablespace_name\n    | DEFAULT TABLESPACE NULL\n    ;\n\ntemp_ts_name :\n    TEMPORARY TABLESPACE tablespace_name\n    ;\n\ndefault_ts_group_name_low :\n    DEFAULT TABLESPACE GROUP tablespace_name\n    | DEFAULT TABLESPACE GROUP NULL\n    ;\n\non_schema :\n    ON SCHEMA id\n    ;\n\nreplace_old_pwd :\n    REPLACE password\n    ;\n\nalter_user_stmt :\n    alter_tag USER user_name authent_type_options? replace_old_pwd? pwd_policy? account_lock? user_encrypt_options? space_limit2? read_only_flag? resource? expire? allow_ip_list? not_allow_ip_list? allow_dt_list? not_allow_dt_list? default_ts_name? on_schema? quota_ts?\n    | alter_tag USER user_name GRANT CONNECT THROUGH user_name\n    | alter_tag USER user_name REVOKE CONNECT THROUGH user_name\n    ;\n\nuser_encrypt_options :\n    user_encrypt_option\n    ;\n\nuser_encrypt_option :\n    ENCRYPT BY password\n    | ENCRYPT BY WRAPPED LT_STRING\n    ;\n\nauthent_type_options :\n    IDENTIFIED authent_type\n    ;\n\nhash_cipher_option :\n    hash_cipher\n    ;\n\nauthent_type :\n    BY password hash_cipher_option? force_format?\n    | EXTERNALLY as?\n    | BY WRAPPED LT_STRING hash_cipher_option?\n    ;\n\nforce_format :\n    FORCE FORMAT\n    ;\n\nas :\n    AS LT_STRING\n    ;\n\npwd_policy :\n    PASSWORD_POLICY LT_INTEGER\n    ;\n\naccount_lock :\n    ACCOUNT LOCK\n    | ACCOUNT UNLOCK\n    ;\n\nread_only_flag :\n    READ ONLY\n    | NOT READ ONLY\n    ;\n\nread_only_flag_not_null :\n    READ ONLY\n    | READ WRITE\n    ;\n\nresource :\n    LIMIT resource_limit_list\n    | PROFILE profile_name\n    | DROP PROFILE\n    ;\n\nexpire :\n    PASSWORD EXPIRE\n    ;\n\nresource_limit_options :\n    LIMIT resource_limit_list\n    ;\n\nresource_limit_list :\n    resource_limit_list_with_comma\n    | resource_limit_list_with_empty\n    ;\n\nresource_limit_list_with_comma :\n    resource_limit\n    | resource_limit COMMA resource_limit_list_with_comma\n    ;\n\nresource_limit_list_with_empty :\n    resource_limit resource_limit\n    | resource_limit resource_limit_list_with_empty\n    ;\n\nresource_limit :\n    SESSION_PER_USER resource_limit_value\n    | CONNECT_IDLE_TIME resource_limit_value\n    | FAILED_LOGIN_ATTEMPS resource_limit_value\n    | FAILED_LOGIN_ATTEMPTS resource_limit_value\n    | PASSWORD_LIFE_TIME resource_limit_value\n    | PASSWORD_REUSE_TIME resource_limit_value\n    | PASSWORD_REUSE_MAX resource_limit_value\n    | PASSWORD_LOCK_TIME resource_limit_value\n    | PASSWORD_GRACE_TIME resource_limit_value\n    | CPU_PER_CALL resource_limit_value\n    | CPU_PER_SESSION resource_limit_value\n    | MEM_SPACE resource_limit_value\n    | READ_PER_CALL resource_limit_value\n    | READ_PER_SESSION resource_limit_value\n    | CONNECT_TIME resource_limit_value\n    ;\n\nresource_limit_value :\n    UNLIMITED\n    | DEFAULT\n    | LT_INTEGER\n    ;\n\ncreate_audit_rule_stmt :\n    CREATE AUDIT RULE rule_name audit_rule_action by_login_or_all whenever_stmt_options? allow_ip_list? allow_dt_list? op_freq?\n    ;\n\nrule_name :\n    id\n    ;\n\naudit_rule_action :\n    STARTUP\n    | SHUTDOWN\n    | DATABASE\n    | LOGIN\n    | CONNECT\n    | ROLLBACK\n    | COMMIT\n    | USER\n    | ROLE\n    | SCHEMA\n    | TABLE\n    | VIEW\n    | INDEX\n    | PROCEDURE\n    | TRIGGER\n    | SEQUENCE\n    | CONTEXT\n    | GRANT\n    | REVOKE\n    | AUDIT\n    | NOAUDIT\n    | INSERT TABLE\n    | UPDATE TABLE\n    | DELETE TABLE\n    | SELECT TABLE\n    | LOCK TABLE\n    | EXECUTE PROCEDURE\n    | SELECT ON full_object_name\n    | INSERT ON full_object_name\n    | UPDATE ON full_object_name\n    | DELETE ON full_object_name\n    | EXECUTE ON full_object_name\n    | PACKAGE\n    | PACKAGE BODY\n    | SYNONYM\n    | TYPE\n    | TYPE BODY\n    | PROFILE\n    ;\n\nby_login_or_all :\n    BY login_name\n    | BY ALL\n    ;\n\nallow_ip_list :\n    ALLOW_IP NULL\n    | ALLOW_IP ip_list\n    ;\n\nnot_allow_ip_list :\n    NOT_ALLOW_IP NULL\n    | NOT_ALLOW_IP ip_list\n    ;\n\nip_list :\n    id\n    | id COMMA ip_list\n    ;\n\nallow_dt_list :\n    ALLOW_DATETIME NULL\n    | ALLOW_DATETIME dt_list\n    ;\n\nnot_allow_dt_list :\n    NOT_ALLOW_DATETIME NULL\n    | NOT_ALLOW_DATETIME dt_list\n    ;\n\ndt_list :\n    dt\n    | dt COMMA dt_list\n    ;\n\ndt :\n    id id TO id id\n    ;\n\nop_freq :\n    INTERVAL LT_INTEGER TIMES LT_INTEGER\n    ;\n\nquota_val :\n    LT_INTEGER\n    | LT_INTEGER LT_IDENTIFIER\n    ;\n\nquota_ts_node :\n    QUOTA quota_val ON tablespace_name\n    | QUOTA UNLIMITED ON tablespace_name\n    ;\n\nquota_ts_lst :\n    quota_ts_node\n    | quota_ts_lst quota_ts_node\n    ;\n\nquota_ts :\n    quota_ts_lst\n    | QUOTA UNLIMITED\n    | QUOTA LT_INTEGER\n    ;\n\ncreate_role_stmt :\n    CREATE ROLE not_exist? role_name\n    ;\n\ncreate_dblink_stmt :\n    CREATE replace_option? LINK not_exist? qualified_name CONNECT db_type_str? WITH login_name IDENTIFIED BY password USING LT_STRING dblink_option_lst_options?\n    | CREATE replace_option? LINK not_exist? qualified_name CONNECT db_type_str? WITH login_name IDENTIFIED BY WRAPPED LT_STRING USING LT_STRING dblink_option_lst_options?\n    | CREATE replace_option? PUBLIC LINK not_exist? qualified_name CONNECT db_type_str? WITH login_name IDENTIFIED BY password USING LT_STRING dblink_option_lst_options?\n    | CREATE replace_option? PUBLIC LINK not_exist? qualified_name CONNECT db_type_str? WITH login_name IDENTIFIED BY WRAPPED LT_STRING USING LT_STRING dblink_option_lst_options?\n    ;\n\ndb_type_str :\n    LT_STRING\n    ;\n\ndblink_option_lst_options :\n    OPTION '(' dblink_option_lst ')'\n    ;\n\ndblink_option_lst :\n    dblink_option (COMMA dblink_option)*\n    ;\n\ndblink_option :\n    id '=' exp\n    ;\n\ncreate_synonym_stmt :\n    CREATE replace_option? PUBLIC SYNONYM not_exist? full_synonym_name FOR full_obj_name\n    | CREATE replace_option? SYNONYM not_exist? full_synonym_name FOR full_obj_name\n    ;\n\nfull_synonym_name :\n    qualified_name\n    ;\n\nfull_obj_name :\n    qualified_name dblink_clause?\n    ;\n\ncreate_domain_stmt :\n    CREATE DOMAIN not_exist? qualified_name as_tag? datatype charset_option? domain_default_option? domain_constraints_option?\n    ;\n\ndomain_default_option :\n    default_clause\n    ;\n\ndomain_constraints_option :\n    domain_constraints_def\n    ;\n\ndomain_constraints_def :\n    domain_constraints constraint_attributes_options?\n    ;\n\ndomain_constraints :\n    domain_constraint+\n    ;\n\ndomain_constraint :\n    domain_constraint_name_def_options? column_constraint_action\n    ;\n\ndomain_constraint_name_def_options :\n    domain_constraint_name_def\n    ;\n\ndomain_constraint_name_def :\n    CONSTRAINT domain_constraint_name\n    ;\n\ndomain_constraint_name :\n    qualified_name\n    ;\n\ncreate_character_set_stmt :\n    CREATE CHARACTER SET not_exist? character_set_name as_tag? character_set_source collate_clause_option?\n    ;\n\ncharacter_set_source :\n    GET existing_character_set_name\n    ;\n\nexisting_character_set_name :\n    character_set_name\n    ;\n\ncharacter_set_name :\n    qualified_name\n    ;\n\ncollate_clause_option :\n    COLLATE collation_name\n    | COLLATION FROM DEFAULT\n    ;\n\ncollation_name :\n    qualified_name\n    ;\n\ncreate_collation_stmt :\n    CREATE COLLATION not_exist? collation_name FOR existing_character_set_name FROM existing_collation_name pad_option?\n    ;\n\nexisting_collation_name :\n    collation_name\n    ;\n\npad_option :\n    NO PAD\n    | PAD SPACE_KEYWORD\n    ;\n\ncreate_sequence_stmt :\n    CREATE SEQUENCE not_exist? sequence_name sequence_option_list_options?\n    | alter_tag SEQUENCE sequence_name sequence_option_list_options?\n    ;\n\nsequence_option_list_options :\n    sequence_option_list\n    ;\n\nsequence_option_list :\n    sequence_option\n    | sequence_option sequence_option_list\n    ;\n\nsequence_option :\n    increment_option\n    | start_option\n    | current_option\n    | maxvalue_option\n    | minvalue_option\n    | cycle_option\n    | cache_option\n    | order_option\n    | seq_local_option\n    ;\n\nsequence_name :\n    qualified_name\n    ;\n\nincrement_option :\n    INCREMENT BY exp\n    ;\n\nstart_option :\n    START WITH exp\n    ;\n\ncurrent_option :\n    CURRENT VALUE exp\n    ;\n\nmaxvalue_option :\n    MAXVALUE exp\n    | NOMAXVALUE\n    ;\n\nminvalue_option :\n    MINVALUE exp\n    | NOMINVALUE\n    ;\n\ncycle_option :\n    CYCLE\n    | NOCYCLE\n    ;\n\ncache_option :\n    CACHE exp\n    | NOCACHE\n    ;\n\norder_option :\n    ORDER\n    | NOORDER\n    ;\n\nseq_local_option :\n    GLOBAL\n    | LOCAL\n    ;\n\nwhenever_stmt_options :\n    WHENEVER whenever_stmt\n    ;\n\nwhenever_stmt :\n    SUCCESSFUL\n    | NOT SUCCESSFUL\n    ;\n\ngrant_stmt :\n    grant_tag grant_stmt_body\n    ;\n\ngrant_tag :\n    GRANT\n    ;\n\ngrant_stmt_body :\n    grant_privs ON full_object_name TO grantees with_grant_option? by_grantor?\n    | grant_privs ON db_object full_object_name TO grantees with_grant_option? by_grantor?\n    | grant_privs ON qualified_name full_object_name TO grantees with_grant_option? by_grantor?\n    | db_priv_list TO grantees with_admin_option? by_grantor?\n    | grant_privs TO grantees with_admin_option? by_grantor?\n    ;\n\nrevoke_stmt :\n    REVOKE revoke_stmt_body\n    ;\n\nrevoke_stmt_body :\n    grant_privs ON full_object_name FROM grantees revoke_action? by_grantor?\n    | GRANT OPTION FOR grant_privs ON full_object_name FROM grantees revoke_action? by_grantor?\n    | grant_privs ON db_object full_object_name FROM grantees revoke_action? by_grantor?\n    | GRANT OPTION FOR grant_privs ON db_object full_object_name FROM grantees revoke_action? by_grantor?\n    | grant_privs ON qualified_name qualified_name FROM grantees revoke_action? by_grantor?\n    | GRANT OPTION FOR grant_privs ON qualified_name qualified_name FROM grantees revoke_action? by_grantor?\n    | db_priv_list FROM grantees by_grantor?\n    | ADMIN OPTION FOR db_priv_list FROM grantees by_grantor?\n    | grant_privs FROM grantees by_grantor?\n    | ADMIN OPTION FOR role_name_list FROM grantees by_grantor?\n    ;\n\ngrant_privs :\n    ALL\n    | ALL PRIVILEGES\n    | grant_priv_list\n    ;\n\ngrant_priv_list :\n    grant_priv\n    | grant_priv COMMA grant_priv_list\n    ;\n\ngrant_priv_off :\n    OFF\n    ;\n\ngrant_priv :\n    SELECT grant_priv_off?\n    | INSERT grant_priv_off?\n    | DELETE grant_priv_off?\n    | UPDATE grant_priv_off?\n    | REFERENCES grant_priv_off?\n    | EXECUTE grant_priv_off?\n    | SELECT FOR DUMP grant_priv_off?\n    | SELECT '(' column_list ')'\n    | UPDATE '(' column_list ')'\n    | INSERT '(' column_list ')'\n    | REFERENCES '(' column_list ')'\n    | ALTER grant_priv_off?\n    | INDEX grant_priv_off?\n    | role_name\n    | FLASHBACK grant_priv_off?\n    ;\n\nrevoke_action :\n    RESTRICT\n    | CASCADE\n    ;\n\ndb_priv_list :\n    db_priv\n    | db_priv COMMA db_priv_list\n    ;\n\ndb_priv :\n    ALTER DATABASE\n    | BACKUP DATABASE\n    | RESTORE DATABASE\n    | CREATE USER\n    | ALTER USER\n    | DROP USER\n    | CREATE ROLE\n    | DROP ROLE\n    | ADMIN ANY ROLE\n    | ADMIN ANY DATABASE PRIVILEGE\n    | GRANT ANY OBJECT PRIVILEGE\n    | CREATE SCHEMA\n    | DROP SCHEMA\n    | CREATE ANY SCHEMA\n    | DROP ANY SCHEMA\n    | CREATE TABLE\n    | DROP TABLE\n    | CREATE ANY TABLE\n    | ALTER ANY TABLE\n    | ALTER TABLE\n    | DROP ANY TABLE\n    | INSERT TABLE\n    | INSERT ANY TABLE\n    | UPDATE TABLE\n    | UPDATE ANY TABLE\n    | DELETE TABLE\n    | DELETE ANY TABLE\n    | SELECT TABLE\n    | SELECT ANY TABLE\n    | REFERENCES TABLE\n    | REFERENCES ANY TABLE\n    | GRANT TABLE\n    | GRANT ANY TABLE\n    | CREATE VIEW\n    | DROP VIEW\n    | CREATE ANY VIEW\n    | ALTER ANY VIEW\n    | ALTER VIEW\n    | DROP ANY VIEW\n    | INSERT VIEW\n    | INSERT ANY VIEW\n    | UPDATE VIEW\n    | UPDATE ANY VIEW\n    | DELETE VIEW\n    | DELETE ANY VIEW\n    | SELECT VIEW\n    | SELECT ANY VIEW\n    | GRANT VIEW\n    | GRANT ANY VIEW\n    | CREATE PROCEDURE\n    | DROP PROCEDURE\n    | CREATE ANY PROCEDURE\n    | DROP ANY PROCEDURE\n    | EXECUTE PROCEDURE\n    | EXECUTE ANY PROCEDURE\n    | GRANT PROCEDURE\n    | GRANT ANY PROCEDURE\n    | CREATE SEQUENCE\n    | DROP SEQUENCE\n    | ALTER ANY SEQUENCE\n    | ALTER SEQUENCE\n    | CREATE ANY SEQUENCE\n    | DROP ANY SEQUENCE\n    | SELECT SEQUENCE\n    | SELECT ANY SEQUENCE\n    | GRANT SEQUENCE\n    | GRANT ANY SEQUENCE\n    | DROP TRIGGER\n    | CREATE TRIGGER\n    | CREATE ANY TRIGGER\n    | DROP ANY TRIGGER\n    | ALTER ANY TRIGGER\n    | ALTER TRIGGER\n    | CREATE INDEX\n    | DROP INDEX\n    | CREATE ANY INDEX\n    | ALTER ANY INDEX\n    | ALTER INDEX\n    | DROP ANY INDEX\n    | CREATE CONTEXT INDEX\n    | DROP CONTEXT INDEX\n    | CREATE ANY CONTEXT INDEX\n    | ALTER ANY CONTEXT INDEX\n    | ALTER CONTEXT INDEX\n    | DROP ANY CONTEXT INDEX\n    | CREATE PACKAGE\n    | DROP PACKAGE\n    | CREATE ANY PACKAGE\n    | DROP ANY PACKAGE\n    | EXECUTE PACKAGE\n    | EXECUTE ANY PACKAGE\n    | GRANT PACKAGE\n    | GRANT ANY PACKAGE\n    | CREATE LINK\n    | DROP LINK\n    | CREATE ANY LINK\n    | DROP ANY LINK\n    | CREATE SYNONYM\n    | DROP SYNONYM\n    | CREATE ANY SYNONYM\n    | DROP ANY SYNONYM\n    | CREATE PUBLIC SYNONYM\n    | DROP PUBLIC SYNONYM\n    | CREATE REPLICATE\n    | ALTER REPLICATE\n    | DROP REPLICATE\n    | AUDIT DATABASE\n    | LABEL DATABASE\n    | VERIFY DATABASE\n    | CREATE TABLESPACE\n    | DROP TABLESPACE\n    | ALTER TABLESPACE\n    | CREATE MATERIALIZED VIEW\n    | DROP MATERIALIZED VIEW\n    | CREATE ANY MATERIALIZED VIEW\n    | DROP ANY MATERIALIZED VIEW\n    | ALTER ANY MATERIALIZED VIEW\n    | ALTER MATERIALIZED VIEW\n    | SELECT MATERIALIZED VIEW\n    | SELECT ANY MATERIALIZED VIEW\n    | CREATE ANY DOMAIN\n    | DROP ANY DOMAIN\n    | CREATE DOMAIN\n    | DROP DOMAIN\n    | GRANT ANY DOMAIN\n    | GRANT DOMAIN\n    | USAGE ANY DOMAIN\n    | USAGE DOMAIN\n    | CREATE ANY CHARACTER SET\n    | DROP ANY CHARACTER SET\n    | CREATE CHARACTER SET\n    | DROP CHARACTER SET\n    | GRANT ANY CHARACTER SET\n    | GRANT CHARACTER SET\n    | USAGE ANY CHARACTER SET\n    | USAGE CHARACTER SET\n    | CREATE ANY COLLATION\n    | DROP ANY COLLATION\n    | CREATE COLLATION\n    | DROP COLLATION\n    | GRANT ANY COLLATION\n    | GRANT COLLATION\n    | USAGE ANY COLLATION\n    | USAGE COLLATION\n    | CREATE ANY CONTEXT\n    | DROP ANY CONTEXT\n    | GRANT ANY CONTEXT\n    | SELECT ANY DICTIONARY\n    | ADMIN REPLAY\n    | ADMIN BUFFER\n    | COMMENT ANY TABLE\n    | DUMP ANY TABLE\n    | DUMP TABLE\n    | ADMIN JOB\n    | CREATE ANY DIRECTORY\n    | DROP ANY DIRECTORY\n    | CREATE SESSION\n    | CREATE PROFILE\n    | ALTER PROFILE\n    | DROP PROFILE\n    | CREATE PARTITION GROUP\n    | DROP PARTITION GROUP\n    | CREATE ANY PARTITION GROUP\n    | DROP ANY PARTITION GROUP\n    | USAGE PARTITION GROUP\n    | USAGE ANY PARTITION GROUP\n    | CREATE OPERATOR\n    | DROP OPERATOR\n    | CREATE ANY OPERATOR\n    | DROP ANY OPERATOR\n    | FLASHBACK TABLE\n    | FLASHBACK ANY TABLE\n    | UNLIMITED TABLESPACE\n    | SUBSCRIBE\n    ;\n\nby_grantor :\n    BY user_name\n    ;\n\ngrantees :\n    user_role_name\n    | user_role_name COMMA grantees\n    ;\n\ncreate_schema_stmt :\n    CREATE SCHEMA full_schema_name? (AUTHORIZATION user_name)? SEMI? (grant_and_ddl SEMI?)*\n    ;\n\noprt_arg :\n    LEFTARG opr_dtype\n    | RIGHTARG opr_dtype\n    ;\n\noprt_arg_lst :\n    oprt_arg (COMMA oprt_arg)*\n    ;\n\ncreate_operator_stmt :\n    CREATE OPERATOR qualified_u_oprt '(' FUNCTION full_func_name COMMA oprt_arg_lst ')'\n    ;\n\ndrop_operator_stmt :\n    DROP OPERATOR exist? qualified_u_oprt '(' opr_datatype_lst ')'\n    ;\n\ngrant_and_ddl :\n    grant_stmt\n    | create_func_stmt\n    | create_index_stmt\n    | create_proc_stmt\n    | create_table_stmt\n    | create_trigger_stmt\n    | create_view_stmt\n    | create_materialized_view_stmt\n    | create_materialized_view_log_stmt\n    | alter_table_stmt\n    | create_sequence_stmt\n    | create_contextindex_stmt\n    | create_synonym_stmt\n    | create_package_stmt\n    | create_package_body_stmt\n    | create_dblink_stmt\n    | create_type_stmt\n    | create_type_body_stmt\n    | create_domain_stmt\n    | create_character_set_stmt\n    | create_collation_stmt\n    | create_context_stmt\n    | comment_stmt\n    | create_partition_group_stmt\n    | create_operator_stmt\n    | drop_operator_stmt\n    ;\n\ntop_exp :\n    LT_INTEGER\n    | stm_param\n    | member\n    | '(' exp ')'\n    | null_value\n    ;\n\nu_oprt :\n    OP_U_OPRT\n    ;\n\nqualified_u_oprt :\n    u_oprt\n    | qualified_name ('.' u_oprt)?\n    ;\n\nexp_u_oprt :\n    u_oprt\n    | OPERATOR '(' qualified_u_oprt ')'\n    ;\n\nraw_exp :\n    '-' raw_exp\n    | LT_INTEGER\n    | LT_BINTEGER\n    | LT_DECIMAL\n    | LT_REAL\n    | LT_STRING\n    | member_access LT_STRING\n    | member LT_STRING\n    | LT_BITSTRING\n    | member_access\n    | member\n    | null_value\n    | stm_param\n    | INTERVAL ('+' | '-') LT_STRING interval_qualifier\n    | INTERVAL LT_STRING interval_qualifier\n    | global_var\n    ;\n\nexp :\n    op=('~'|'+'|'-') exp\n    | exp_u_oprt exp\n    | BINARY_KEYWORD exp\n    | PRIOR exp\n    | select_with_paran\n    | '(' exp '-' exp ')' interval_qualifier?\n    | exp op=('*' | '/' | '%' | MOD) exp\n    | exp op=('+' | '-' | '|' |'^' | '&') exp\n    | exp exp_u_oprt exp\n    | '(' exp exp_u_oprt ')'\n    | exp op=(OP_CONSTR | OP_SHIFT_LEFT | OP_SHIFT_RIGHT) exp\n    | boolean_case\n    | if_exp\n    | null_value\n    | stm_param\n    | USER\n    | USER '(' ')'\n    | INTERVAL ('+'| '-')? LT_STRING interval_qualifier\n    | DATEPART '(' datepart_op COMMA exp ')'\n    | IFNULL '(' bool_exp COMMA bool_exp ')'\n    | datead_fun '(' datepart_op COMMA exp COMMA exp ')'\n    | REPEAT '(' exp COMMA exp ')'\n    | REPLICATE '(' exp COMMA exp ')'\n    | OVERLAY '(' exp PLACING exp FROM exp (FOR exp)? ')'\n    | decode_case\n    | pexp_pfx '%' (ROWCOUNT | ROWCOUNT2 | IS OPEN | FOUND | NOT FOUND)\n    | global_var\n    | NEXT VALUE FOR pexp_pfx\n    | CONNECT_BY_ROOT (qualified_name | '(' exp ')')\n    | ARRAYLEN '(' exp ')'\n    | CHAR '(' exp ')'\n    | REVERSE '(' exp ')'\n    | ROWNUM\n    | sizeof_expression\n    | pexp\n    | TRUE\n    | FALSE\n    | invocation_expression OVER '(' afun_partition_by? order_by_options? afun_windowing? ')'\n    | exp ignore_nulls_clause OVER '(' afun_partition_by? order_by_options? afun_windowing? ')'\n    | invocation_expression from_first_last_option '(' afun_partition_by? order_by_options? afun_windowing? ')'\n    | pexp_pfx '(' afun_arg_lst ')' OVER '(' afun_partition_by? order_by_options? afun_windowing? ')'\n    | pexp time_zone_exp_new\n    | CURSOR FAST? select_with_paran\n    | exp MULTISET (UNION | INTERSECT | EXCEPT) all_distinct_option? exp\n    | SET '(' exp ')'\n    | contains_exp\n    ;\n\nfrom_first_last_option :\n    FROM FIRST OVER\n    | FROM LAST OVER\n    | FROM FIRST IGNORE NULLS OVER\n    | FROM LAST IGNORE NULLS OVER\n    | FROM FIRST RESPECT NULLS OVER\n    | FROM LAST RESPECT NULLS OVER\n    ;\n\nafun_arg_lst :\n    afun_arg_lst_low\n    ;\n\nafun_arg_lst_low :\n    exp ignore_nulls_clause (COMMA exp)*\n    ;\n\nin_value_exp :\n    op=('~'| '+'| '-') in_value_exp\n    | PRIOR in_value_exp\n    | in_value_exp op=('*'|'/'| '%'| MOD ) in_value_exp\n    | in_value_exp op=('+'|'-'| '|'| '^' ) in_value_exp\n    | in_value_exp op=(OP_CONSTR | OP_SHIFT_LEFT | OP_SHIFT_RIGHT) in_value_exp\n    | boolean_case\n    | if_exp\n    | null_value\n    | stm_param\n    | USER\n    | USER '(' ')'\n    | INTERVAL '+' LT_STRING interval_qualifier\n    | INTERVAL '-' LT_STRING interval_qualifier\n    | INTERVAL LT_STRING interval_qualifier\n    | DATEPART '(' datepart_op COMMA in_value_exp ')'\n    | datead_fun '(' datepart_op COMMA in_value_exp COMMA in_value_exp ')'\n    | REPEAT '(' in_value_exp COMMA in_value_exp ')'\n    | REPLICATE '(' in_value_exp COMMA in_value_exp ')'\n    | OVERLAY '(' in_value_exp PLACING in_value_exp FROM in_value_exp ')'\n    | OVERLAY '(' in_value_exp PLACING in_value_exp FROM in_value_exp FOR in_value_exp ')'\n    | decode_case\n    | pexp_pfx '%' ROWCOUNT\n    | pexp_pfx '%' ROWCOUNT2\n    | global_var\n    | NEXT VALUE FOR pexp_pfx\n    | ARRAYLEN '(' in_value_exp ')'\n    | CHAR '(' in_value_exp ')'\n    | REVERSE '(' in_value_exp ')'\n    | ROWNUM\n    | sizeof_expression\n    | pexp_a\n    | pexp_b\n    | pexp_c\n    | TRUE\n    | FALSE\n    | pexp_a time_zone_exp_new\n    ;\n\nafun_partition_by :\n    PARTITION BY exp_list\n    ;\n\nafun_windowing :\n    afun_windowing_type afun_range_clause\n    | afun_windowing_type BETWEEN afun_range_clause AND afun_range_clause\n    ;\n\nafun_windowing_type :\n    ROWS\n    | RANGE\n    ;\n\nafun_range_clause :\n    exp PRECEDING\n    | exp FOLLOWING\n    | CURRENT ROW\n    ;\n\npexp :\n    pexp_a\n    | pexp_b\n    | pexp_c\n    | pexp_d\n    | pexp_e\n    ;\n\npexp_pfx : \n    pexp_pfx DOT (id dblink_clause? | key | '*')  (('[' exp_list ']')+)?\n    | pexp_pfx '(' opt_argument_list ')' ( keep_clause |  within_clause )?  (('[' exp_list ']')+)?\n    | pexp_pfx '.' ( EXECUTE | EXTRACT  )'(' opt_argument_list ')' (('[' exp_list ']')+)?\n    | XMLPARSE '(' raw_id exp raw_id? ')' (('[' exp_list ']')+)?\n    | XMLELEMENT '(' xmlele_name xmlele_sub_lst? ')' (('[' exp_list ']')+)?\n    | XMLAGG '(' exp order_by_options? ')' (('[' exp_list ']')+)?\n    | pexp_c_insert  (('[' exp_list ']')+)?\n    | new_arr_expression\n    | pexp_cast\n    | stm_param_normal\n;\n\n\npexp_cast :\n    '(' exp AS datatype ')'\n    | CAST '(' exp AS datatype ')'\n    | CAST '(' COLLECT '(' all_distinct_option? exp order_by_options? ')' AS datatype ')'\n    ;\n\npexp_b :\n    element_access\n    | new_arr_expression\n    ;\n\npexp_a :\n    typeof_expression\n    | LT_INTEGER\n    | LT_BINTEGER\n    | LT_DECIMAL\n    | LT_REAL\n    | LT_STRING\n    | LT_BITSTRING\n    ;\n\npexp_c :\n    member ('%' BULK (EXCEPTION | ROWCOUNT))?\n    | member_access\n    | new_obj_expression\n    | invocation_expression\n    | ':' trig_new_name '.' column_name\n    | NEW '.' column_name\n    ;\n\npexp_c_insert :\n    member\n    | new_obj_expression\n    | ':' trig_new_name '.' column_name\n    | NEW '.' column_name\n    | member '%' BULK EXCEPTION\n    | member '%' BULK ROWCOUNT\n;\n\npexp_d :\n    member LT_STRING\n    | CAST '(' exp AS datatype ')'\n    | CAST '(' COLLECT '(' all_distinct_option? exp order_by_options? ')' AS datatype ')'\n    | CONVERT '(' datatype COMMA exp ')'\n    | CONVERT '(' datatype COMMA exp COMMA exp ')'\n    | TRIM '(' exp ')'\n    | TRIM '(' orient_option FROM exp ')'\n    | TRIM '(' exp FROM exp ')'\n    | TRIM '(' orient_option exp FROM exp ')'\n    | TRUNCATE '(' value_list ')'\n    | INSERT '(' value_list ')'\n    | EXTRACT '(' datepart FROM exp ')'\n    | EXTRACT '(' exp COMMA exp ')'\n    | GROUPING '(' exp ')'\n    ;\n\npexp_e :\n    '(' exp ')'\n    ;\n\n\npexp_pfx2 :\n    pexp_pfx2 DOT (id dblink_clause? | key) (('[' exp_list ']')+)?\n    | pexp_pfx2 '(' opt_argument_list ')' ( keep_clause |  within_clause )?  (('[' exp_list ']')+)?\n    | pexp_pfx2 '.' ( EXECUTE | EXTRACT  )'(' opt_argument_list ')' (('[' exp_list ']')+)?\n    | pexp_c2_insert  (('[' exp_list ']')+)?\n    | XMLPARSE '(' raw_id exp raw_id? ')' (('[' exp_list ']')+)?\n    | XMLELEMENT '(' xmlele_name xmlele_sub_lst? ')' (('[' exp_list ']')+)?\n    | XMLAGG '(' exp order_by_options? ')' (('[' exp_list ']')+)?\n    | new_arr_expression\n    | pexp_cast\n    | stm_param_normal\n;\n\n\nmember2 :\n    variable_name dblink_clause?\n    ;\n\npexp_c2_insert :\n    member2\n    | new_obj_expression\n    | ':' trig_new_name '.' column_name\n    | NEW '.' column_name\n    | member2 '%' BULK EXCEPTION\n    | member2 '%' BULK ROWCOUNT\n;\n\n\nmember_access2 :\n    pexp_pfx2 (DOT id dblink_clause?)+\n    | pexp_pfx2 (DOT key)+\n    ;\n\ninvocation_expression2 :\n    pexp_pfx2  invocation_expression_low\n    ;\n\nmember :\n    id dblink_clause?\n    ;\n\nkey :\n    FIRST\n    | NEXT\n    | PRIOR\n    | DELETE\n    | GET\n    | SET\n    | EXISTS\n    | TRIM\n    | ROWNUM\n    | ROWS\n    ;\n\nmember_access :\n    pexp_pfx ((DOT id dblink_clause?)+ | (DOT key)+ | (DOT '*')+)\n    ;\n\ninvocation_expression :\n    pexp_pfx invocation_expression_low\n    | xmlfun_inv_expression\n    | xmlagg_inv_expression\n    ;\n\ninvocation_expression_low :\n    ('.' EXECUTE LR_BRACKET opt_argument_list? RR_BRACKET)+\n    | (LR_BRACKET opt_argument_list? RR_BRACKET (keep_clause | within_clause)? )+\n    ;\n\nxmlagg_inv_expression :\n    XMLAGG '(' exp order_by_options? ')'\n    ;\n\nxmlfun_inv_expression :\n    XMLPARSE '(' raw_id exp raw_id ')'\n    | XMLPARSE '(' raw_id exp ')'\n    | XMLELEMENT '(' xmlele_name xmlele_sub_lst? ')'\n    | pexp_pfx (DOT EXTRACT '(' opt_argument_list? ')')+\n    ;\n\nxmlele_name :\n    id\n    | EVALNAME exp\n    ;\n\nxmlele_sub_lst :\n    COMMA xmlval_lst\n    | COMMA XMLATTRIBUTES '(' xmlattr_lst ')'\n    | COMMA XMLATTRIBUTES '(' xmlattr_lst ')' COMMA xmlval_lst\n    ;\n\nxmlattr_lst :\n    xmlattr (COMMA xmlattr)*\n    ;\n\nxmlattr :\n    exp\n    | exp id\n    | exp AS id\n    | exp AS EVALNAME exp\n    ;\n\nxmlval_lst :\n    exp (COMMA exp)*\n    ;\n\nkeep_clause :\n    KEEP '(' DENSE_RANK FIRST order_by_options? ')'\n    | KEEP '(' DENSE_RANK LAST order_by_options? ')'\n    ;\n\nwithin_clause :\n    WITHIN GROUP '(' order_by_options? ')'\n    ;\n\ntypeof_expression :\n    TYPEOF '(' sizeof_type ')'\n    ;\n\nnew_obj_expression :\n    NEW qualified_name '(' opt_argument_list? ')'\n    ;\n\nnew_arr_expression :\n    array_creation_expression\n    ;\n\narray_creation_expression :\n    NEW new_array_type '[' exp_list ']' opt_rank_specifier? opt_array_initializer?\n    | NEW STRUCT new_array_type '[' exp_list ']' opt_rank_specifier? opt_array_initializer?\n    ;\n\nplsql_datatype_ex :\n    INTERVAL interval_qualifier\n    | qualified_name '%' TYPE\n    | qualified_name '%' ROWTYPE\n    | REF qualified_name\n    | CURSOR\n    ;\n\nnew_array_type :\n    plsql_datatype_ex\n    | dtype\n    | REF CURSOR\n    ;\n\nopt_array_initializer :\n    array_initializer\n    ;\n\narray_initializer :\n    '{' '}'\n    | '{' variable_initializer_list opt_comma? '}'\n    ;\n\nvariable_initializer_list :\n    variable_initializer (COMMA variable_initializer)*\n    ;\n\nvariable_initializer :\n    exp\n    ;\n\nopt_comma :\n    COMMA\n    ;\n\nsizeof_expression :\n    SIZEOF '(' type_name ')'\n    ;\n\nelement_access :\n    pexp_c ('[' exp_list ']')+\n    ;\n\ndecode_case :\n    DECODE '(' exp_list ')'\n    ;\n\nelse_exp :\n    ELSE exp\n    ;\n\nboolean_case :\n    CASE bool_exp? bool_when_list else_exp? END case_option?\n    ;\n\nif_exp :\n    IF '(' bool_exp COMMA bool_exp COMMA bool_exp ')'\n    ;\n\nbool_when_list :\n    (WHEN bool_exp THEN exp)+\n    ;\n\nops :\n    '='\n    | '=='\n    | '>'\n    | '<'\n    | '<' '>'\n    | '>' '='\n    | '<' '='\n    | OPR_NE\n    | OPR_GE\n    | OPR_LE\n    | OP_MULT_ASSIGN\n    ;\n\nvalue_list :\n    exp_list\n    ;\n\nin_value_list :\n    in_value_exp\n    ;\n\nvalue_list_set :\n    '(' value_list ')' (COMMA '(' value_list ')')*\n    ;\n\ncomma_list :\n    COMMA+\n    ;\n\nins_value_list :\n    ins_exp_list\n    | comma_list ins_exp_list\n    ;\n\nnull_value :\n    NULL\n    ;\n\nid_and_rsvd_word_others :\n    new_none_reserved_word\n    | alias_resvd_word\n    | variable_resvd_word\n    | schname_resvd_word\n    ;\n\nid_and_rsvd_word :\n    raw_id\n    | reserved_word\n    | id_and_rsvd_word_others\n    ;\n\nstm_param :\n    stm_param_normal\n    | stm_param_name\n    ;\n\nstm_param_normal :\n    '?'\n    | ':' LT_INTEGER\n    | ':' '<' LT_INTEGER param_name_options? '>'\n    | '^' '?' '^'\n    ;\n\nstm_param_name :\n    ':' id_and_rsvd_word\n    ;\n\nparam_name_options :\n    id\n    ;\n\ncontains_query_exp :\n    exp\n    | contains_query_exp (AND | OR | AND NOT) contains_query_exp\n    ;\n\ncontains_query_exp_lst :\n    contains_query_exp (COMMA contains_query_exp)*\n    ;\n\ncontains_exp :\n    CONTAINS '(' exp COMMA contains_query_exp ')'\n    | CONTAINS '(' exp COMMA contains_query_exp COMMA contains_query_exp ')'\n    | CONTAINS '(' exp COMMA contains_query_exp COMMA SYSTEM LABEL COMMA LT_INTEGER COMMA LT_INTEGER ')'\n    | CONTAINS '(' exp COMMA contains_query_exp COMMA contains_query_exp COMMA contains_query_exp_lst ')'\n    ;\n\nstrict_option :\n    '(' LAX ')'\n    | LAX\n    | '(' STRICT ')'\n    | STRICT\n    ;\n\nwith_unique_option :\n    WITHOUT UNIQUE KEYS\n    | WITH UNIQUE KEYS\n    ;\n\ntype_option :\n    TYPE\n    ;\n\ntype_element :\n    qualified_name\n    ;\n\ntype_element_list :\n    type_element (COMMA type_element)*\n    ;\n\nbool_exp :\n    exp\n    | bool_exp_element\n    ;\n\nbool_exp_element :\n    exp IS not_tag? JSON strict_option? with_unique_option?\n    | exp IS not_tag? OF type_option? '(' type_element_list ')'\n    | NOT (bool_exp_element | exp)\n    //| (bool_exp_element | exp) (AND | OR) (bool_exp_element | exp)\n    | bool_exp_element (AND | OR) (bool_exp_element | exp)\n    | exp (AND | OR) (bool_exp_element | exp)\n    | exp not_tag? IN (select_with_paran | in_value_list | ('(' value_list ')'))\n    | '(' exp_list_2 ')' not_tag? IN (select_with_paran |  ('(' value_list_set ')'))\n    | '(' exp_list_2 ')' ops query_any_options? (select_with_paran | ('(' value_list_set ')'))\n    | exp ops query_any_options (select_with_paran |  ('(' value_list_set ')'))\n    | EXISTS select_with_paran\n    | exp ops exp\n    | exp IS not_tag? NULL\n    | exp NOT? BETWEEN exp AND exp\n    | exp NOT? LIKE exp (ESCAPE exp)?\n    | pexp_pfx '.' ROW NOT? LIKE exp (ESCAPE exp)?\n    | BINARY_KEYWORD pexp_pfx '.' ROW NOT? LIKE exp (ESCAPE exp)?\n    | '(' exp_list_2 ')' OVERLAPS '(' exp_list_2 ')'\n    | LNNVL '(' (bool_exp_element | exp) ')'\n    | exp not_tag? MEMBER OF exp\n    | '(' bool_exp_element ')'\n    ;\n\nquery_any_options :\n    ALL\n    | SOME\n    | ANY\n    | EVERY\n    ;\n\nglobal_var :\n    LT_GLOBAL_VAR\n    ;\n\nreserved_word :\n    IFNULL\n    | ABSOLUTE\n    | ADD\n    | ALL\n    | ALTER\n    | AND\n    | ANY\n    | ARRAYLEN\n    | AS\n    | ASC\n    | ASSIGN\n    | AUDIT\n    | BEGIN\n    | BETWEEN\n    | BIGDATEDIFF\n    | BOOL\n    | BOTH\n    | BSTRING\n    | BY\n    | BYTE\n    | CALL\n    | CASE\n    | CAST\n    | CHAR\n    | CHECK\n    | CLUSTER\n    | COLUMN\n    | COMMIT\n    | COMMITWORK\n    | COMMENT\n    | CONNECT\n    | CONNECT_BY_ROOT\n    | CONSTRAINT\n    | CONTAINS\n    | CONTEXT\n    | CONVERT\n    | CORRESPONDING\n    | CREATE\n    | CRYPTO\n    | CURRENT\n    | CURSOR\n    | DATEADD\n    | DATEDIFF\n    | DATEPART\n    | DECIMAL\n    | DECLARE\n    | DECODE\n    | DEFAULT\n    | DELETE\n    | DESC\n    | DISTINCT\n    | DISTRIBUTED\n    | DOUBLE\n    | DROP\n    | ELSE\n    | ELSEIF\n    | END\n    | EXECUTE\n    | EXISTS\n    | EXIT\n    | EXPLAIN\n    | EXTRACT\n    | FETCH\n    | FINAL\n    | FIRST\n    | FLOAT\n    | FOR\n    | FOREIGN\n    | FROM\n    | FULLY\n    | FUNCTION\n    | GOTO\n    | GRANT\n    | GROUP\n    | HAVING\n    | IDENTITY\n    | IF\n    | IMMEDIATE\n    | IN\n    | INDEX\n    | INSERT\n    | INT\n    | INTERVAL\n    | INTO\n    | IS\n    | LEAD\n    | LIKE\n    | LOGIN\n    | LOOP\n    | MEMBER\n    | NEW\n    | NEXT\n    | NOT\n    | NULL\n    | OBJECT\n    | OF\n    | ON\n    | OR\n    | ORDER\n    | OUT\n    | PARTITION\n    | PENDANT\n    | PERCENT\n    | PRIMARY\n    | PRINT\n    | PRIOR\n    | PRIVILEGES\n    | PROCEDURE\n    | PUBLIC\n    | RAISE\n    | RECORD\n    | REF\n    | REFERENCES\n    | REFERENCE\n    | REFERENCING\n    | RELATIVE\n    | REPEAT\n    | RETURN\n    | REVERSE\n    | REVOKE\n    | ROLLBACK\n    | ROW\n    | ROWNUM\n    | ROWS\n    | SAVEPOINT\n    | SCHEMA\n    | SELECT\n    | SET\n    | SOME\n    | SUBPARTITION\n    | SWITCH\n    | SYNONYM\n    | TABLE\n    | TIMESTAMPADD\n    | TIMESTAMPDIFF\n    | TO\n    | TOP\n    | TRAIL\n    | TRIGGER\n    | TRIM\n    | TRUNCATE\n    | UNION\n    | UNIQUE\n    | UNTIL\n    | UPDATE\n    | USER\n    | USING\n    | VALUES\n    | VARRAY\n    | VIEW\n    | WHEN\n    | WHENEVER\n    | WHILE\n    | WITH\n    | DISKSPACE\n    | RETURNING\n    | SBYTE\n    | SHORT\n    | USHORT\n    | UINT\n    | ULONG\n    | VOID\n    | CONST\n    | DO\n    | BREAK\n    | CONTINUE\n    | THROW\n    | FINALLY\n    | TRY\n    | CATCH\n    | PROTECTED\n    | PRIVATE\n    | ABSTRACT\n    | SEALED\n    | STATIC\n    | VIRTUAL\n    | OVERRIDE\n    | EXTERN\n    | CLASS\n    | STRUCT\n    | GET\n    | SIZEOF\n    | TYPEOF\n    | ADMIN\n    | REPLICATE\n    | VERIFY\n    | EQU\n    | EXCHANGE\n    | CLUSTERBTR\n    | LIST\n    | ARRAY\n    | ROLLUP\n    | CUBE\n    | GROUPING\n    | OVER\n    | SECTION\n    | SETS\n    | DOMAIN\n    | COLLATION\n    | OVERLAY\n    | EVERY\n    | KEEP\n    | WITHIN\n    | LNNVL\n    | NOCOPY\n    | INLINE\n    | TYPEDEF\n    | XMLTABLE\n    | XMLPARSE\n    | XMLAGG\n    | AUTO_INCREMENT\n    | BINARY_KEYWORD\n    | XMLELEMENT\n    | XMLATTRIBUTES\n    | EVALNAME\n    | LEXER\n    | FLASHBACK\n    | NOCYCLE\n    | NOSORT\n    | OPTIMIZE\n    | VERSIONS\n    | LARGE\n    | WITHOUT\n    | PIPE\n    | XML\n    | JSON_TABLE\n    | SUBSCRIBE\n    | LESS\n    | THAN\n    ;\n\nnew_none_reserved_word :\n    ACROSS\n    | ABORT\n    | ROWID\n    | ACTION\n    | AFTER\n    | ALLOW_DATETIME\n    | ALLOW_IP\n    | ANALYZE\n    | ARCHIVEDIR\n    | ARCHIVELOG\n    | ARCHIVESTYLE\n    | AT_KEYWORD\n    | ATTACH\n    | AUTO\n    | AVG\n    | BACKUP\n    | BACKUPDIR\n    | BACKUPINFO\n    | BAKFILE\n    | BEFORE\n    | BIGINT\n    | DEVICE\n    | PARMS\n    | TRACE\n    | FILE\n    | BIT\n    | BITMAP\n    | BLOB\n    | BLOCK\n    | BOOLEAN\n    | CACHE\n    | CASCADE\n    | CASCADED\n    | CATALOG\n    | CHAIN\n    | CALCULATE\n    | CHARACTER\n    | CIPHER\n    | CLOB\n    | COMMITTED\n    | COMPILE\n    | DUMP\n    | JOB\n    | COMPRESS\n    | COMPRESSED\n    | CONNECT_BY_IS_CYCLE\n    | CONNECT_BY_IS_LEAF\n    | CONNECT_IDLE_TIME\n    | COUNT\n    | COUNTER\n    | CTLFILE\n    | CYCLE\n    | SEARCH\n    | DEPTH\n    | BREADTH\n    | DANGLING\n    | DATAFILE\n    | DATE\n    | DATETIME\n    | DBFILE\n    | DEBUG\n    | DEC\n    | DEFERRABLE\n    | DEFERRED\n    | DELETING\n    | DELTA\n    | DEREF\n    | DETACH\n    | DISCONNECT\n    | DOWN\n    | EACH\n    | ENCRYPT\n    | ENCRYPTION\n    | ESCAPE\n    | EVENTINFO\n    | EXCLUSIVE\n    | EXTERNAL\n    | EXTERNALLY\n    | FAILED_LOGIN_ATTEMPS\n    | FAILED_LOGIN_ATTEMPTS\n    | FILEGROUP\n    | FILLFACTOR\n    | FORCE\n    | FREQUENCE\n    | GLOBAL\n    | GLOBALLY\n    | HASH\n    | HEXTORAW\n    | IDENTIFIED\n    | IDENTITY_INSERT\n    | IMAGE\n    | INCREASE\n    | INCREMENT\n    | INITIAL\n    | INITIALLY\n    | INNERID\n    | INSERTING\n    | INSTEAD\n    | INTEGER\n    | INTENT\n    | ISOLATION\n    | KEY\n    | LABEL\n    | LOCAL\n    | LOCALLY\n    | LOGFILE\n    | LOGOUT\n    | LONG\n    | LONGVARBINARY\n    | LONGVARCHAR\n    | MANUAL\n    | MATCH\n    | MATCHED\n    | MAX\n    | MAXSIZE\n    | MAXVALUE\n    | MERGE\n    | MIN\n    | MINEXTENTS\n    | MINVALUE\n    | MODE\n    | MODIFY\n    | MONEY\n    | MOUNT\n    | NO\n    | NOARCHIVELOG\n    | NOAUDIT\n    | NOCACHE\n    | NOMAXVALUE\n    | NOMINVALUE\n    | NOORDER\n    | NOT_ALLOW_DATETIME\n    | NOT_ALLOW_IP\n    | NOWAIT\n    | NUMBER\n    | NUMERIC\n    | OFF\n    | OFFLINE\n    | CORRUPT\n    | ONLY\n    | OPTION\n    | OUTER\n    | OVERLAPS\n    | CONSTANT\n    | PAGE\n    | PARTIAL\n    | PARTITIONS\n    | PASSWORD_GRACE_TIME\n    | PASSWORD_LIFE_TIME\n    | PARALLEL\n    | CPU_PER_CALL\n    | CPU_PER_SESSION\n    | MEM_SPACE\n    | READ_PER_CALL\n    | READ_PER_SESSION\n    | PASSWORD_LOCK_TIME\n    | PASSWORD_POLICY\n    | PASSWORD_REUSE_MAX\n    | PASSWORD_REUSE_TIME\n    | PRECISION\n    | PRESERVE\n    | RAWTOHEX\n    | READ\n    | REAL\n    | REBUILD\n    | RELATED\n    | RENAME\n    | REPEATABLE\n    | REPLACE\n    | RESTORE\n    | RESTRICT\n    | PLACING\n    | ROLE\n    | ROLLFILE\n    | ROOT\n    | ROWCOUNT\n    | RULE\n    | SALT\n    | SCOPE\n    | SERERR\n    | SERIALIZABLE\n    | SESSION_PER_USER\n    | SHARE\n    | SHUTDOWN\n    | SIBLINGS\n    | SMALLINT\n    | SNAPSHOT\n    | SOUND\n    | SPATIAL\n    | SPLIT\n    | SQL\n    | STARTUP\n    | STATEMENT\n    | STORAGE\n    | STRING\n    | STYLE\n    | SUBSTRING\n    | SUCCESSFUL\n    | SUM\n    | SUSPEND\n    | SYNC\n    | SYS_CONNECT_BY_PATH\n    | TEMPORARY\n    | TEXT\n    | THEN\n    | TIES\n    | TIME\n    | TIMES\n    | TIMESTAMP\n    | TINYINT\n    | TRANSACTION\n    | TRIGGERS\n    | TRUNCSIZE\n    | UNCOMMITTED\n    | UNDER\n    | UNLIMITED\n    | UP\n    | UPDATING\n    | VALUE\n    | VARBINARY_KEYWORD\n    | VARCHAR\n    | VARCHAR2\n    | STDDEV\n    | VARIANCE\n    | VARYING\n    | VSIZE\n    | WORK\n    | WRITE\n    | SEQUENCE\n    | SERVER\n    | TIMER\n    | WEEK\n    | ONCE\n    | ZONE\n    | VERTICAL\n    | QUOTA\n    | LOG\n    | NONE\n    | LOB\n    | ERROR\n    | PASSWORD\n    | EXPIRE\n    | BACKUPSET\n    | MAXPIECESIZE\n    | BACKED\n    | SINCE\n    | DDL_CLONE\n    | CUMULATIVE\n    | NORMAL\n    | STANDBY\n    | TRANSACTIONAL\n    | STORE\n    | BRANCH\n    | NOBRANCH\n    | READONLY\n    | UNBOUNDED\n    | PRECEDING\n    | FOLLOWING\n    | AUTOEXTEND\n    | WRAPPED\n    | BTREE\n    | CONNECT_TIME\n    | TRXID\n    | THROUGH\n    | SCN\n    | VERSIONS_STARTTIME\n    | VERSIONS_ENDTIME\n    | VERSIONS_STARTTRXID\n    | VERSIONS_ENDTRXID\n    | VERSIONS_OPERATION\n    | RANDOMLY\n    | COPY\n    | PATH\n    | HUGE\n    | FILESIZE\n    | SESSION\n    | QUERY_REWRITE_INTEGRITY\n    | REFRESH\n    | MATERIALIZED\n    | FAST\n    | COMPLETE\n    | DEMAND\n    | MIRROR\n    | NEVER\n    | BUILD\n    | PURGE\n    | SYNCHRONOUS\n    | ASYNCHRONOUS\n    | PREBUILT\n    | REDUCED\n    | BASE\n    | SELF\n    | INDEXES\n    | EXCEPTION_INIT\n    | AUTONOMOUS_TRANSACTION\n    | INDICES\n    | EXCEPTIONS\n    | SAVE\n    | RESULT\n    | COLLATE\n    | PAD\n    | SPACE_KEYWORD\n    | EVENTS\n    | NCHAR\n    | NCHARACTER\n    | NATIONAL\n    | USE_HASH\n    | USE_MERGE\n    | USE_NL\n    | USE_NL_WITH_INDEX\n    | TIME_ZONE\n    | DIAGNOSTICS\n    | SIMPLE\n    | CHARACTERISTICS\n    | INSENSITIVE\n    | ASENSITIVE\n    | SENSITIVE\n    | SCROLL\n    | HOLD\n    | SUBPARTITIONS\n    | TEMPLATE\n    | NULLS\n    | DENSE_RANK\n    | SYSTEM\n    | MEMORY\n    | SPFILE\n    | AUTHID\n    | CURRENT_USER\n    | CURRENT_SCHEMA\n    | DEFINER\n    | ACCESSED\n    | INITIALIZED\n    | LOGGING\n    | NOLOGGING\n    | DETERMINISTIC\n    | TABLESPACE\n    | COLUMNS\n    | WAIT\n    | SKIP_KEYWORD\n    | LOCKED\n    | PARALLEL_ENABLE\n    | AGGREGATE\n    | SIZE\n    | LEVEL\n    | REPLAY\n    | DICTIONARY\n    | PRIVILEGE\n    | BUFFER\n    | MOVE\n    | MOVEMENT\n    | ACCOUNT\n    | UNLOCK\n    | INCLUDING\n    | EXCLUDING\n    | JAVA\n    | INVISIBLE\n    | VISIBLE\n    | UNUSABLE\n    | DATA\n    | CONSTRAINTS\n    | OLD\n    | MAPPED\n    | LOGON\n    | LOGOFF\n    | RANGE\n    | ARCHIVE\n    | FIELDS\n    | DELIMITED\n    | RECORDS\n    | ERRORS\n    | LSN\n    | INPUT\n    | INCLUDE\n    | EXCLUDE\n    | DDL\n    | DIRECTORY\n    | LOCATION\n    | RESULT_CACHE\n    | PIPELINED\n    | MONITORING\n    | NOMONITORING\n    | EXTENDS\n    | NODE\n    | STRICT\n    | LAX\n    | FORMAT\n    | JSON\n    | KEYS\n    | ASCII\n    | PRETTY\n    | WRAPPER\n    | EMPTY\n    | CONDITIONAL\n    | UNCONDITIONAL\n    | TASK\n    | THREAD\n    | BADFILE\n    | ADVANCED\n    | ROWDEPENDENCIES\n    | NOROWDEPENDENCIES\n    | SPAN\n    | MON\n    | TUE\n    | WED\n    | THU\n    | FRI\n    | SAT\n    | SUN\n    | JAN\n    | FEB\n    | MAR\n    | APR\n    | MAY\n    | JUN\n    | JUL\n    | AUG\n    | SEP\n    | OCT\n    | NOV\n    | YEARLY\n    | MONTHLY\n    | WEEKLY\n    | DAILY\n    | HOURLY\n    | MINUTELY\n    | SECONDLY\n    | BYMONTH\n    | BYWEEKNO\n    | BYYEARDAY\n    | BYMONTHDAY\n    | BYDAY\n    | BYHOUR\n    | BYMINUTE\n    | BYSECOND\n    | USAGE\n    | EXCEPTION\n    | DATABASE\n    | LAST\n    | PACKAGE\n    | PASSING\n    | GREAT\n    | MICRO\n    | LOCAL_OBJECT\n    | LINK\n    | RESTRICT_REFERENCES\n    | REJECT\n    | PROFILE\n    | HASHPARTMAP\n    | SPEED\n    | STOP\n    | INSTANCE\n    | IGNORE_ROW_ON_DUPKEY_INDEX\n    | EDITIONABLE\n    | NONEDITIONABLE\n    | BATCH\n    | ORDINALITY\n    | STRIPING\n    | HIGH\n    | DISKGROUP\n    | SHADOW\n    | CASE_SENSITIVE\n    | LEFTARG\n    | RIGHTARG\n    | OPERATOR\n    | RESIZE\n    | SCHEMABINDING\n    | CHANGE\n    | TRACKING\n    | SUBSTITUTABLE\n    | LEVELS\n    | IDENTIFIER_KEYWORD\n    | GENERATED\n    | OIDINDEX\n    | NOPARALLEL\n    | COLLECT\n    | DML\n    | APPLY\n    | CHECKPOINT\n    | NOVALIDATE\n    | QUERY\n    ;\n\ninterval_nresvd_word :\n    YEAR\n    | MONTH\n    | DAY\n    | HOUR\n    | MINUTE\n    | SECOND\n    ;\n\nvariable_resvd_word :\n    TYPE\n    | SUBTYPE\n    | MAP\n    | INSTANTIABLE\n    | CONSTRUCTOR\n    | OVERRIDING\n    | PRAGMA\n    | CLOSE\n    | OPEN\n    | LOCK\n    | STAT\n    | FORALL\n    | DISABLE\n    | ENABLE\n    ;\n\nalias_resvd_word :\n    interval_nresvd_word\n    | LEFT\n    | RIGHT\n    | EXCEPT\n    | MINUS\n    | INTERSECT\n    | CROSS\n    | FULL\n    | INNER\n    | JOIN\n    | NATURAL\n    | WHERE\n    | BULK\n    | OFFSET\n    | MOD\n    | SEED\n    | SAMPLE\n    | PIVOT\n    | ONLINE\n    | UNPIVOT\n    | LIMIT\n    | MULTISET\n    ;\n\nschname_resvd_word :\n    AUTHORIZATION\n    ;\n\nraw_id :\n    LT_IDENTIFIER\n    ;\n\nid :\n    raw_id\n    | new_none_reserved_word\n    | schname_resvd_word\n    | alias_resvd_word\n    | variable_resvd_word\n    ;\n\nqualified_name :\n    id ('.' id)*\n    ;\n\nqualified_name2 :\n    id ('.' id)*\n    ;\n\nvariable_name :\n    raw_id\n    | new_none_reserved_word\n    | schname_resvd_word\n    | alias_resvd_word\n    ;\n\nend_loop_label_null :\n    END LOOP label_name_options?\n    ;\n\nlabel_name_options :\n    label_name\n    ;\n\nlabel_name :\n    id\n    ;\n\ndatabase_name :\n    id\n    ;\n\nbackup_name :\n    id\n    ;\n\nfull_proc_name :\n    qualified_name\n    ;\n\nfull_proc_name2 :\n    qualified_name2\n    ;\n\nfull_fun_name :\n    qualified_name\n    ;\n\nfull_table_name :\n    qualified_name\n    ;\n\nfull_grp_name :\n    qualified_name\n    ;\n\nfull_table_name2 :\n    qualified_name2\n    ;\n\nfull_partition_name :\n    raw_id\n    ;\n\nfull_schema_name :\n    schema_name\n    | database_name '.' schema_name\n    ;\n\ntable_name :\n    id\n    ;\n\ncolumn_name :\n    id\n    ;\n\nconstraint_name :\n    id\n    ;\n\nfull_trigger_name :\n    qualified_name\n    ;\n\nfull_trigger_name2 :\n    qualified_name2\n    ;\n\nfull_view_name :\n    qualified_name\n    ;\n\nfull_view_name2 :\n    qualified_name2\n    ;\n\ncursor_name :\n    raw_id\n    ;\n\ntrigger_name :\n    id\n    ;\n\nlogin_name :\n    id\n    ;\n\nprofile_name :\n    DEFAULT\n    | id\n    ;\n\nuser_name :\n    id\n    ;\n\nrole_name :\n    id\n    | PUBLIC\n    ;\n\nuser_role_name :\n    role_name\n    ;\n\nrole_name_list :\n    role_name\n    | role_name COMMA role_name_list\n    ;\n\nfull_func_name :\n    qualified_name2\n    ;\n\nparam_name :\n    id\n    ;\n\nindex_name :\n    id\n    | id '.' id\n    ;\n\nindex_name2 :\n    id\n    | id '.' id\n    | id '.' id '.' id\n    ;\n\ntrig_old_name :\n    variable_name\n    | NEW\n    ;\n\ntrig_new_name :\n    variable_name\n    | variable_resvd_word\n    | NEW\n    ;\n\nfull_tv_name :\n    qualified_name dblink_clause2? ((PARTITION | SUBPARTITION) ('(' full_partition_name ')' | FOR '(' value_list ')'))?\n    | qualified_name INDEX (id | LT_INTEGER)\n    ;\n\nfull_object_name :\n    qualified_name\n    ;\n\norient_option :\n    LEAD\n    | TRAIL\n    | BOTH\n    ;\n\ndatepart :\n    raw_id\n    | YEAR\n    | MONTH\n    | WEEK\n    | DAY\n    | HOUR\n    | MINUTE\n    | SECOND\n    ;\n\ndatepart_op :\n    datepart\n    ;\n\ndatead_fun :\n    DATEADD\n    | DATEDIFF\n    | BIGDATEDIFF\n    | TIMESTAMPADD\n    | TIMESTAMPDIFF\n    ;\n\nreturning :\n    RETURNING dtype double_length_option?\n    ;\n\npretty :\n    ASCII\n    | PRETTY\n    | PRETTY ASCII\n    ;\n\nwrapper_flag :\n    WRAPPER\n    | ARRAY WRAPPER\n    ;\n\narray_wrapper :\n    WITHOUT wrapper_flag\n    | WITH wrapper_flag\n    | WITH UNCONDITIONAL wrapper_flag\n    | WITH CONDITIONAL wrapper_flag\n    ;\n\njson_tail_on_empty :\n    empty_handle\n    | DEFAULT exp ON EMPTY\n    ;\n\nempty_handle :\n    NULL ON EMPTY\n    | ERROR ON EMPTY\n    ;\n\njson_tail_on_error_null :\n    error_handle?\n    | DEFAULT exp ON ERROR\n    ;\n\nerror_handle :\n    NULL ON ERROR\n    | ERROR ON ERROR\n    | EMPTY ON ERROR\n    | TRUE ON ERROR\n    | FALSE ON ERROR\n    ;\n\nsavepoint_name :\n    id\n    ;\n\nalias :\n    raw_id\n    | new_none_reserved_word\n    | schname_resvd_word\n    | '*'\n    | variable_resvd_word\n    | interval_nresvd_word\n    ;\n\nalias_2 :\n    id\n    ;\n\nfull_column_name :\n    qualified_name\n    ;\n\nschema_name :\n    raw_id\n    | new_none_reserved_word\n    | variable_resvd_word\n    ;\n\nnot_tag :\n    NOT\n    ;\n\ndebug_tag :\n    DEBUG\n    ;\n\ncolumn_tag :\n    COLUMN\n    ;\n\npendant_tag :\n    PENDANT\n    ;\n\nunique_tag :\n    UNIQUE\n    | BITMAP\n    | SPATIAL\n    | ARRAY\n    ;\n\npartition_tag :\n    CLUSTER\n    | NOT PARTIAL\n    ;\n\nrow_tag :\n    ROW\n    ;\n\nas_tag :\n    AS\n    ;\n\nfrom_tag :\n    FROM\n    ;\n\ninto_tag :\n    INTO\n    ;\n\nwork_tag :\n    WORK\n    ;\n\nwith_grant_option :\n    WITH GRANT OPTION\n    ;\n\nwith_admin_option :\n    WITH ADMIN OPTION\n    ;\n\ntime_zone_or_local :\n    TIME ZONE\n    | LOCAL TIME ZONE\n    ;\n\nsub_plsql_datatype :\n    datatype\n    | qualified_name dblink_clause? '%' TYPE\n    | qualified_name dblink_clause? '%' ROWTYPE\n    ;\n\ndatatype_list :\n    datatype (COMMA datatype)*\n    ;\n\ndatatype :\n    dtype double_length_option? (WITH time_zone_or_local | WITHOUT TIME ZONE)?\n    | INTERVAL interval_qualifier\n    | dtype LARGE OBJECT double_length_option?\n    ;\n\ndatatype2 :\n    dtype1 double_length_option?\n    | INTERVAL interval_qualifier\n    ;\n\nopr_dtype :\n    dtype\n    | NULL\n    ;\n\nopr_datatype_lst :\n    opr_dtype COMMA opr_dtype\n    ;\n\ninterval_qualifier :\n    interval_nresvd_word double_length_option? (TO interval_nresvd_word double_length_option?)?\n    ;\n\ndtype :\n    dtype1\n    | dtype2\n    ;\n\ndtype1 :\n    qualified_name\n    | BINARY_KEYWORD\n    | sql_builtin_types\n    ;\n\ndtype2 :\n    CHAR VARYING\n    | CHARACTER VARYING\n    | NCHAR VARYING\n    | NATIONAL CHAR VARYING\n    | NATIONAL CHAR\n    | NCHARACTER VARYING\n    | NATIONAL CHARACTER VARYING\n    | NATIONAL CHARACTER\n    | DOUBLE PRECISION\n    | REF '(' qualified_name ')'\n    ;\n\ndouble_length_option :\n    '(' LT_INTEGER size_unit_caluse? ')'\n    | '(' LT_INTEGER COMMA LT_INTEGER ')'\n    | '(' '*' COMMA LT_INTEGER ')'\n    ;\n\nsize_unit_caluse :\n    CHAR\n    | BYTE\n    ;\n\nlt_integer_negative :\n    LT_INTEGER\n    | '-' LT_INTEGER\n    ;\n\ncreate_contextindex_stmt :\n    CREATE replace_option? CONTEXT INDEX not_exist? index_name ON full_table_name '(' index_column_list ')' storage_tag? lexer_clause? sync?\n    ;\n\nlexer_name :\n    id\n    ;\n\nlexer_clause :\n    LEXER lexer_name\n    ;\n\nlexer_clause2 :\n    LEXER lexer_name\n    ;\n\nsync :\n    SYNC\n    | SYNC TRANSACTION\n    ;\n\ndrop_contextindex_stmt :\n    DROP CONTEXT INDEX exist? index_name ON full_table_name\n    ;\n\nalter_contextindex_stmt :\n    alter_tag CONTEXT INDEX index_name ON full_table_name cti_sync_option online_options? lexer_clause2?\n    ;\n\ncti_sync_option :\n    REBUILD\n    | INCREMENT\n    | OPTIMIZE\n    ;\n\ntype_name :\n    qualified_name\n    | BINARY_KEYWORD\n    ;\n\nsizeof_type :\n    type_name\n    | builtin_types\n    ;\n\ntype :\n    sizeof_type\n    | array_type\n    ;\n\narray_type :\n    sizeof_type rank_specifiers\n    ;\n\nbuiltin_types :\n    OBJECT\n    | BSTRING\n    | BOOL\n    | DECIMAL\n    | FLOAT\n    | DOUBLE\n    | integral_type\n    ;\n\nintegral_type :\n    SBYTE\n    | BYTE\n    | SHORT\n    | USHORT\n    | INT\n    | UINT\n    | ULONG\n    | CHAR\n    | VOID\n    ;\n\nsql_builtin_types :\n    BOOL\n    | DECIMAL\n    | FLOAT\n    | DOUBLE\n    | INT\n    | CHAR\n    | BYTE\n    ;\n\n\ncursor_declaration :\n    CURSOR cursor_name cursor_attrs_options? cursor_option?\n    ;\n\ncursor_declaration_2 :\n    cursor_declaration\n    | variable_name_list CURSOR cursor_attrs_options? cursor_option_2\n    ;\n\ncursor_attrs_options :\n    cursor_attrs\n    ;\n\ncursor_attrs :\n    cursor_attr\n    | cursor_attrs cursor_attr\n    ;\n\ncursor_attr :\n    INSENSITIVE\n    | SENSITIVE\n    | ASENSITIVE\n    | NO SCROLL\n    | SCROLL\n    | WITHOUT HOLD\n    | WITH HOLD\n    | WITHOUT RETURN\n    | WITH RETURN\n    | FAST\n    | NO FAST\n    ;\n\nopt_rank_specifier :\n    rank_specifiers\n    ;\n\nrank_specifiers :\n    rank_specifier\n    ;\n\nrank_specifier :\n    '[' opt_dim_separators? ']'\n    ;\n\nopt_dim_separators :\n    dim_separators\n    ;\n\nopt_rank_specifier2 :\n    opt_rank_specifier?\n    | '[' lt_int_lst ']'\n    ;\n\ndim_separators :\n    COMMA+\n    ;\n\nopt_argument_list :\n    mixed_param_list json_fun_tail\n    | bool_exp FROM exp (FOR exp)?\n    | all_distinct_option_2 exp\n    | all_distinct_option_2 exp_list_2\n    | '*'\n    | '+'\n    | without_into_select\n    ;\n\njson_fun_tail :\n    returning? pretty? array_wrapper? json_tail_on_error_null\n    | returning? pretty? array_wrapper? json_tail_on_empty json_tail_on_error_null\n    ;\n\nignore_nulls_clause :\n    IGNORE NULLS\n    | RESPECT NULLS\n    ;\n\nmixed_param_list :\n    mixed_param (COMMA mixed_param)*\n    ;\n\nmixed_param :\n    argument as_alias?\n    | param\n    ;\n\nargument :\n    bool_exp (FORMAT JSON)?\n    ;\n\ncursor_option :\n    cursor_option_2\n    ;\n\nwithout_into_select2 :\n    without_into_select\n    | select_with_paran\n    ;\n\ncursor_option_2 :\n    IS without_into_select2\n    | IS joined_table\n    | IS TABLE full_tv_name\n    | FOR without_into_select2\n    | FOR joined_table\n    | FOR TABLE full_tv_name\n    | '(' param_def_list ')' IS without_into_select2\n    | '(' param_def_list ')' RETURN plsql_datatype IS without_into_select2\n    | RETURN plsql_datatype IS without_into_select2\n    ;\n\nregion_size :\n    GREAT\n    | MICRO\n    ;\n\ncopy_num :\n    COPY LT_INTEGER\n    ;\n\nredundancy_clause :\n    EXTERNAL\n    | NORMAL\n    | HIGH\n    ;\n\nstriping_clause :\n    STRIPING LT_INTEGER\n    ;\n\nwith_huge_clause :\n    WITH HUGE PATH pathname region_size?\n    ;\n\n"
  },
  {
    "path": "superior-dameng-parser/src/main/kotlin/io/github/melin/superior/parser/dameng/AbstractSqlParser.kt",
    "content": "package io.github.melin.superior.parser.dameng\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.dameng.antlr4.DmSqlParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(DmSqlParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: DmSqlParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(DmSqlParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-dameng-parser/src/main/kotlin/io/github/melin/superior/parser/dameng/DmSqlAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.dameng\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.SQLParserException\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.TableType\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.DefaultStatement\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.alter.AlterTable\nimport io.github.melin.superior.common.relational.common.CommentStatement\nimport io.github.melin.superior.common.relational.common.ShowStatement\nimport io.github.melin.superior.common.relational.create.CreateMaterializedView\nimport io.github.melin.superior.common.relational.create.CreateTable\nimport io.github.melin.superior.common.relational.create.CreateView\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport io.github.melin.superior.parser.dameng.antlr4.DmSqlParser\nimport io.github.melin.superior.parser.dameng.antlr4.DmSqlParserBaseVisitor\nimport org.antlr.v4.runtime.ParserRuleContext\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/2/8. */\nclass DmSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) : DmSqlParserBaseVisitor<Statement>() {\n\n    private var rootTableId: TableId = TableId(\"\")\n    private var currentOptType: StatementType = StatementType.UNKOWN\n    private var limit: Int? = null\n    private var offset: Int? = null\n    private val primaryKeys = ArrayList<String>()\n\n    private var queryStmt: QueryStmt? = null\n    private var inputTables: ArrayList<TableId> = arrayListOf()\n    private var outputTables: ArrayList<TableId> = arrayListOf()\n    private var cteTempTables: ArrayList<TableId> = arrayListOf()\n\n    // 多语句解析结果\n    private var statements: ArrayList<Statement> = arrayListOf()\n    // 存储过程和函数中包含的子语句\n    private var childStatements: ArrayList<Statement> = arrayListOf()\n    private val sqls: ArrayList<String> = arrayListOf()\n\n    fun getSqlStatements(): List<Statement> {\n        return statements\n    }\n\n    fun getSplitSqls(): List<String> {\n        return sqls\n    }\n\n    override fun visitDmprogram(ctx: DmSqlParser.DmprogramContext): Statement? {\n        ctx.sql_clauses().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else {\n                        var statement = this.visitSql_clauses(it)\n                        if (statement == null) {\n                            statement = DefaultStatement(StatementType.UNKOWN)\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n                currentOptType = StatementType.UNKOWN\n            }\n        }\n\n        return null\n    }\n\n    override fun visitSelect_stmt(ctx: DmSqlParser.Select_stmtContext?): Statement? {\n        currentOptType = StatementType.SELECT\n        super.visitSelect_stmt(ctx)\n        return queryStmt\n    }\n\n    override fun visitQuery_exp(ctx: DmSqlParser.Query_expContext?): Statement? {\n        super.visitQuery_exp(ctx)\n        queryStmt = QueryStmt(inputTables, limit, offset)\n        val sql = source(ctx)\n        queryStmt?.setSql(sql)\n        return queryStmt\n    }\n\n    override fun visitMerge_into_stmt(ctx: DmSqlParser.Merge_into_stmtContext?): Statement {\n        currentOptType = StatementType.MERGE\n        super.visitMerge_into_stmt(ctx)\n        return MergeTable(rootTableId, inputTables)\n    }\n\n    override fun visitInsert_stmt(ctx: DmSqlParser.Insert_stmtContext?): Statement {\n        currentOptType = StatementType.INSERT\n        super.visitInsert_stmt(ctx)\n        var curQueryStmt: QueryStmt = QueryStmt()\n        if (queryStmt != null) {\n            curQueryStmt = queryStmt as QueryStmt\n        }\n        val retObj = InsertTable(InsertMode.INTO, curQueryStmt, rootTableId)\n        retObj.outputTables.clear()\n        retObj.outputTables.addAll(outputTables)\n        return retObj\n    }\n\n    override fun visitUpdate_stmt(ctx: DmSqlParser.Update_stmtContext?): Statement {\n        currentOptType = StatementType.UPDATE\n        super.visitUpdate_stmt(ctx)\n        return UpdateTable(rootTableId, inputTables)\n    }\n\n    override fun visitDelete_stmt(ctx: DmSqlParser.Delete_stmtContext?): Statement {\n        currentOptType = StatementType.DELETE\n        super.visitDelete_stmt(ctx)\n        return DeleteTable(rootTableId, inputTables)\n    }\n\n    override fun visitCreate_table_stmt(ctx: DmSqlParser.Create_table_stmtContext?): Statement {\n        currentOptType = StatementType.CREATE_TABLE\n        super.visitCreate_table_stmt(ctx)\n        return CreateTable(rootTableId, TableType.DAMENG)\n    }\n\n    override fun visitCreate_view_stmt(ctx: DmSqlParser.Create_view_stmtContext?): Statement {\n        currentOptType = StatementType.CREATE_VIEW\n        super.visitCreate_view_stmt(ctx)\n        return CreateView(rootTableId, QueryStmt(inputTables, limit, offset))\n    }\n\n    override fun visitCreate_materialized_view_stmt(ctx: DmSqlParser.Create_materialized_view_stmtContext?): Statement {\n        currentOptType = StatementType.CREATE_MATERIALIZED_VIEW\n        super.visitCreate_materialized_view_stmt(ctx)\n        return CreateMaterializedView(rootTableId, QueryStmt(inputTables, limit, offset))\n    }\n\n    override fun visitFull_view_name2(ctx: DmSqlParser.Full_view_name2Context?): Statement? {\n        if (currentOptType == StatementType.CREATE_VIEW\n            || currentOptType == StatementType.CREATE_MATERIALIZED_VIEW) {\n            if (ctx?.qualified_name2() != null) {\n                rootTableId = parseTableViewName(ctx.qualified_name2())\n            }\n        }\n        return super.visitFull_view_name2(ctx)\n    }\n\n    override fun visitComment_stmt(ctx: DmSqlParser.Comment_stmtContext): Statement {\n        super.visitComment_stmt(ctx)\n        var objValue: String? = null\n        val isNull = false\n        var objType: String = \"\"\n        val text: String = CommonUtils.cleanQuote(ctx.LT_STRING().text)\n        val fullTableName = ctx.full_table_name()\n        val fullColumnName = ctx.full_column_name()\n        val fullViewName = ctx.full_view_name()\n        if (fullTableName != null) {\n            objType = \"TABLE\"\n            objValue = fullTableName.qualified_name().text\n        } else if(fullColumnName != null) {\n            objType = \"COLUMN\"\n            objValue = fullColumnName.qualified_name().text\n        } else if(fullViewName != null) {\n            objType = \"VIEW\"\n            objValue = fullViewName.qualified_name().text\n        }\n        currentOptType = StatementType.COMMENT\n        return CommentStatement(text, isNull, objType, objValue)\n    }\n\n    override fun visitDrop_stmt(ctx: DmSqlParser.Drop_stmtContext?): Statement? {\n        super.visitDrop_stmt(ctx)\n        val dropDbObject = ctx?.drop_db_object()\n        if (dropDbObject?.db_object()?.text.equals(\"table\")) {\n            currentOptType = StatementType.DROP_TABLE\n            val dropStmtBody = ctx?.drop_stmt_body_1()\n            if (dropStmtBody?.full_object_name() != null) {\n                rootTableId = parseTableViewName(dropStmtBody.full_object_name().qualified_name())\n            } else if(dropStmtBody?.full_table_name() != null) {\n                rootTableId = parseTableViewName(dropStmtBody.full_table_name().qualified_name())\n            }\n            val dropTable = DropTable(rootTableId, dropDbObject?.exist()?.text == \"ifexists\")\n            if (dropStmtBody?.purge_option() != null) {\n                dropTable.purge = true\n            }\n            return dropTable\n        }\n        return null\n    }\n\n    override fun visitAlter_table_stmt(ctx: DmSqlParser.Alter_table_stmtContext): Statement {\n        currentOptType = StatementType.ALTER_TABLE\n        super.visitAlter_table_stmt(ctx)\n        rootTableId = parseTableViewName(ctx.full_table_name().qualified_name())\n        return AlterTable(rootTableId)\n    }\n\n    override fun visitFull_tv_name(ctx: DmSqlParser.Full_tv_nameContext): Statement? {\n        super.visitFull_tv_name(ctx)\n        val tableId = parseTableViewName(ctx.qualified_name())\n        val parentLv2 = ctx.parent?.parent\n        val parentLv5 = parentLv2?.parent?.parent?.parent\n        val parentLv6 = parentLv5?.parent\n        if (parentLv6 is DmSqlParser.Update_stmt_bodyContext\n            || parentLv5 is DmSqlParser.Delete_stmtContext\n            || parentLv2 is DmSqlParser.Insert_stmtContext\n            || parentLv5 is DmSqlParser.Insert_stmtContext\n            || parentLv5 is DmSqlParser.Insert_stmt_bodyContext\n            || parentLv5 is DmSqlParser.Multi_insert_stmt_bodyContext\n            || parentLv2 is DmSqlParser.Merge_into_stmtContext) {\n            if (rootTableId.tableName == \"\") {\n                tableId.also { rootTableId = it }\n            }\n            addOutputTableId(tableId)\n        } else {\n            if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {\n                inputTables.add(tableId)\n            }\n        }\n        return null\n    }\n\n    override fun visitFull_table_name(ctx: DmSqlParser.Full_table_nameContext?): Statement? {\n        if (ctx?.qualified_name() != null) {\n            rootTableId = parseTableViewName(ctx.qualified_name())\n        }\n        return super.visitFull_table_name(ctx)\n    }\n\n    private fun parseTableViewName(ctx: ParserRuleContext): TableId {\n        if (ctx.childCount == 1) {\n            return TableId(null, null, CommonUtils.cleanQuote(ctx.getChild(0).text))\n        } else if (ctx.childCount == 3) {\n            return TableId(null, CommonUtils.cleanQuote(ctx.getChild(0).text), CommonUtils.cleanQuote(ctx.getChild(2).text))\n        } else {\n            throw SQLParserException(\"not suuport tablename\")\n        }\n    }\n\n    private fun addOutputTableId(tableId: TableId) {\n        if (!outputTables.contains(tableId)) {\n            outputTables.add(tableId)\n        }\n    }\n}\n"
  },
  {
    "path": "superior-dameng-parser/src/main/kotlin/io/github/melin/superior/parser/dameng/DmSqlHelper.kt",
    "content": "package com.github.melin.superior.sql.parser.mysql\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.dameng.AbstractSqlParser\nimport io.github.melin.superior.parser.dameng.DmSqlAntlr4Visitor\nimport io.github.melin.superior.parser.dameng.antlr4.DmSqlLexer\nimport io.github.melin.superior.parser.dameng.antlr4.DmSqlParser\nimport io.github.melin.superior.parser.dameng.antlr4.DmSqlParserBaseVisitor\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/1/10. */\nobject DmSqlHelper {\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until DmSqlLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = DmSqlLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement {\n        val statements = this.parseMultiStatement(command)\n        if (statements.size != 1) {\n            throw IllegalStateException(\"only parser one sql, sql count: \" + statements.size)\n        } else {\n            return statements.get(0)\n        }\n    }\n\n    @JvmStatic\n    fun parseMultiStatement(command: String): List<Statement> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = DmSqlAntlr4Visitor(false, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSqlStatements()\n    }\n\n    @JvmStatic\n    fun splitSql(command: String): List<String> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = DmSqlAntlr4Visitor(true, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSplitSqls()\n    }\n\n    @JvmStatic\n    fun checkSqlSyntax(command: String) {\n        val sqlVisitor = DmSqlParserBaseVisitor<Statement>()\n        innerParseStatement(command, sqlVisitor)\n    }\n\n    private fun innerParseStatement(command: String, sqlVisitor: DmSqlParserBaseVisitor<Statement>) {\n        val charStream = UpperCaseCharStream(CharStreams.fromString(command))\n        val lexer = DmSqlLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = DmSqlParser(tokenStream)\n        AbstractSqlParser.installCaches(parser)\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visitDmprogram(parser.dmprogram())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                sqlVisitor.visitDmprogram(parser.dmprogram())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(command)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-dameng-parser/src/test/kotlin/io/github/melin/superior/parser/dameng/DmSqlParserDdlTest.kt",
    "content": "package io.github.melin.superior.parser.dameng\n\nimport com.github.melin.superior.sql.parser.mysql.DmSqlHelper\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.alter.AlterTable\nimport io.github.melin.superior.common.relational.common.CommentStatement\nimport io.github.melin.superior.common.relational.create.CreateMaterializedView\nimport io.github.melin.superior.common.relational.create.CreateTable\nimport io.github.melin.superior.common.relational.create.CreateView\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport org.junit.Assert\nimport org.junit.Test\n\nclass DmSqlParserDdlTest {\n    @Test\n    fun createTableTest0() {\n        val sql = \"\"\"\n            CREATE TABLE employees(\n                employee_id number(10) NOT NULL,\n                employee_name varchar2(50) NOT NULL,\n                city varchar2(50),\n                CONSTRAINT employees_pk PRIMARY KEY (employee_id)\n            )\n        \"\"\".trimIndent()\n\n        DmSqlHelper.splitSql(sql)\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId.tableName)\n//            Assert.assertEquals(3, statement.columnRels?.size)\n//            Assert.assertTrue(statement.columnRels?.get(0)?.primaryKey!!)\n//            Assert.assertFalse(statement.columnRels?.get(1)?.primaryKey!!)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createView0() {\n        val sql = \"\"\"\n            CREATE OR REPLACE VIEW comedies AS\n            SELECT f.*,\n                   country_code_to_name(f.country_code) AS country,\n                   (SELECT avg(r.rating)\n                    FROM user_ratings r\n                    WHERE r.film_id = f.id) AS avg_rating\n            FROM films f\n            WHERE f.kind = 'Comedy'\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is CreateView) {\n            Assert.assertEquals(StatementType.CREATE_VIEW, statement.statementType)\n            Assert.assertEquals(\"comedies\", statement.tableId.tableName)\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n\n    @Test\n    fun createMatView0() {\n        val sql = \"\"\"\n            CREATE MATERIALIZED VIEW sales_summary AS\n              SELECT\n                  seller_no,\n                  invoice_date,\n                  sum(invoice_amt) as sales_amt\n                FROM invoice\n                WHERE invoice_date < CURRENT_DATE\n                GROUP BY\n                  seller_no,\n                  invoice_date;\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is CreateMaterializedView) {\n            Assert.assertEquals(StatementType.CREATE_MATERIALIZED_VIEW, statement.statementType)\n            Assert.assertEquals(\"sales_summary\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun commentTest0() {\n        val sql = \"\"\"\n            COMMENT ON COLUMN employees.job_id IS 'abbreviated job title';\n            COMMENT ON COLUMN employees1.job_id IS 'abbreviated1 job title'\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseMultiStatement(sql)\n        val st1 = statement[0]\n        val st2 = statement[1]\n\n        if (st1 is CommentStatement) {\n            Assert.assertEquals(StatementType.COMMENT, st1.statementType)\n            Assert.assertEquals(\"employees.job_id\", st1.objValue)\n            Assert.assertEquals(\"abbreviated job title\", st1.comment)\n            Assert.assertFalse(st1.isNull)\n        }\n\n        if (st2 is CommentStatement) {\n            Assert.assertEquals(StatementType.COMMENT, st2.statementType)\n            Assert.assertEquals(\"employees1.job_id\", st2.objValue)\n            Assert.assertEquals(\"abbreviated1 job title\", st2.comment)\n            Assert.assertFalse(st2.isNull)\n        }\n    }\n\n    @Test\n    fun dropTableTest() {\n        val sql = \"\"\"\n            drop table employees purge;\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is DropTable) {\n            Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId.tableName)\n            Assert.assertTrue(statement.purge)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun alterTableTest() {\n        val sql = \"\"\"\n            ALTER TABLE \"t1\" RENAME COLUMN \"old_column\" TO \"new_column_temp\";\n            ALTER TABLE \"t2\" ADD \"new_column\" VARCHAR(8000);\n            ALTER TABLE \"t3\" DROP COLUMN \"new_column_temp\";\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseMultiStatement(sql)\n        val st1 = statement[0]\n        val st2 = statement[1]\n        val st3 = statement[2]\n\n        if (st1 is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, st1.statementType)\n            Assert.assertEquals(\"t1\", st1.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n\n        if (st2 is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, st2.statementType)\n            Assert.assertEquals(\"t2\", st2.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n\n        if (st3 is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, st3.statementType)\n            Assert.assertEquals(\"t3\", st3.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-dameng-parser/src/test/kotlin/io/github/melin/superior/parser/dameng/DmSqlParserDmlTest.kt",
    "content": "package io.github.melin.superior.parser.dameng\n\nimport com.github.melin.superior.sql.parser.mysql.DmSqlHelper\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.dml.DeleteTable\nimport io.github.melin.superior.common.relational.dml.InsertTable\nimport io.github.melin.superior.common.relational.dml.MergeTable\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport io.github.melin.superior.common.relational.dml.UpdateTable\nimport org.apache.commons.io.FileUtils\nimport org.junit.Assert\nimport org.junit.Test\nimport java.io.File\n\n/** Created by libinsong on 2018/1/10. */\nclass DmSqlParserDmlTest {\n    @Test\n    fun querySqlTest0() {\n        val sql1 = FileUtils.readFileToString(File(\"./src/test/resources/insert.sql\"), \"UTF-8\")\n        val statement = DmSqlHelper.parseStatement(sql1)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(27, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(TableId(\"dwd\", \"dwd_d03_contract_det_s\"), statement.outputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun querySqlTest1() {\n        val sql = \"\"\"\n            select 1 from db.t1;\n        \"\"\".trimIndent()\n\n        try {\n            val statement = DmSqlHelper.parseStatement(sql)\n            if (statement is QueryStmt) {\n                Assert.assertEquals(StatementType.SELECT, statement.statementType)\n                Assert.assertEquals(1, statement.inputTables.size)\n                Assert.assertEquals(TableId(null, \"db\", \"t1\"), statement.inputTables[0])\n            } else {\n                Assert.fail()\n            }\n        } catch (e: Exception) {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun cteSqlTest0() {\n        val sql = \"\"\"\n            WITH\n              cte1 AS (SELECT 'a' AS a, 'b' AS b),\n              cte2 AS (SELECT 'c' AS c, 'd' AS d)\n            SELECT b, d FROM cte1 JOIN cte2 ON cte1.a = cte2.c;\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(2, statement.inputTables.size)\n            Assert.assertEquals(TableId(\"cte1\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest() {\n        val sql = \"\"\"\n            DELETE FROM films\n            WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest0() {\n        val sql = \"\"\"\n            UPDATE employees SET sales_count = sales_count + 1 WHERE id =\n            (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest0() {\n        val sql = \"\"\"\n            INSERT ALL\n              INTO pivot_dest (id, day, val) VALUES (id, 'mon', mon_val)\n              INTO pivot_dest (id, day, val) VALUES (id, 'tue', tue_val)\n              INTO pivot_dest (id, day, val) VALUES (id, 'wed', wed_val)\n              INTO pivot_dest (id, day, val) VALUES (id, 'thu', thu_val)\n              INTO pivot_dest (id, day, val) VALUES (id, 'fri', fri_val)\n            SELECT *\n            FROM   pivot_source;\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"pivot_dest\", statement.outputTables.get(0).tableName)\n            Assert.assertEquals(1, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest1() {\n        val sql = \"\"\"\n            INSERT ALL\n              INTO dest_tab1 (id, description) VALUES (id, description)\n              INTO dest_tab2 (id, description) VALUES (id, description)\n              INTO dest_tab3 (id, description) VALUES (id, description)\n            SELECT id, description\n            FROM   source_tab;\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"dest_tab1\", statement.outputTables.get(0).tableName)\n            Assert.assertEquals(3, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest2() {\n        val sql = \"\"\"\n            INSERT ALL\n              WHEN id <= 3 THEN\n                INTO dest_tab1 (id, description) VALUES (id, description)\n              WHEN id BETWEEN 4 AND 7 THEN\n                INTO dest_tab2 (id, description) VALUES (id, description)\n              WHEN id >= 8 THEN\n                INTO dest_tab3 (id, description) VALUES (id, description)\n            SELECT id, description\n            FROM   source_tab;\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"dest_tab1\", statement.outputTables.get(0).tableName)\n            Assert.assertEquals(3, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest3() {\n        val sql = \"\"\"\n            INSERT FIRST\n              WHEN id <= 3 THEN\n                INTO dest_tab1 (id, description) VALUES (id, description)\n              WHEN id <= 5 THEN\n                INTO dest_tab2 (id, description) VALUES (id, description)\n              ELSE\n                INTO dest_tab3 (id, description) VALUES (id, description)\n            SELECT id, description\n            FROM   source_tab;\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"dest_tab1\", statement.outputTables.get(0).tableName)\n            Assert.assertEquals(3, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest4() {\n        val sql = \"\"\"\n            INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deltaMergeTest() {\n        val sql = \"\"\"\n            MERGE INTO bonuses D\n            USING (SELECT employee_id, salary, department_id FROM hr.employees\n            WHERE department_id = 80) S\n            ON (D.employee_id = S.employee_id)\n            WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01\n                DELETE WHERE (S.salary > 8000)\n            WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus)\n                VALUES (S.employee_id, S.salary*.01)\n                WHERE (S.salary <= 8000);\n        \"\"\".trimIndent()\n\n        val statement = DmSqlHelper.parseStatement(sql)\n\n        if (statement is MergeTable) {\n            Assert.assertEquals(StatementType.MERGE, statement.statementType)\n            Assert.assertEquals(\"bonuses\", statement.targetTable.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-dameng-parser/src/test/kotlin/io/github/melin/superior/parser/dameng/DmSqlProcedureParserTest.kt",
    "content": "package io.github.melin.superior.parser.dameng\n\nclass DmSqlProcedureParserTest {}\n"
  },
  {
    "path": "superior-dameng-parser/src/test/resources/insert.sql",
    "content": "insert into dwd.dwd_d03_contract_det_s\nselect to_date('${yyyy-mm-dd}', 'yyyy-mm-dd')                                    stt_date\n     ,to_date('${yyyy-mm-dd}', 'yyyy-mm-dd')                                    end_date\n     ,'01'        cont_source_cd                                                 -- 合同来源编码: 01-通用核心； 02-商用车\n     ,'通用核心'  cont_source_nm                                                 -- 合同来源：通用核心/商用车\n     ,cc.pk_contract                                                             -- 合同主键\n     ,cc.cont_code                                                               -- 合同编码\n     ,cc.cont_name                                                               -- 合同名称\n     ,cc.cont_type                                         cont_type_cd          -- 合同类型编码\n     ,pt2.param_name                                       cont_type_nm          -- 合同类型名称\n     ,cc.cont_status                                       cont_status_cd        -- 合同状态编码\n     ,pt1.param_name                                       cont_status_nm        -- 合同状态名称\n     ,pt3.param_value                                      economic_style_cd     -- 控股类型编码\n     ,replace(replace(pt3.param_name ,'绝对',''),'相对','') economic_style_nm     -- 控股类型\n     ,cc.cont_amount                                                             -- 合同金额\n     ,cc.lease_date_fact                                                         -- 起租日\n     ,cc.cont_end_date                                                           -- 到期日\n     ,lc.lease_times                                        lease_times          -- 租赁期（月数）\n     ,round(lc.lease_times/12,2)                            lease_year           -- 租赁期（年数）\n     ,case when cc.cont_amount >= 100000000 then '大型'\n           when cc.cont_amount >= 10000000 and cc.cont_amount < 100000000\n               then '中型'\n           else '小型'\n    end cont_scala                                                            -- 合同规模\n     ,case when cc.if_adjust = 0 then '是'\n           when cc.if_adjust = 1 then '否'\n           else null\n    end if_adjust                                                             -- 是否调息\n     ,sjtf.fact_cash_loan                                                        -- 已投放金额\n     ,sjtf.pay_date                                                              -- 首次投放日期\n     ,ba1.name                                             pay_province          -- 投放地区省\n     ,ba2.name                                             pay_city              -- 投放地区市\n     ,ba3.name                                             pay_area              -- 客户所属区\n     ,coalesce(nn.assets_classify, cc.assets_classify, 0)     assets_classify_cd    -- 五级分类代码\n     ,case coalesce(nn.assets_classify, cc.assets_classify, 0)\n          when 0 then '正常'\n          when 1 then '关注'\n          when 2 then '次级'\n          when 3 then '可疑'\n          when 4 then '损失'\n          else '正常'\n    end                                                 assets_classify_nm    -- 五级分类名称\n\n     ,pi.pk_project_info                                                         -- 项目编号\n\n     ,pi.project_name                                                            -- 项目名称\n\n     ,pi.lease_categry                                     lease_categry_cd      -- 租赁类型代码\n\n     ,case when pi.lease_categry = 0 then '融资租赁'\n\n           when pi.lease_categry = 1 then '经营性租赁'\n\n           else null\n\n    end                                                 lease_categry_nm      -- 租赁类型名称\n\n     ,case when pbl.if_group_company = 0 then '是'\n\n           else '否'\n\n    end                                                 if_group_company      -- 是否集团客户\n\n     ,pbl.vesting_group                                                          -- 集团客户名称\n\n     ,lc.lease_method                                      lease_method_cd       -- 业务类型代码\n\n     ,case when lc.lease_method = 0 then '直租'\n\n           when lc.lease_method = 1 then '回租'\n\n           when lc.lease_method = 4 then '转租赁'\n\n           else null\n\n    end                                                 lease_method_nm       -- 业务类型名称\n\n     ,main_thing.fixed_assets                                                    -- 固定资产门类\n\n     ,main_thing.fixed_assets_lag                                                -- 固定资产门类-大类\n\n     ,main_thing.fixed_assets_mid                                                -- 固定资产门类--中类\n\n     ,main_thing.fixed_assets_sml                                                -- 固定资产门类--小类\n\n     ,main_thing.thing_name                                                      -- 租赁物名称\n\n     -- 主办人相关信息\n\n     ,su.user_code               main_user_code                                  -- 主办项目经理编号\n\n     ,su.user_name               main_user_name                                  -- 主办项目经理\n\n     ,su.dept_code               main_dept_code                                  -- 主办业务部门编号\n\n     ,su.dept_name               main_dept_name                                  -- 主办业务部门名称\n\n\n\n     -- 协办人相关信息\n\n     ,su2.user_code              help_user_code                                  -- 协办项目经理编号\n\n     ,su2.user_name              help_user_name                                  -- 协办项目经理\n\n     ,su2.dept_code              help_dept_code                                  -- 协办业务部门编号\n\n     ,su2.dept_name              help_dept_name                                  -- 协办业务部门名称\n\n\n\n     ,coalesce(pa.sponsor_performance, pa.sponsor_performance_sh * 100) sponsor_performance    -- 主办分成比例（两位整数）\n\n     ,coalesce(pa.help_performance, pa.help_performance_one * 100)      help_performance       -- 协办分成比例（两位整数）\n\n     ,pn.investment                                        investment_cd         -- 城建类分类\n\n     ,case when coalesce(pn.investment, cu.investment) = 0\n\n               then '是'\n\n           else '否'\n\n    end investment_nm                                                         -- 是否城建类\n\n     ,vc.customer_name                                                           -- 承租人名称\n\n     ,case when vc.identity_type = 4 then vc.identity_no\n\n           else null\n\n    end                                                 identity_no           -- 统一社会信用代码\n\n     ,vc.risk_level                                        risk_level_cd         -- 客户洗钱风险评级代码\n\n     ,case when vc.risk_level = '1001' then '低风险'\n\n           when vc.risk_level = '1002' then '较低风险'\n\n           when vc.risk_level = '1003' then '中风险'\n\n           when vc.risk_level = '1004' then '较高风险'\n\n           when vc.risk_level = '1005' then '高风险'\n\n           when vc.risk_level = '1006' then '无结果'\n\n           when vc.risk_level = '1007' then '查询失败'\n\n           else null\n\n    end                                                 risk_level_nm         -- 客户洗钱风险评级名称\n\n     ,cu.organization_code                                 organization_code     -- 组织机构代码\n\n\n\n     ,hy.param_name                                        industry              -- 国标行业门类\n\n     ,hy1.param_name                                       industry_lag          -- 国标行业大类\n\n     ,hy2.param_name                                       industry_mid          -- 国标行业中类\n\n     ,hy3.param_name                                       industry_sml          -- 国标行业小类\n\n     ,coalesce(cc.business_module, dm1.business_mode_nm, '其他')                                  industry_mod          -- 业务板块——9大分类\n\n\n\n     ,case when cc.cont_status = 8 or\n\n                (cc.cont_status = 2 and '${yyyy-mm-dd}' <= cc.lease_date_fact) or\n\n                (cc.cont_status = 2 and '${yyyy-mm-dd}' >= cc.lease_date_fact and coalesce(sjtf.fact_cash_loan,0) < coalesce(ipc.lease_corpus,0) and planc.plan_count >= 2 )\n\n               then coalesce(sjtf.fact_cash_loan,0) - coalesce(gather.gather_corpus,0) - coalesce(sfk.inner_deduct_cash,0)\n\n           else coalesce(ipc.lease_corpus,0) - coalesce(gather.gather_corpus,0) - coalesce(sfk.inner_deduct_cash,0)\n\n    end                                                                                     corpus_balance   -- 剩余本金\n\n     ,coalesce(history.lease_interest,ipc.lease_interest) - coalesce(gather.gather_interest,0) interest_balance -- 剩余利息\n\n     ,case when yoc.pk_contract is not null then coalesce(lpb.deposit_balance,0)\n\n           else 0\n\n    end                                                                                     deposit_balance  -- 剩余保证金\n\n     -- 调整剩余保证金逻辑， 保持和源端取值一样 11.22(剩余风险抵押金 按照逻辑把字段衍生出来)\n\n     -- ,coalesce(lpb.deposit_balance,0)                                                          deposit_balance  -- 剩余保证金\n\n     ,case when yoc.pk_contract is null then coalesce(lpb.deposit_balance,0)\n\n           else 0\n\n    end                                                                                     mortgage_balance -- 剩余风险抵押金\n\n     ,COALESCE(adj.INTERRATE_FACT_AFTER,lc.FINAL_RATE, 0)                                      contract_rate    -- 合同利率\n\n     ,COALESCE(adj.PROJECT_IRR,lc.PROJECT_IRR, 0) * 100.0                                      PROJECT_IRR      -- IRR（现行）\n\n     ,COALESCE(adj.CONTRACT_XIRR,lc.CONTRACT_XIRR, 0)  * 100.0                                 CONTRACT_XIRR    -- XIRR（含税）\n\n     -- 增加字段\n\n     ,case when yoc.pk_contract is null then '是'\n\n           else '否'\n\n    end                                                                                     is_mortgage      -- 是否风险抵押金\n\n     ,case when cc.cont_status = 8 and coalesce(ipo.overdue_days_zqx, 0) >= 1\n\n               then '是'\n\n           when cc.cont_status <> 8 and coalesce(ipo.overdue_days, 0) >= 1\n\n               then '是'\n\n           else '否'\n\n    end                                                                                     if_overdue       -- 是否逾期\n\n     ,yq.OVERDUE_DATE                                                                          overdue_days     -- 最大逾期天数（含历史）\n\n     ,magum.param_name                                                                         pledge_name      -- 担保方式\n\n     ,case when lc.interrate_type = 0\n\n               then '浮动利率' else '固定利率'\n\n    end                                                                                      interrate_type   -- 利率类型\n\n     ,ipc.lease_cash1      handling_fee       -- 手续费/咨询费\n\n     ,ipc.lease_cash11     fixed_rent         -- 固定租金\n\n     ,ipc.lease_cash2      deposit_amt        -- 保证金金额\n\n     ,ipc.lease_cash22     margin_bal         -- 保证金余额\n\n     ,ipc.lease_cash3      margin_off_amt     -- 保证金冲抵金额\n\n     ,ipc.lease_cash33     refund_deposit     -- 退还保证金\n\n     ,nn.accrue_cash                          -- 拨备余额\n\n     ,vc.customer_code                        -- 承租人编号\n\nfrom dwd.dg1_yls_contract_c_c cc    -- 合同表\n\n\n\n-- 补全9大分类\n\n         left join dim.dim_d99_business_mode_cd dm1\n\n                   on cc.industry3 = dm1.pk_parameter\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between dm1.stt_date and dm1.end_date\n\n\n\n    -- 合同状态\n\n         left join dwd.dg1_yls_parameter_c pt1\n\n                   on cc.cont_status = pt1.param_value\n\n                       and pt1.pk_param_type = upper('0001AA1000000001RC3C')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt1.stt_date and pt1.end_date\n\n    -- 合同类型\n\n         left join dwd.dg1_yls_parameter_c pt2\n\n                   on cc.cont_type = pt2.param_value\n\n                       and pt2.pk_param_type = upper('0001AA1000000001VJBS')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt2.stt_date and pt2.end_date\n\n    -- 控股类型\n\n         left join dwd.dg1_yls_parameter_c pt3\n\n                   on cc.economic_style1 = pt3.pk_parameter\n\n                       and pt3.pk_param_type = upper('0001AA10000000041633')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt3.stt_date and pt3.end_date\n\n    -- 担保方式\n\n         left join dwd.dg1_yls_parameter_c magum\n\n                   on cc.major_guarantee_method = magum.pk_parameter\n\n                       and magum.pk_param_type = upper('0001AA1000000002K3MQ')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt3.stt_date and pt3.end_date\n\n    -- 逾期情况\n\n         left join (\n\n    select ipc.pk_contract\n\n         ,coalesce(max(case\n\n                           when ipc.trans_type = upper('0001AA100000000AUBPA') and\n\n                                ipc.charge_off_status = 2 and\n\n                                gab.check_date > '${yyyy-mm-dd}' then\n\n                               to_date(gab.check_date, 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')\n\n                           when ipc.trans_type = upper('0001AA100000000AUBPA') and\n\n                                ipc.charge_off_status <> 2 and\n\n                                ipc.plan_date <= '${yyyy-mm-dd}' then\n\n                               to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')\n\n        end),\n\n                   0) as overdue_days_zqx\n\n         ,coalesce(max(case\n\n                           when ipc.charge_off_status = 2 and\n\n                                gab.check_date > '${yyyy-mm-dd}' then\n\n                               to_date(gab.check_date, 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')\n\n                           when ipc.charge_off_status <> 2 and\n\n                                ipc.plan_date <= '${yyyy-mm-dd}' then\n\n                               to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')\n\n        end),\n\n                   0) as overdue_days /*租金逾期天数*/\n\n    from dwd.dg1_yls_inout_plan_c_c ipc\n\n             left join (select gab.pk_inout_plan\n\n                             ,coalesce(max(gap.trade_date), '${yyyy-mm-dd}') as check_date\n\n                        from dwd.dg1_yls_gather_account_b_c gab\n\n                                 inner join dwd.dg1_yls_gather_account_c ga\n\n                                            on ga.pk_gather_account = gab.pk_gather_account\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date\n\n                                 inner join dwd.dg1_yls_gather_audit_plan_c gap\n\n                                            on gap.pk_gather_account_b = gab.pk_gather_account_b\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gap.stt_date and gap.end_date\n\n                        where ga.billstatus = 9\n\n                          and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date\n\n                        group by gab.pk_inout_plan) gab\n\n                       on gab.pk_inout_plan = ipc.pk_inout_plan\n\n    where ipc.trans_type in (upper('0001AA10000000007NGV'),\n\n                             upper('0001AA100000000AUBPA'),\n\n                             upper('0001AA10000000007NH3')) /* 现金流类型 租金 收租（租前息） 首付款*/\n\n      and ipc.rent_type = 1 /* 租金表类型 会计表*/\n\n      and ipc.plan_date <= '${yyyy-mm-dd}'\n\n      and ipc.lease_cash >= 0.01\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    group by ipc.pk_contract\n\n) ipo\n\n                   on cc.pk_contract = ipo.pk_contract\n\n         left join (\n\n    select plan.PK_CONTRACT,max(rec.OVERDUE_DATE) OVERDUE_DATE\n\n    from dwd.dg1_yls_overdue_record_c rec\n\n             join dwd.dg1_yls_inout_plan_c_c plan on plan.PK_INOUT_PLAN = rec.PK_INOUT_PLAN\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between plan.stt_date and plan.end_date\n\n    where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between rec.stt_date and rec.end_date\n\n    group by plan.PK_CONTRACT\n\n) yq on yq.PK_CONTRACT = cc.PK_CONTRACT\n\n    -- 实际投放金额\n\n         left join (\n\n    select ipc.pk_contract  -- 主键\n\n         ,sum(coalesce(lp.real_pay_cash, 0.00))              fact_cash_loan      -- 已投放金额\n\n         ,min(coalesce(ld.real_pay_date, '${yyyy-mm-dd}'))      pay_date            -- 首次投放日\n\n    from dwd.dg1_yls_inout_plan_c_c ipc\n\n             left join dwd.dg1_yls_loan_plan_c lp\n\n                       on ipc.pk_inout_plan = lp.pk_inout_plan\n\n                           and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date\n\n             left join dwd.dg1_yls_loan_deal_c ld\n\n                       on lp.pk_loan_deal = ld.pk_loan_deal\n\n                           and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date\n\n    where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n      and ipc.trans_type in (upper('0001AA10000000005GRC'), upper('0001AA10000000007NGO'), upper('0001AA1000000005AB31'), upper('0001AA1000000005AB32'))\n\n      and ipc.rent_type = 1          -- 租金表类型-会计表\n\n      and lp.if_account = 0          -- 是否核销为是\n\n      and lp.if_approve_cancel = 1   -- 是否审核撤销为否时\n\n      and lp.if_cancel = 1           -- 是否核销撤销为否时\n\n      and ld.billstatus = 9\n\n      and ld.real_pay_date <= '${yyyy-mm-dd}'\n\n    group by ipc.pk_contract\n\n) sjtf\n\n                   on cc.pk_contract = sjtf.pk_contract\n\n\n\n    -- 首付款\n\n         left join (\n\n    select ipc.pk_contract\n\n         ,sum(coalesce(ipc.lease_cash, 0.00)) as inner_deduct_cash\n\n         ,min(coalesce(ld.real_pay_date, '${yyyy-mm-dd}')) as pay_date\n\n    from dwd.dg1_yls_inout_plan_c_c ipc\n\n             left join dwd.dg1_yls_loan_plan_c lp\n\n                       on lp.pk_inout_plan = ipc.pk_inout_plan\n\n                           and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date\n\n             left join dwd.dg1_yls_loan_deal_c ld\n\n                       on ld.pk_loan_deal = lp.pk_loan_deal\n\n                           and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date\n\n    where ipc.trans_type = '0001AA10000000007NH3' /* 现金流类型 设备款*/\n\n      and ipc.rent_type = 1 /* 租金表类型 会计表*/\n\n      and lp.if_inner_deduct = 2 /* 是否内扣为是 */\n\n      and lp.if_cancel = 1 /* 是否核销撤销为否时 */\n\n      and ld.billstatus = 9\n\n      and ld.real_pay_date <= '${yyyy-mm-dd}'\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    group by ipc.pk_contract\n\n) sfk\n\n                   on cc.pk_contract = sfk.pk_contract\n\n\n\n    -- 五级分类\n\n         left join (\n\n    select i1.pk_contract             -- 合同PK\n\n         ,i1.assets_classify         -- 五级分类\n\n         ,i1.accrue_cash\n\n    from dwd.dg1_assets_classify_history_c i1                -- yls_assets_classify_history\n\n             join (\n\n        select ic.pk_contract\n\n             ,max(ic.pk_assets_classify_history) pk_assets_classify_history\n\n        from dwd.dg1_assets_classify_history_c ic\n\n        where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ic.stt_date and ic.end_date\n\n          and (\n\n                  case when ic.if_new = 0 then ic.period\n\n                       else coalesce(substr(replace(ic.change_date, '-', ''), 1, 6), ic.period)\n\n                      end\n\n                  )  <= substr(replace('${yyyy-mm-dd}', '-', ''), 1, 6)\n\n        group by ic.pk_contract\n\n    ) i2\n\n                  on i1.pk_assets_classify_history = i2.pk_assets_classify_history\n\n    where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between i1.stt_date and i1.end_date\n\n) nn\n\n                   on cc.pk_contract = nn.pk_contract\n\n\n\n    -- 项目信息\n\n         left join dwd.dg1_yls_project_info_c pi\n\n                   on cc.pk_project = pi.pk_project_info\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pi.stt_date and pi.end_date\n\n    -- 集团客户\n\n         left join (\n\n    select distinct source_bill, if_group_company, vesting_group\n\n    from dwd.dg1_yls_project_both_lessee_c\n\n    where lessee_type = 0\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between stt_date and end_date\n\n) pbl\n\n                   on pi.pk_project_info = pbl.source_bill\n\n    -- 主办/协办信息\n\n         left join dwd.dg1_yls_project_approval_c pa\n\n                   on pi.pk_project_approval = pa.pk_project_approval\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pa.stt_date and pa.end_date\n\n    -- 城建类\n\n         left join (\n\n    select row_number() over(partition by pk_project_info order by ts) rcnt\n\n          ,i3.pk_project_info\n\n         ,i3.investment                  -- 城建类判断\n\n    from dwd.dg1_yls_prj_nodecollect_c i3\n\n    where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between i3.stt_date and i3.end_date\n\n) pn\n\n                   on pi.pk_project_info = pn.pk_project_info\n\n                       and pn.rcnt = 1\n\n\n\n    -- 用户信息相关\n\n         left join dwd.dg1_yls_customer_c vc\n\n                   on cc.pk_customer_lessee = vc.pk_customer\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between vc.stt_date and vc.end_date\n\n    -- 企业客户基本信息\n\n         left join dwd.dg1_yls_customer_corp_c cu\n\n                   on vc.pk_customer = cu.pk_customer\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between cu.stt_date and cu.end_date\n\n    -- 投放地区\n\n         left join dwd.dg1_bd_areacl_c ba1 on ba1.pk_areacl = cu.PROVINCE\n\n    and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba1.stt_date and ba1.end_date\n\n         left join dwd.dg1_bd_areacl_c ba2 on ba2.pk_areacl = cu.CITY\n\n    and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba2.stt_date and ba2.end_date\n\n         left join dwd.dg1_bd_areacl_c ba3 on ba3.pk_areacl = cu.DISTRICT\n\n    and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba3.stt_date and ba3.end_date\n\n    -- 行业分类\n\n         left join dwd.dg1_yls_parameter_c hy\n\n                   on cc.industry = hy.pk_parameter\n\n                       and hy.pk_param_type  = upper('0001AA1000000000OY5C')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy.stt_date and hy.end_date\n\n         left join dwd.dg1_yls_parameter_c hy1\n\n                   on cc.industry1 = hy1.pk_parameter\n\n                       and hy1.pk_param_type = upper('0001AA1000000000OY5C')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy1.stt_date and hy1.end_date\n\n         left join dwd.dg1_yls_parameter_c hy2\n\n                   on cc.industry2 = hy2.pk_parameter\n\n                       and hy2.pk_param_type = upper('0001AA1000000000OY5C')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy2.stt_date and hy2.end_date\n\n         left join dwd.dg1_yls_parameter_c hy3\n\n                   on cc.industry3 = hy3.pk_parameter\n\n                       and hy3.pk_param_type = upper('0001AA1000000000OY5C')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy3.stt_date and hy3.end_date\n\n\n\n    -- 剩余保证金计算\n\n         left join (\n\n    select ipc.pk_contract\n\n         ,sum(case\n\n                  when ipc.trans_type = '0001AA10000000007NHR' then\n\n                      (case when lp.pay_cash > ipc.lease_cash then coalesce(ipc.lease_cash, 0.00)\n\n                            else coalesce(lp.pay_cash, 0.00)\n\n                          end) + coalesce(gac.gather_cash, 0)\n\n                  when ipc.trans_type = '0001AA10000000007NHT' then\n\n                      -coalesce(gab.gather_cash, 0)\n\n                  when ipc.trans_type = '0001AA10000000007NI5' then\n\n                      coalesce(gac.gather_cash, 0)\n\n                  when ipc.trans_type = '0001AA10000000007NHX' then\n\n                      -coalesce(lp.pay_cash, 0)\n\n                  else 0\n\n        end) as deposit_balance\n\n    from dwd.dg1_yls_inout_plan_c_c ipc\n\n             left join (select ipc.pk_inout_plan\n\n                             ,coalesce(ga.charge_off_cash, 0) as gather_cash\n\n                        from dwd.dg1_yls_inout_plan_c_c ipc\n\n                                 inner join dwd.dg1_yls_gather_account_c ga\n\n                                            on ipc.pk_inout_plan = ga.pk_account_bill\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date\n\n                        where ga.billstatus = 9 /*单据状态 审核通过*/\n\n                          and ga.check_date <= '${yyyy-mm-dd}'\n\n                          and ipc.trans_type = '0001AA10000000007NHT'\n\n                          and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    ) gab\n\n                       on gab.pk_inout_plan = ipc.pk_inout_plan\n\n             left join (select ipc.pk_inout_plan\n\n                             ,coalesce(gab.gather_cash, 0) as gather_cash\n\n                        from dwd.dg1_yls_inout_plan_c_c ipc\n\n                                 inner join dwd.dg1_yls_gather_account_b_c gab\n\n                                            on ipc.pk_inout_plan = gab.pk_inout_plan\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date\n\n                                 inner join dwd.dg1_yls_gather_account_c ga\n\n                                            on ga.pk_gather_account = gab.pk_gather_account\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date\n\n                        where ga.billstatus = 9 /*单据状态 审核通过*/\n\n                          and ga.check_date <= '${yyyy-mm-dd}'\n\n                          and ipc.trans_type in\n\n                              ('0001AA10000000007NHR', '0001AA10000000007NI5')\n\n                          and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    ) gac\n\n                       on gac.pk_inout_plan = ipc.pk_inout_plan\n\n             left join (select lp.pk_inout_plan\n\n                             ,(case when coalesce(ld.real_pay_cash, 0.00) = 0\n\n                                        then coalesce(ld.inner_deduct_cash, 0.00)\n\n                                    else coalesce(ld.real_pay_cash, 0.00)\n\n            end) as pay_cash\n\n                        from dwd.dg1_yls_loan_plan_c lp\n\n                                 inner join dwd.dg1_yls_loan_deal_c ld\n\n                                            on ld.pk_loan_deal = lp.pk_loan_deal\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date\n\n                        where lp.if_approve_cancel = 1 /* 是否审核撤销为否时 */\n\n                          and lp.if_cancel = 1         /* 是否核销撤销为否时 */\n\n                          and ld.billstatus = 9\n\n                          and ld.real_pay_date <= '${yyyy-mm-dd}'\n\n                          and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date\n\n    ) lp\n\n                       on lp.pk_inout_plan = ipc.pk_inout_plan\n\n    where ipc.trans_type in ('0001AA10000000007NHR',\n\n                             '0001AA10000000007NHT',\n\n                             '0001AA10000000007NI5',\n\n                             '0001AA10000000007NHX') /* 现金流类型 收取保证金,保证金冲抵,补足保证金,退还保证金*/\n\n      and ipc.rent_type = 1 /* 租金表类型 会计表*/\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    group by ipc.pk_contract\n\n) lpb\n\n                   on cc.pk_contract = lpb.pk_contract\n\n\n\n         left join dwd.dg1_yls_old_contract_c yoc\n\n                   on cc.pk_contract = yoc.pk_contract\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between yoc.stt_date and yoc.end_date\n\n\n\n    -- 实收数据\n\n         left join (\n\n    select sum(case when et.event_code in ('10201', '10203', '10216') and gab.trade_date <= '${yyyy-mm-dd}'\n\n                        then coalesce(gab.gather_cash, 0)\n\n                    else 0\n\n        end) gather_cash\n\n         ,sum(case when et.event_code in ('10201', '10203') and gab.trade_date <= '${yyyy-mm-dd}'\n\n                       then coalesce(gab.gather_corpus, 0)\n\n                   else 0\n\n        end) gather_corpus\n\n         ,sum(case when et.event_code in ('10201', '10216') and gab.trade_date <= '${yyyy-mm-dd}'\n\n                       then coalesce(gab.gather_interest, 0)\n\n                   else 0\n\n        end) gather_interest\n\n         ,sum(case when et.event_code in ('10213') and gab.trade_date <= '${yyyy-mm-dd}'\n\n                       then coalesce(gab.gather_cash, 0)\n\n                   else 0\n\n        end) gather_penal_cash\n\n         ,sum(case when et.event_code in ('10201', '10203') and gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and\n\n                        gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')\n\n                       then coalesce(gab.gather_cash, 0)\n\n                   else 0\n\n        end) gather_cash1\n\n         ,sum(case when et.event_code in ('10201', '10203') and\n\n                        gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and\n\n                        gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')\n\n                       then coalesce(gab.gather_corpus, 0)\n\n                   else 0\n\n        end) gather_corpus1\n\n         ,sum(case when et.event_code in ('10201', '10203', '10216') and\n\n                        gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and\n\n                        gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')\n\n                       then coalesce(gab.gather_interest, 0)\n\n                   else 0\n\n        end) gather_interest1\n\n         ,sum(case when et.event_code in ('10213') and\n\n                        gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and\n\n                        gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')\n\n                       then coalesce(gab.gather_cash, 0)\n\n                   else 0\n\n        end) gather_penal_cash1\n\n         ,sum(case when gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and\n\n                        gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')\n\n                       then\n\n                       1\n\n                   else\n\n                       0\n\n        end) cur_year_time\n\n         ,sum(case when gab.trade_date >= '${yyyy-mm-dd}' and\n\n                        gab.trade_date <= to_char(add_months(date'${yyyy-mm-dd}', 12), 'yyyy-mm-dd') then\n\n                       1\n\n                   else\n\n                       0\n\n        end) future_time\n\n         ,ipc.pk_contract\n\n    from dwd.dg1_yls_gather_account_b_c gab\n\n             join dwd.dg1_yls_gather_account_c ga\n\n                  on ga.pk_gather_account = gab.pk_gather_account\n\n                      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date\n\n             join dwd.dg1_yls_inout_plan_c_c ipc\n\n                  on ipc.pk_inout_plan = gab.pk_inout_plan\n\n                      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n             join dwd.dg1_yls_event_type_c et\n\n                  on et.pk_event_type = ipc.trans_type\n\n                      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date\n\n    where ga.billstatus = 9\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date\n\n    group by ipc.pk_contract\n\n) gather\n\n                   on cc.pk_contract = gather.pk_contract\n\n\n\n         left join dwd.dg1_yls_lease_calculator_c_c lc\n\n                   on cc.pk_lease_calculator = lc.pk_lease_calculator\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lc.stt_date and lc.end_date\n\n    -- 实时数据\n\n         left join (\n\n    select sum(case when et.event_code in ('10201','10202','10203','10216') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash, /* 总租金 */\n\n           sum(case when et.event_code in ('10401'/*,'10402','10403'*/,'10606') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash1,/* 手续费/咨询费 */\n\n           sum(case when et.event_code in ('10405') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash11,/* 固定租金 */\n\n           sum(case when et.event_code in ('10301') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash2, /* 保证金收取 */\n\n           sum(case when et.event_code in ('10308') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash22, /* 补住保证金 */\n\n           sum(case when et.event_code in ('10302') then coalesce(ipc.fact_cash,0) else 0 end) lease_cash3, /* 保证金冲抵 */\n\n           sum(case when et.event_code in ('10304') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash33, /* 退还保证金 */\n\n           sum(case when et.event_code in ('10201','10203') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash4, /* 收取总租金 */\n\n           sum(case when et.event_code in ('10201','10202','10216') then coalesce(ipc.lease_interest,0) else 0 end) lease_interest, /* 收取总利息 */\n\n           sum(case when et.event_code in ('10101','10102') and ycc.cont_status = 8 then coalesce(ipc.fact_cash,0)\n\n                    when et.event_code in ('10201','10203') and ycc.cont_status != 8 then coalesce(ipc.lease_corpus,0) else 0 end) lease_corpus, /* 总本金 */\n\n           sum(case when et.event_code in ('10301','10308') then coalesce(ipc.fact_cash,0) else 0 end) fact_cash2, /* 实收:保证金收取、补足 */\n\n           sum(case when et.event_code in ('10302','10304') then coalesce(ipc.fact_cash,0) else 0 end) fact_cash3, /* 实际：保证金冲抵、退还保证金 */\n\n           ipc.source_bill\n\n    from dwd.dg1_yls_inout_plan_c_c ipc\n\n             join dwd.dg1_yls_event_type_c et on et.pk_event_type = ipc.trans_type\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date\n\n             join dwd.dg1_yls_contract_c_c ycc on ycc.pk_contract = ipc.pk_contract\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ycc.stt_date and ycc.end_date\n\n    where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    group by ipc.source_bill\n\n) ipc on lc.pk_lease_calculator = ipc.source_bill\n\n    -- 历史数据\n\n         left join (\n\n\n\n    select ch.CONT_CODE,rc.interrate,rc.new_final_rate ,rc.NEW_PROJECT_IRR,rc.NEW_CONTRACT_XIRR,h.lease_cash,h.lease_cash1,h.lease_cash2,\n\n           h.lease_cash3,lease_cash22,h.lease_cash33,h.LEASE_INTEREST,\n\n           h.fact_cash2,h.fact_cash3\n\n    from dwd.dg1_yls_contract_h_c ch\n\n             join dwd.dg1_yls_rent_calculator_c rc on rc.PK_CONTRACT = ch.PK_CONTRACT\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between rc.stt_date and rc.end_date\n\n             join (\n\n        select iph.SOURCE_BILL,\n\n               sum(case when et.EVENT_CODE in ('10201','10202','10203','10216') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash, /* 收租总租金 */\n\n               sum(case when et.EVENT_CODE in ('10401'/*,'10402','10403'*/,'10405','10606') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash1, /* 手续费/咨询费/固定租金 */\n\n               sum(case when et.EVENT_CODE in ('10201','10202','10216') then coalesce(iph.LEASE_INTEREST,0) else 0 end) LEASE_INTEREST, /* 收租总租息 */\n\n               sum(case when et.EVENT_CODE in ('10301') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash2, /* 保证金收取 */\n\n               sum(case when et.EVENT_CODE in ('10308') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash22, /* 保证金补住 */\n\n               sum(case when et.EVENT_CODE in ('10302') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash3, /* 保证金冲抵*/\n\n               sum(case when et.EVENT_CODE in ('10304') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash33, /* 保证金退还 */\n\n               sum(case when et.EVENT_CODE in ('10301','10308') then coalesce(iph.FACT_CASH,0) else 0 end) fact_cash2, /* 实收:保证金收取、补足 */\n\n               sum(case when et.EVENT_CODE in ('10302','10304') then coalesce(iph.FACT_CASH,0) else 0 end) fact_cash3 /* 实际：保证金冲抵、退还保证金 */\n\n        from dwd.dg1_yls_inout_plan_h_c iph\n\n                 join dwd.dg1_yls_event_type_c et on et.PK_EVENT_TYPE = iph.TRANS_TYPE\n\n            and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date\n\n        where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between iph.stt_date and iph.end_date\n\n        group by iph.SOURCE_BILL\n\n    ) h on h.SOURCE_BILL = rc.PK_RENT_CALCULATOR\n\n    where ch.SOURCE_BILL_VERSIONPK in (\n\n        select chh.PK_CONTRACT\n\n        from dwd.dg1_yls_contract_h_c chh\n\n                 join (\n\n            select max(CHECK_DATE)CHECK_DATE,ch.cont_code\n\n            from dwd.dg1_yls_contract_h_c ch\n\n            where upper(ch.SOURCE_BILLTYPE) = upper('lease/ContractChange')\n\n              and ch.SOURCE_BILL_VERSIONPK is null\n\n              and ch.CHECK_DATE > '${yyyy-mm-dd}'\n\n              and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ch.stt_date and ch.end_date\n\n            group by ch.CONT_CODE\n\n        )zj_change on zj_change.CHECK_DATE = chh.check_date and zj_change.cont_code = chh.cont_code\n\n            and upper(chh.SOURCE_BILLTYPE) = upper('lease/ContractChange')\n\n            and chh.SOURCE_BILL_VERSIONPK is null\n\n        where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between chh.stt_date and chh.end_date\n\n\n\n    )\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ch.stt_date and ch.end_date\n\n) history\n\n                   on history.cont_code = cc.cont_code\n\n    -- 计划投放数量\n\n         left join (\n\n    select i5.pk_contract\n\n         ,count(*) plan_count\n\n    from dwd.dg1_yls_inout_plan_c_c i5\n\n    where i5.trans_type in ('0001AA10000000005GRC','0001AA10000000007NGO','0001AA1000000005AB31', '0001AA1000000005AB32')\n\n      and i5.rent_type = 1\n\n    group by i5.pk_contract\n\n) planc\n\n                   on cc.pk_contract = planc.pk_contract\n\n\n\n    -- 租赁物信息\n\n         left join (\n\n    select ypfa1.param_name fixed_assets\n\n         ,ypfa2.param_name fixed_assets_lag\n\n         ,ypfa3.param_name fixed_assets_mid\n\n         ,ypfa4.param_name fixed_assets_sml\n\n         ,prtc.thing_name\n\n         ,prtc.source_bill\n\n    from dwd.dg1_yls_project_rent_thing_c_c prtc\n\n             left join dwd.dg1_yls_parameter_c ypfa1 on ypfa1.pk_parameter = prtc.fixed_assets        and  ypfa1.is_enable = upper('Y') and ypfa1.param_type = 293\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa1.stt_date and ypfa1.end_date\n\n             left join dwd.dg1_yls_parameter_c ypfa2 on ypfa2.pk_parameter = prtc.fixed_assets_large  and  ypfa2.is_enable = upper('Y') and ypfa2.param_type = 293\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa2.stt_date and ypfa2.end_date\n\n             left join dwd.dg1_yls_parameter_c ypfa3 on ypfa3.pk_parameter = prtc.fixed_assets_middle and  ypfa3.is_enable = upper('Y') and ypfa3.param_type = 293\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa3.stt_date and ypfa3.end_date\n\n             left join dwd.dg1_yls_parameter_c ypfa4 on ypfa4.pk_parameter = prtc.fixed_assets_small  and  ypfa4.is_enable = upper('Y') and ypfa4.param_type = 293\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa4.stt_date and ypfa4.end_date\n\n    where prtc.is_ref_main = 0\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between prtc.stt_date and prtc.end_date\n\n) main_thing\n\n                   on cc.pk_contract = main_thing.source_bill\n\n    -- 主办\n\n         left join dwd.dwd_d01_party_c su\n\n                   on cc.pk_prj_manager = su.cuserid\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between su.stt_date and su.end_date\n\n    -- 协办\n\n         left join dwd.dwd_d01_party_c su2\n\n                   on cc.pk_cust_help = su2.cuserid\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between su2.stt_date and su2.end_date\n\n         left join (\n\n    select adj3.cont_code,\n\n           max(case when (adj3.response_day <= '${yyyy-mm-dd}' and  '${yyyy-mm-dd}' < adj3.response_day_end) or '${yyyy-mm-dd}' <= adj3.response_day then adj3.interrate_after end) as interrate_after,\n\n           max(case when (adj3.response_day <= '${yyyy-mm-dd}' and  '${yyyy-mm-dd}' < adj3.response_day_end) or '${yyyy-mm-dd}' <= adj3.response_day then adj3.interrate_fact_after end) as interrate_fact_after,\n\n           max(case when (adj3.response_day <= '${yyyy-mm-dd}' and  '${yyyy-mm-dd}' < adj3.response_day_end) or '${yyyy-mm-dd}' <= adj3.response_day then adj3.project_irr end) as project_irr,\n\n           max(case when (adj3.response_day <= '${yyyy-mm-dd}' and  '${yyyy-mm-dd}' < adj3.response_day_end) or '${yyyy-mm-dd}' <= adj3.response_day then adj3.contract_xirr end) as contract_xirr\n\n    from(\n\n            select adj.cont_code,\n\n                   adj.response_day,\n\n                   coalesce(min(case when adj.response_day < adj2.response_day then adj2.response_day end),'${yyyy-mm-dd}') response_day_end,\n\n                   min(adj.interrate_after) interrate_after, -- /*调息后基准利率*/\n\n                   min(adj.interrate_fact_after) interrate_fact_after, -- /*调息后实际利率*/\n\n                   min(adj.project_irr) project_irr, -- /*调息后合同irr*/\n\n                   min(adj.contract_xirr) contract_xirr -- /*合同收益xirr*/\n\n            from (select ch.cont_code,\n\n                         ch.check_date as response_day,\n\n                         rc.interrate as interrate_after,\n\n                         rc.new_final_rate as interrate_fact_after,\n\n                         rc.new_project_irr as project_irr,\n\n                         rc.new_contract_xirr as contract_xirr\n\n                  from dwd.dg1_yls_contract_h_c ch\n\n                           join dwd.dg1_yls_rent_calculator_c rc on rc.pk_contract = ch.pk_contract\n\n                  where upper(ch.source_billtype) = upper('lease/contractchange')\n\n                    and ch.source_bill_versionpk is null\n\n                    and ch.billstatus = 9\n\n                    and date'${yyyy-mm-dd}' between ch.stt_date and ch.end_date\n\n                    and date'${yyyy-mm-dd}' between rc.stt_date and rc.end_date\n\n                  union all  -- /*实际调息*/\n\n                  select distinct cc.cont_code,aa.response_day,\n\n                                  aa.interrate_after, -- /*调息后基准利率*/\n\n                                  aa.interrate_fact_after, -- /*调息后实际利率*/\n\n                                  aa.project_irr, -- /*调息后合同irr*/\n\n                                  aa.contract_xirr -- /*合同收益xirr*/\n\n                  from dwd.dg1_yls_adjust_apply_c aa\n\n                           left join dwd.dg1_yls_contract_c_c cc on cc.pk_contract = aa.pk_contract\n\n                      and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date\n\n                  where aa.billstatus = 9\n\n                    and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date\n\n                  union all    -- /*首次调息时，调息前信息*/\n\n                  select distinct cc.cont_code,to_char(to_date(aa.response_day, 'yyyy-mm-dd') - 1, 'yyyy-mm-dd') as response_day,\n\n                                  aa.interrate_before as interrate_after, -- /*调息前基准利率*/\n\n                                  aa.interrate_fact_before as interrate_fact_after, -- /*调息前实际利率*/\n\n                                  aa.cont_irr_befor as project_irr, -- /*调息前合同irr*/\n\n                                  aa.contract_xirr_before as contract_xirr -- /*调息前合同收益xirr*/\n\n                  from dwd.dg1_yls_adjust_apply_c aa\n\n                           join (select min(a.response_day) as response_day,a.pk_contract\n\n                                 from dwd.dg1_yls_adjust_apply_c a\n\n                                 where a.billstatus = 9\n\n                                   and date'${yyyy-mm-dd}' between a.stt_date and a.end_date\n\n                                 group by a.pk_contract) minday\n\n                                on minday.pk_contract = aa.pk_contract and minday.response_day = aa.response_day\n\n                                    and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date\n\n                           left join dwd.dg1_yls_contract_c_c cc\n\n                                     on cc.pk_contract = aa.pk_contract\n\n                                         and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date) adj\n\n                     left join (\n\n                select ch.cont_code,\n\n                       ch.check_date as response_day,\n\n                       rc.interrate as interrate_after,\n\n                       rc.new_final_rate as interrate_fact_after,\n\n                       rc.new_project_irr as project_irr,\n\n                       rc.new_contract_xirr as contract_xirr\n\n                from dwd.dg1_yls_contract_h_c ch\n\n                         join dwd.dg1_yls_rent_calculator_c rc on rc.pk_contract = ch.pk_contract\n\n                where upper(ch.source_billtype) = upper('lease/contractchange')\n\n                  and ch.source_bill_versionpk is null\n\n                  and ch.billstatus = 9\n\n                  and date'${yyyy-mm-dd}' between ch.stt_date and ch.end_date\n\n                  and date'${yyyy-mm-dd}' between rc.stt_date and rc.end_date\n\n                union all\n\n                select distinct cc.cont_code,aa.response_day,\n\n                                aa.interrate_after, -- /*调息后基准利率*/\n\n                                aa.interrate_fact_after, -- /*调息后实际利率*/\n\n                                aa.project_irr, -- /*调息后合同irr*/\n\n                                aa.contract_xirr -- /*合同收益xirr*/\n\n                from dwd.dg1_yls_adjust_apply_c aa\n\n                         left join dwd.dg1_yls_contract_c_c cc on cc.pk_contract = aa.pk_contract\n\n                where aa.billstatus = 9\n\n                  and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date\n\n                  and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date\n\n                union all\n\n                select distinct cc.cont_code,to_char(to_date(aa.response_day, 'yyyy-mm-dd') - 1, 'yyyy-mm-dd') as response_day,\n\n                                aa.interrate_before as interrate_after, -- /*调息前基准利率*/\n\n                                aa.interrate_fact_before as interrate_fact_after, -- /*调息前实际利率*/\n\n                                aa.cont_irr_befor as project_irr, -- /*调息前合同irr*/\n\n                                aa.contract_xirr_before as contract_xirr -- /*调息前合同收益xirr*/\n\n                from dwd.dg1_yls_adjust_apply_c aa\n\n                         join (select min(a.response_day) as response_day,a.pk_contract\n\n                               from dwd.dg1_yls_adjust_apply_c a\n\n                               where a.billstatus = 9\n\n                                 and date'${yyyy-mm-dd}' between a.stt_date and a.end_date\n\n                               group by a.pk_contract) minday\n\n                              on minday.pk_contract = aa.pk_contract and minday.response_day = aa.response_day\n\n                         left join dwd.dg1_yls_contract_c_c cc\n\n                                   on cc.pk_contract = aa.pk_contract\n\n                                       and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date\n\n                where date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date\n\n            ) adj2  on adj2.cont_code = adj.cont_code\n\n            group by adj.cont_code,adj.response_day\n\n        ) adj3\n\n    group by adj3.cont_code\n\n) adj on adj.cont_code = cc.cont_code\n\nwhere to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between cc.stt_date and cc.end_date\n\n  -- PK_PARAM_TYPE = '0001AA1000000001RC3C' 合同状态\n\n  and cc.cont_status > '1'\n\n  and cc.cont_status not in ('5' ,'7')\n"
  },
  {
    "path": "superior-dameng-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-flink-parser/README.md",
    "content": "### 介绍\n\n### 整库同步\n\n```sql\n-- 分布表，合并写入目标库中\nCREATE DATABASE IF NOT EXISTS flink_cdc_demos \nWITH (\n    'connector' = 'jdbc',\n    'url' = 'jdbc:mysql://172.18.1.55:3306/flink_cdc_demos?characterEncoding=utf-8&useSSL=false',\n    'username' = 'root',\n    'password' = 'Datac@123',\n    'table-name' = '${'$'}{tableName}',\n    'sink.buffer-flush.interval' = '2s',\n    'sink.buffer-flush.max-rows' = '100',\n    'sink.max-retries' = '5'\n) \nAS DATABASE `cdc_demos_[0-9]+` INCLUDING ALL TABLES  \nOPTIONS(\n    'connector' = 'mysql-cdc',\n    'hostname' = '172.18.5.44',\n    'port' = '3306',\n    'username' = 'root',\n    'password' = 'root2023',\n    'checkpoint' = '10000',\n    'scan.startup.mode' = 'initial',\n    'parallelism' = '1'\n)\n```\n\n### 分库分表同步\n\n```sql\nCREATE TABLE IF NOT EXISTS flink_cdc_demos.account\nWITH (\n    'connector' = 'jdbc',\n    'url' = 'jdbc:mysql://172.18.1.55:3306/flink_cdc_demos?characterEncoding=utf-8&useSSL=false',\n    'username' = 'root',\n    'password' = 'Datac@123',\n    'table-name' = 'account',\n    'sink.buffer-flush.interval' = '2s',\n    'sink.buffer-flush.max-rows' = '100',\n    'sink.max-retries' = '5'\n) \nAS TABLE `cdc_demos_[0-9]*`.`account_[0-9]*`\nOPTIONS(\n    'connector' = 'mysql-cdc',\n    'hostname' = '172.18.5.44',\n    'port' = '3306',\n    'username' = 'root',\n    'password' = 'root2023',\n    'checkpoint' = '10000',\n    'scan.startup.mode' = 'initial',\n    'parallelism' = '2'\n)\n```\n\n### 参考\n1. [Dinky在Doris实时整库同步和模式演变的探索实践](https://mp.weixin.qq.com/s/OVsbRbfLEIgSNurlP6woAg)\n2. [Dinky 数据集成](http://www.dlink.top/docs/next/data_integration_guide/cdcsource_statements)\n3. [CREATE DATABASE AS（CDAS）语句](https://help.aliyun.com/document_detail/374304.html)\n4. [数据库类型转换](https://www.sqlines.com/oracle-to-mysql)"
  },
  {
    "path": "superior-flink-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-flink-parser</artifactId>\n    <name>superior-flink-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "superior-flink-parser/src/main/antlr4/io/github/melin/superior/parser/flink/antlr4/FlinkSqlLexer.g4",
    "content": "lexer grammar FlinkSqlLexer;\n\n// SKIP\n\nWHITE_SPACE       : (' ' | '\\t' | '\\r' | '\\n')                                     -> channel(HIDDEN);\nBRACKETED_COMMENT : '/*' .*? '*/'                                                  -> channel(HIDDEN);\nLINE_COMMENT: (('--' | '#') ~[\\r\\n]* ('\\r'? '\\n' | EOF) | '--' ('\\r'? '\\n' | EOF)) -> channel(HIDDEN);\n\n/**\n * Keywords and Reserved Keywords\n * Flink uses Calcite as its SQL parser,\n * The following keywords are derived from the Calcite documentation and Flink's own source code.\n * First, perform a union between the keyword sets declared in the Flink source code and those in the Calcite documentation,\n * then calculate the difference between the resulting set and the non-keyword set declared in the Flink source code.\n *\n * Calcite Documentation: https://calcite.apache.org/docs/reference.html#keywords\n * Flink Parser.tdd file: https://github.com/apache/flink/blob/release-1.16/flink-table/flink-sql-parser/src/main/codegen/data/Parser.tdd\n *\n * Please keep the keyword in alphabetical order if new keyword is added.\n * When adding new keywords, please consider whether they should be added to the NonReserved Keywords section below.\n */\nKW_ABS                              : 'ABS';\nKW_ALL                              : 'ALL';\nKW_ALLOCATE                         : 'ALLOCATE';\nKW_ALLOW                            : 'ALLOW';\nKW_ALTER                            : 'ALTER';\nKW_ANALYZE                          : 'ANALYZE';\nKW_AND                              : 'AND';\nKW_ANY                              : 'ANY';\nKW_ARE                              : 'ARE';\nKW_ARRAY                            : 'ARRAY';\nKW_ARRAY_AGG                        : 'ARRAY_AGG';\nKW_ARRAY_CONCAT_AGG                 : 'ARRAY_CONCAT_AGG';\nKW_ARRAY_MAX_CARDINALITY            : 'ARRAY_MAX_CARDINALITY';\nKW_AS                               : 'AS';\nKW_ASENSITIVE                       : 'ASENSITIVE';\nKW_ASYMMETRIC                       : 'ASYMMETRIC';\nKW_AT                               : 'AT';\nKW_ATOMIC                           : 'ATOMIC';\nKW_AUTHORIZATION                    : 'AUTHORIZATION';\nKW_AVG                              : 'AVG';\nKW_BEGIN                            : 'BEGIN';\nKW_BEGIN_FRAME                      : 'BEGIN_FRAME';\nKW_BEGIN_PARTITION                  : 'BEGIN_PARTITION';\nKW_BETWEEN                          : 'BETWEEN';\nKW_BIGINT                           : 'BIGINT';\nKW_BINARY                           : 'BINARY';\nKW_BIT                              : 'BIT';\nKW_BLOB                             : 'BLOB';\nKW_BOOLEAN                          : 'BOOLEAN';\nKW_BOTH                             : 'BOTH';\nKW_BY                               : 'BY';\nKW_BYTES                            : 'BYTES';\nKW_CALL                             : 'CALL';\nKW_CALLED                           : 'CALLED';\nKW_CARDINALITY                      : 'CARDINALITY';\nKW_CASCADED                         : 'CASCADED';\nKW_CASE                             : 'CASE';\nKW_CAST                             : 'CAST';\nKW_CATALOGS                         : 'CATALOGS';\nKW_CEIL                             : 'CEIL';\nKW_CEILING                          : 'CEILING';\nKW_CHANGELOG_MODE                   : 'CHANGELOG_MODE';\nKW_CHAR                             : 'CHAR';\nKW_CHARACTER                        : 'CHARACTER';\nKW_CHARACTER_LENGTH                 : 'CHARACTER_LENGTH';\nKW_CHAR_LENGTH                      : 'CHAR_LENGTH';\nKW_CHECK                            : 'CHECK';\nKW_CLASSIFIER                       : 'CLASSIFIER';\nKW_CLOB                             : 'CLOB';\nKW_CLOSE                            : 'CLOSE';\nKW_COALESCE                         : 'COALESCE';\nKW_COLLATE                          : 'COLLATE';\nKW_COLLECT                          : 'COLLECT';\nKW_COLUMN                           : 'COLUMN';\nKW_COLUMNS                          : 'COLUMNS';\nKW_COMMENT                          : 'COMMENT';\nKW_COMMIT                           : 'COMMIT';\nKW_COMPUTE                          : 'COMPUTE';\nKW_CONDITION                        : 'CONDITION';\nKW_CONNECT                          : 'CONNECT';\nKW_CONSTRAINT                       : 'CONSTRAINT';\nKW_CONTAINS                         : 'CONTAINS';\nKW_CONVERT                          : 'CONVERT';\nKW_CORR                             : 'CORR';\nKW_CORRESPONDING                    : 'CORRESPONDING';\nKW_COUNT                            : 'COUNT';\nKW_COVAR_POP                        : 'COVAR_POP';\nKW_COVAR_SAMP                       : 'COVAR_SAMP';\nKW_CREATE                           : 'CREATE';\nKW_CROSS                            : 'CROSS';\nKW_CUBE                             : 'CUBE';\nKW_CUME_DIST                        : 'CUME_DIST';\nKW_CURRENT                          : 'CURRENT';\nKW_CURRENT_CATALOG                  : 'CURRENT_CATALOG';\nKW_CURRENT_DATE                     : 'CURRENT_DATE';\nKW_CURRENT_DEFAULT_TRANSFORM_GROUP  : 'CURRENT_DEFAULT_TRANSFORM_GROUP';\nKW_CURRENT_PATH                     : 'CURRENT_PATH';\nKW_CURRENT_ROLE                     : 'CURRENT_ROLE';\nKW_CURRENT_ROW                      : 'CURRENT_ROW';\nKW_CURRENT_SCHEMA                   : 'CURRENT_SCHEMA';\nKW_CURRENT_TIME                     : 'CURRENT_TIME';\nKW_CURRENT_TIMESTAMP                : 'CURRENT_TIMESTAMP';\nKW_CURRENT_TRANSFORM_GROUP_FOR_TYPE : 'CURRENT_TRANSFORM_GROUP_FOR_TYPE';\nKW_CURRENT_USER                     : 'CURRENT_USER';\nKW_CURSOR                           : 'CURSOR';\nKW_CYCLE                            : 'CYCLE';\nKW_DATABASES                        : 'DATABASES';\nKW_DATE                             : 'DATE';\nKW_DATETIME                         : 'DATETIME';\nKW_DATETIME_DIFF                    : 'DATETIME_DIFF';\nKW_DATETIME_TRUNC                   : 'DATETIME_TRUNC';\nKW_DATE_DIFF                        : 'DATE_DIFF';\nKW_DATE_TRUNC                       : 'DATE_TRUNC';\nKW_DAY                              : 'DAY';\nKW_DAYOFWEEK                        : 'DAYOFWEEK';\nKW_DAYOFYEAR                        : 'DAYOFYEAR';\nKW_DEALLOCATE                       : 'DEALLOCATE';\nKW_DEC                              : 'DEC';\nKW_DECIMAL                          : 'DECIMAL';\nKW_DECLARE                          : 'DECLARE';\nKW_DEFAULT                          : 'DEFAULT';\nKW_DEFINE                           : 'DEFINE';\nKW_DELETE                           : 'DELETE';\nKW_DENSE_RANK                       : 'DENSE_RANK';\nKW_DEREF                            : 'DEREF';\nKW_DESCRIBE                         : 'DESCRIBE';\nKW_DETERMINISTIC                    : 'DETERMINISTIC';\nKW_DISALLOW                         : 'DISALLOW';\nKW_DISCONNECT                       : 'DISCONNECT';\nKW_DISTINCT                         : 'DISTINCT';\nKW_DOT                              : 'DOT';\nKW_DOUBLE                           : 'DOUBLE';\nKW_DROP                             : 'DROP';\nKW_DYNAMIC                          : 'DYNAMIC';\nKW_EACH                             : 'EACH';\nKW_ELEMENT                          : 'ELEMENT';\nKW_ELSE                             : 'ELSE';\nKW_EMPTY                            : 'EMPTY';\nKW_END                              : 'END';\n// KW_END_EXEC: 'END-EXEC';\nKW_END_FRAME           : 'END_FRAME';\nKW_END_PARTITION       : 'END_PARTITION';\nKW_ENFORCED            : 'ENFORCED';\nKW_EQUALS              : 'EQUALS';\nKW_ESCAPE              : 'ESCAPE';\nKW_ESTIMATED_COST      : 'ESTIMATED_COST';\nKW_EVERY               : 'EVERY';\nKW_EXCEPT              : 'EXCEPT';\nKW_EXEC                : 'EXEC';\nKW_EXECUTE             : 'EXECUTE';\nKW_EXISTS              : 'EXISTS';\nKW_EXP                 : 'EXP';\nKW_EXPLAIN             : 'EXPLAIN';\nKW_EXTEND              : 'EXTEND';\nKW_EXTENDED            : 'EXTENDED';\nKW_EXTERNAL            : 'EXTERNAL';\nKW_EXTRACT             : 'EXTRACT';\nKW_FALSE               : 'FALSE';\nKW_FETCH               : 'FETCH';\nKW_FILTER              : 'FILTER';\nKW_FIRST_VALUE         : 'FIRST_VALUE';\nKW_FLOAT               : 'FLOAT';\nKW_FLOOR               : 'FLOOR';\nKW_FOR                 : 'FOR';\nKW_FOREIGN             : 'FOREIGN';\nKW_FRAME_ROW           : 'FRAME_ROW';\nKW_FREE                : 'FREE';\nKW_FRIDAY              : 'FRIDAY';\nKW_FROM                : 'FROM';\nKW_FULL                : 'FULL';\nKW_FUNCTION            : 'FUNCTION';\nKW_FUNCTIONS           : 'FUNCTIONS';\nKW_FUSION              : 'FUSION';\nKW_GET                 : 'GET';\nKW_GLOBAL              : 'GLOBAL';\nKW_GRANT               : 'GRANT';\nKW_GROUP               : 'GROUP';\nKW_GROUPING            : 'GROUPING';\nKW_GROUPS              : 'GROUPS';\nKW_GROUP_CONCAT        : 'GROUP_CONCAT';\nKW_HAVING              : 'HAVING';\nKW_HOLD                : 'HOLD';\nKW_HOUR                : 'HOUR';\nKW_IDENTITY            : 'IDENTITY';\nKW_IF                  : 'IF';\nKW_ILIKE               : 'ILIKE';\nKW_IMPORT              : 'IMPORT';\nKW_IN                  : 'IN';\nKW_INCLUDE             : 'INCLUDE';\nKW_INDICATOR           : 'INDICATOR';\nKW_INITIAL             : 'INITIAL';\nKW_INNER               : 'INNER';\nKW_INOUT               : 'INOUT';\nKW_INSENSITIVE         : 'INSENSITIVE';\nKW_INSERT              : 'INSERT';\nKW_INT                 : 'INT';\nKW_INTEGER             : 'INTEGER';\nKW_INTERSECT           : 'INTERSECT';\nKW_INTERSECTION        : 'INTERSECTION';\nKW_INTERVAL            : 'INTERVAL';\nKW_INTO                : 'INTO';\nKW_IS                  : 'IS';\nKW_JOIN                : 'JOIN';\nKW_JSON                : 'JSON';\nKW_JSON_ARRAY          : 'JSON_ARRAY';\nKW_JSON_ARRAYAGG       : 'JSON_ARRAYAGG';\nKW_JSON_EXECUTION_PLAN : 'JSON_EXECUTION_PLAN';\nKW_JSON_EXISTS         : 'JSON_EXISTS';\nKW_JSON_OBJECT         : 'JSON_OBJECT';\nKW_JSON_OBJECTAGG      : 'JSON_OBJECTAGG';\nKW_JSON_QUERY          : 'JSON_QUERY';\nKW_JSON_VALUE          : 'JSON_VALUE';\nKW_LAG                 : 'LAG';\nKW_LANGUAGE            : 'LANGUAGE';\nKW_LARGE               : 'LARGE';\nKW_LAST_VALUE          : 'LAST_VALUE';\nKW_LATERAL             : 'LATERAL';\nKW_LEAD                : 'LEAD';\nKW_LEADING             : 'LEADING';\nKW_LEFT                : 'LEFT';\nKW_LIKE                : 'LIKE';\nKW_LIKE_REGEX          : 'LIKE_REGEX';\nKW_LIMIT               : 'LIMIT';\nKW_LN                  : 'LN';\nKW_LOCAL               : 'LOCAL';\nKW_LOCALTIME           : 'LOCALTIME';\nKW_LOCALTIMESTAMP      : 'LOCALTIMESTAMP';\nKW_LOWER               : 'LOWER';\nKW_MATCH               : 'MATCH';\nKW_MATCHES             : 'MATCHES';\nKW_MATCH_NUMBER        : 'MATCH_NUMBER';\nKW_MATCH_RECOGNIZE     : 'MATCH_RECOGNIZE';\nKW_MAX                 : 'MAX';\nKW_MEASURES            : 'MEASURES';\nKW_MEMBER              : 'MEMBER';\nKW_MERGE               : 'MERGE';\nKW_METADATA            : 'METADATA';\nKW_METHOD              : 'METHOD';\nKW_MIN                 : 'MIN';\nKW_MINUS               : 'MINUS';\nKW_MINUTE              : 'MINUTE';\nKW_MOD                 : 'MOD';\nKW_MODIFIES            : 'MODIFIES';\nKW_MODIFY              : 'MODIFY';\nKW_MODULE              : 'MODULE';\nKW_MODULES             : 'MODULES';\nKW_MONDAY              : 'MONDAY';\nKW_MONTH               : 'MONTH';\nKW_MORE                : 'MORE';\nKW_MULTISET            : 'MULTISET';\nKW_NATIONAL            : 'NATIONAL';\nKW_NATURAL             : 'NATURAL';\nKW_NCHAR               : 'NCHAR';\nKW_NCLOB               : 'NCLOB';\nKW_NEW                 : 'NEW';\nKW_NEXT                : 'NEXT';\nKW_NO                  : 'NO';\nKW_NONE                : 'NONE';\nKW_NORMALIZE           : 'NORMALIZE';\nKW_NOT                 : 'NOT';\nKW_NTH_VALUE           : 'NTH_VALUE';\nKW_NTILE               : 'NTILE';\nKW_NULL                : 'NULL';\nKW_NULLIF              : 'NULLIF';\nKW_NUMERIC             : 'NUMERIC';\nKW_OCCURRENCES_REGEX   : 'OCCURRENCES_REGEX';\nKW_OCTET_LENGTH        : 'OCTET_LENGTH';\nKW_OF                  : 'OF';\nKW_OFFSET              : 'OFFSET';\nKW_OLD                 : 'OLD';\nKW_OMIT                : 'OMIT';\nKW_ON                  : 'ON';\nKW_ONE                 : 'ONE';\nKW_ONLY                : 'ONLY';\nKW_OPEN                : 'OPEN';\nKW_OR                  : 'OR';\nKW_ORDER               : 'ORDER';\nKW_ORDINAL             : 'ORDINAL';\nKW_OUT                 : 'OUT';\nKW_OUTER               : 'OUTER';\nKW_OVER                : 'OVER';\nKW_OVERLAPS            : 'OVERLAPS';\nKW_OVERLAY             : 'OVERLAY';\nKW_OVERWRITE           : 'OVERWRITE';\nKW_OVERWRITING         : 'OVERWRITING';\nKW_PARAMETER           : 'PARAMETER';\nKW_PARTITION           : 'PARTITION';\nKW_PARTITIONED         : 'PARTITIONED';\nKW_PARTITIONS          : 'PARTITIONS';\nKW_PATTERN             : 'PATTERN';\nKW_PER                 : 'PER';\nKW_PERCENT             : 'PERCENT';\nKW_PERCENTILE_CONT     : 'PERCENTILE_CONT';\nKW_PERCENTILE_DISC     : 'PERCENTILE_DISC';\nKW_PERCENT_RANK        : 'PERCENT_RANK';\nKW_PERIOD              : 'PERIOD';\nKW_PERMUTE             : 'PERMUTE';\nKW_PLAN_ADVICE         : 'PLAN_ADVICE';\nKW_PIVOT               : 'PIVOT';\nKW_PORTION             : 'PORTION';\nKW_POSITION            : 'POSITION';\nKW_POSITION_REGEX      : 'POSITION_REGEX';\nKW_POWER               : 'POWER';\nKW_PRECEDES            : 'PRECEDES';\nKW_PRECISION           : 'PRECISION';\nKW_PREPARE             : 'PREPARE';\nKW_PREV                : 'PREV';\nKW_PRIMARY             : 'PRIMARY';\nKW_PROCEDURE           : 'PROCEDURE';\nKW_QUALIFY             : 'QUALIFY';\nKW_QUARTERS            : 'QUARTERS';\nKW_RANGE               : 'RANGE';\nKW_RANK                : 'RANK';\nKW_RAW                 : 'RAW';\nKW_READS               : 'READS';\nKW_REAL                : 'REAL';\nKW_RECURSIVE           : 'RECURSIVE';\nKW_REF                 : 'REF';\nKW_REFERENCES          : 'REFERENCES';\nKW_REFERENCING         : 'REFERENCING';\nKW_REGR_AVGX           : 'REGR_AVGX';\nKW_REGR_AVGY           : 'REGR_AVGY';\nKW_REGR_COUNT          : 'REGR_COUNT';\nKW_REGR_INTERCEPT      : 'REGR_INTERCEPT';\nKW_REGR_R2             : 'REGR_R2';\nKW_REGR_SLOPE          : 'REGR_SLOPE';\nKW_REGR_SXX            : 'REGR_SXX';\nKW_REGR_SXY            : 'REGR_SXY';\nKW_REGR_SYY            : 'REGR_SYY';\nKW_RELEASE             : 'RELEASE';\nKW_RENAME              : 'RENAME';\nKW_RESET               : 'RESET';\nKW_RESULT              : 'RESULT';\nKW_RETURN              : 'RETURN';\nKW_RETURNS             : 'RETURNS';\nKW_REVOKE              : 'REVOKE';\nKW_RIGHT               : 'RIGHT';\nKW_RLIKE               : 'RLIKE';\nKW_ROLLBACK            : 'ROLLBACK';\nKW_ROLLUP              : 'ROLLUP';\nKW_ROW                 : 'ROW';\nKW_ROWS                : 'ROWS';\nKW_ROW_NUMBER          : 'ROW_NUMBER';\nKW_RUNNING             : 'RUNNING';\nKW_SAFE_CAST           : 'SAFE_CAST';\nKW_SAFE_OFFSET         : 'SAFE_OFFSET';\nKW_SAFE_ORDINAL        : 'SAFE_ORDINAL';\nKW_SATURDAY            : 'SATURDAY';\nKW_SAVEPOINT           : 'SAVEPOINT';\nKW_SCALA               : 'SCALA';\nKW_SCOPE               : 'SCOPE';\nKW_SCROLL              : 'SCROLL';\nKW_SEARCH              : 'SEARCH';\nKW_SECOND              : 'SECOND';\nKW_SEEK                : 'SEEK';\nKW_SELECT              : 'SELECT';\nKW_SENSITIVE           : 'SENSITIVE';\nKW_SEPARATOR           : 'SEPARATOR';\nKW_SESSION_USER        : 'SESSION_USER';\nKW_SET                 : 'SET';\nKW_SHOW                : 'SHOW';\nKW_SIMILAR             : 'SIMILAR';\nKW_SKIP                : 'SKIP';\nKW_SMALLINT            : 'SMALLINT';\nKW_SOME                : 'SOME';\nKW_SPECIFIC            : 'SPECIFIC';\nKW_SPECIFICTYPE        : 'SPECIFICTYPE';\nKW_SQL                 : 'SQL';\nKW_SQLEXCEPTION        : 'SQLEXCEPTION';\nKW_SQLSTATE            : 'SQLSTATE';\nKW_SQLWARNING          : 'SQLWARNING';\nKW_SQRT                : 'SQRT';\nKW_START               : 'START';\nKW_STATEMENT           : 'STATEMENT';\nKW_STATIC              : 'STATIC';\nKW_STATISTICS          : 'STATISTICS';\nKW_STDDEV_POP          : 'STDDEV_POP';\nKW_STDDEV_SAMP         : 'STDDEV_SAMP';\nKW_STREAM              : 'STREAM';\nKW_STRING              : 'STRING';\nKW_STRING_AGG          : 'STRING_AGG';\nKW_SUBMULTISET         : 'SUBMULTISET';\nKW_SUBSET              : 'SUBSET';\nKW_SUBSTRING           : 'SUBSTRING';\nKW_SUBSTRING_REGEX     : 'SUBSTRING_REGEX';\nKW_SUCCEEDS            : 'SUCCEEDS';\nKW_SUM                 : 'SUM';\nKW_SUNDAY              : 'SUNDAY';\nKW_SYMMETRIC           : 'SYMMETRIC';\nKW_SYSTEM              : 'SYSTEM';\nKW_SYSTEM_TIME         : 'SYSTEM_TIME';\nKW_SYSTEM_USER         : 'SYSTEM_USER';\nKW_TABLE               : 'TABLE';\nKW_TABLES              : 'TABLES';\nKW_TABLESAMPLE         : 'TABLESAMPLE';\nKW_THEN                : 'THEN';\nKW_THURSDAY            : 'THURSDAY';\nKW_TIME                : 'TIME';\nKW_TIMESTAMP           : 'TIMESTAMP';\nKW_TIMESTAMP_DIFF      : 'TIMESTAMP_DIFF';\nKW_TIMESTAMP_LTZ       : 'TIMESTAMP_LTZ';\nKW_TIMESTAMP_TRUNC     : 'TIMESTAMP_TRUNC';\nKW_TIMEZONE_HOUR       : 'TIMEZONE_HOUR';\nKW_TIMEZONE_MINUTE     : 'TIMEZONE_MINUTE';\nKW_TIME_DIFF           : 'TIME_DIFF';\nKW_TIME_TRUNC          : 'TIME_TRUNC';\nKW_TINYINT             : 'TINYINT';\nKW_TO                  : 'TO';\nKW_TRAILING            : 'TRAILING';\nKW_TRANSLATE           : 'TRANSLATE';\nKW_TRANSLATE_REGEX     : 'TRANSLATE_REGEX';\nKW_TRANSLATION         : 'TRANSLATION';\nKW_TREAT               : 'TREAT';\nKW_TRIGGER             : 'TRIGGER';\nKW_TRIM                : 'TRIM';\nKW_TRIM_ARRAY          : 'TRIM_ARRAY';\nKW_TRUE                : 'TRUE';\nKW_TRUNCATE            : 'TRUNCATE';\nKW_TRY_CAST            : 'TRY_CAST';\nKW_TUESDAY             : 'TUESDAY';\nKW_UESCAPE             : 'UESCAPE';\nKW_UNION               : 'UNION';\nKW_UNIQUE              : 'UNIQUE';\nKW_UNKNOWN             : 'UNKNOWN';\nKW_UNNEST              : 'UNNEST';\nKW_UNPIVOT             : 'UNPIVOT';\nKW_UPDATE              : 'UPDATE';\nKW_UPPER               : 'UPPER';\nKW_UPSERT              : 'UPSERT';\nKW_USE                 : 'USE';\nKW_USER                : 'USER';\nKW_USING               : 'USING';\nKW_VALUE               : 'VALUE';\nKW_VALUES              : 'VALUES';\nKW_VALUE_OF            : 'VALUE_OF';\nKW_VARBINARY           : 'VARBINARY';\nKW_VARCHAR             : 'VARCHAR';\nKW_VARYING             : 'VARYING';\nKW_VAR_POP             : 'VAR_POP';\nKW_VAR_SAMP            : 'VAR_SAMP';\nKW_VERSIONING          : 'VERSIONING';\nKW_VIEWS               : 'VIEWS';\nKW_VIRTUAL             : 'VIRTUAL';\nKW_WATERMARK           : 'WATERMARK';\nKW_WATERMARKS          : 'WATERMARKS';\nKW_WEDNESDAY           : 'WEDNESDAY';\nKW_WEEKS               : 'WEEKS';\nKW_WHEN                : 'WHEN';\nKW_WHENEVER            : 'WHENEVER';\nKW_WHERE               : 'WHERE';\nKW_WIDTH_BUCKET        : 'WIDTH_BUCKET';\nKW_WINDOW              : 'WINDOW';\nKW_WITH                : 'WITH';\nKW_WITHIN              : 'WITHIN';\nKW_WITHOUT             : 'WITHOUT';\nKW_YEAR                : 'YEAR';\n\n/**\n * Non-Reserved Keywords\n * Keywords that are used in the syntax rules but do not exist in the above keyword list section.\n * Please keep the keyword in alphabetical order if new keyword is added.\n * New non-reserved keywords should also be added to the nonReservedKeywords rule in FlinkSqlParser.g4 file.\n */\nKW_ADD                 : 'ADD';\nKW_AFTER               : 'AFTER';\nKW_ASC                 : 'ASC';\nKW_CASCADE             : 'CASCADE';\nKW_CATALOG             : 'CATALOG';\nKW_CENTURY             : 'CENTURY';\nKW_CONFIG              : 'CONFIG';\nKW_CONSTRAINTS         : 'CONSTRAINTS';\nKW_CUMULATE            : 'CUMULATE';\nKW_DATA                : 'DATA';\nKW_DATABASE            : 'DATABASE';\nKW_DAYS                : 'DAYS';\nKW_DECADE              : 'DECADE';\nKW_DESC                : 'DESC';\nKW_DESCRIPTOR          : 'DESCRIPTOR';\nKW_DIV                 : 'DIV';\nKW_ENGINE              : 'ENGINE';\nKW_EPOCH               : 'EPOCH';\nKW_EXCLUDING           : 'EXCLUDING';\nKW_FILE                : 'FILE';\nKW_FIRST               : 'FIRST';\nKW_GENERATED           : 'GENERATED';\nKW_HOP                 : 'HOP';\nKW_HOURS               : 'HOURS';\nKW_IGNORE              : 'IGNORE';\nKW_INCLUDING           : 'INCLUDING';\nKW_JAR                 : 'JAR';\nKW_JARS                : 'JARS';\nKW_JAVA                : 'JAVA';\nKW_KEY                 : 'KEY';\nKW_LAST                : 'LAST';\nKW_LOAD                : 'LOAD';\nKW_MAP                 : 'MAP';\nKW_MICROSECOND         : 'MICROSECOND';\nKW_MILLENNIUM          : 'MILLENNIUM';\nKW_MILLISECOND         : 'MILLISECOND';\nKW_MINUTES             : 'MINUTES';\nKW_MONTHS              : 'MONTHS';\nKW_NANOSECOND          : 'NANOSECOND';\nKW_NULLS               : 'NULLS';\nKW_OPTIONS             : 'OPTIONS';\nKW_PAST                : 'PAST';\nKW_PLAN                : 'PLAN';\nKW_PRECEDING           : 'PRECEDING';\nKW_PYTHON              : 'PYTHON';\nKW_PYTHON_ARCHIVES     : 'PYTHON_ARCHIVES';\nKW_PYTHON_DEPENDENCIES : 'PYTHON_DEPENDENCIES';\nKW_PYTHON_FILES        : 'PYTHON_FILES';\nKW_PYTHON_JAR          : 'PYTHON_JAR';\nKW_PYTHON_PARAMETER    : 'PYTHON_PARAMETER';\nKW_PYTHON_REQUIREMENTS : 'PYTHON_REQUIREMENTS';\nKW_QUARTER             : 'QUARTER';\nKW_REMOVE              : 'REMOVE';\nKW_RESTRICT            : 'RESTRICT';\nKW_SECONDS             : 'SECONDS';\nKW_SESSION             : 'SESSION';\nKW_SETS                : 'SETS';\nKW_SIZE                : 'SIZE';\nKW_SLIDE               : 'SLIDE';\nKW_STEP                : 'STEP';\nKW_TEMPORARY           : 'TEMPORARY';\nKW_TIMECOL             : 'TIMECOL';\nKW_TUMBLE              : 'TUMBLE';\nKW_UNLOAD              : 'UNLOAD';\nKW_VIEW                : 'VIEW';\nKW_WEEK                : 'WEEK';\nKW_YEARS               : 'YEARS';\nKW_ZONE                : 'ZONE';\n\n// Operators. Comparation\n\nEQUAL_SYMBOL       : '=';\nGREATER_SYMBOL     : '>';\nLESS_SYMBOL        : '<';\nEXCLAMATION_SYMBOL : '!';\n\n// Operators. Bit\n\nBIT_NOT_OP : '~';\nBIT_OR_OP  : '|';\nBIT_AND_OP : '&';\nBIT_XOR_OP : '^';\n\n// Constructors symbols\n\nDOT                  : '.';\nLS_BRACKET           : '[';\nRS_BRACKET           : ']';\nLR_BRACKET           : '(';\nRR_BRACKET           : ')';\nLB_BRACKET           : '{';\nRB_BRACKET           : '}';\nCOMMA                : ',';\nSEMICOLON            : ';';\nAT_SIGN              : '@';\nSINGLE_QUOTE_SYMB    : '\\'';\nDOUBLE_QUOTE_SYMB    : '\"';\nREVERSE_QUOTE_SYMB   : '`';\nCOLON_SYMB           : ':';\nASTERISK_SIGN        : '*';\nUNDERLINE_SIGN       : '_';\nHYPHEN_SIGN          : '-';\nADD_SIGN             : '+';\nPERCENT_SIGN         : '%';\nDOUBLE_VERTICAL_SIGN : '||';\nDOUBLE_HYPHEN_SIGN   : '--';\nSLASH_SIGN           : '/';\nQUESTION_MARK_SIGN   : '?';\nDOUBLE_RIGHT_ARROW   : '=>';\nSTRING_LITERAL       : DQUOTA_STRING | SQUOTA_STRING | BQUOTA_STRING;\nDIG_LITERAL          : DEC_DIGIT+;\nREAL_LITERAL: (DEC_DIGIT+)? '.' DEC_DIGIT+\n    | DEC_DIGIT+ '.' EXPONENT_NUM_PART\n    | (DEC_DIGIT+)? '.' (DEC_DIGIT+ EXPONENT_NUM_PART)\n    | DEC_DIGIT+ EXPONENT_NUM_PART;\nBIT_STRING : BIT_STRING_L;\nID_LITERAL : ID_LITERAL_FRAG;\n\nfragment JAR_FILE_PARTTARN : '`' ( '\\\\' . | '``' | ~('`' | '\\\\'))* '`';\nfragment EXPONENT_NUM_PART : 'E' [-+]? DEC_DIGIT+;\nfragment ID_LITERAL_FRAG   : [A-Z_0-9]*? [A-Z_]+? [A-Z_0-9]*;\nfragment DEC_DIGIT         : [0-9];\nfragment DEC_LETTER        : [A-Z];\nfragment DQUOTA_STRING     : '\"' ( '\\\\' . | '\"\"' | ~('\"' | '\\\\'))* '\"';\nfragment SQUOTA_STRING     : '\\'' ('\\\\' . | '\\'\\'' | ~('\\'' | '\\\\'))* '\\'';\nfragment BIT_STRING_L      : 'B' '\\'' [01]+ '\\'';\nfragment BQUOTA_STRING     : '`' ( '\\\\' . | '``' | ~('`' | '\\\\'))* '`';"
  },
  {
    "path": "superior-flink-parser/src/main/antlr4/io/github/melin/superior/parser/flink/antlr4/FlinkSqlParser.g4",
    "content": "parser grammar FlinkSqlParser;\n\noptions { tokenVocab=FlinkSqlLexer; }\n\nsqlStatements\n    : singleStatement* EOF\n    ;\n\nsingleStatement\n    : sqlStatement SEMICOLON?\n    | emptyStatement\n    ;\n\nsqlStatement\n    : ddlStatement\n    | dmlStatement\n    | describeStatement\n    | explainStatement\n    | useStatement\n    | showStatement\n    | loadStatement\n    | unloadStatement\n    | setStatement\n    | resetStatement\n    | jarStatement\n    | dtAddStatement\n    ;\n\nemptyStatement\n    : SEMICOLON\n    ;\n\nddlStatement\n    : createTable\n    | createDatabase\n    | createView\n    | createFunction\n    | createCatalog\n    | alterTable\n    | alterView\n    | alterDatabase\n    | alterFunction\n    | dropCatalog\n    | dropTable\n    | dropDatabase\n    | dropView\n    | dropFunction\n    ;\n\ndmlStatement\n    : queryStatement\n    | insertStatement\n    ;\n\n// some statement\ndescribeStatement\n    : (KW_DESCRIBE | KW_DESC) tablePath\n    ;\n\nexplainStatement\n    : KW_EXPLAIN (explainDetails | KW_PLAN KW_FOR)? (\n        dmlStatement\n        | insertSimpleStatement\n        | insertMulStatement\n    )\n    ;\n\nexplainDetails\n    : explainDetail (COMMA explainDetail)*\n    ;\n\nexplainDetail\n    : KW_CHANGELOG_MODE\n    | KW_PLAN_ADVICE\n    | KW_JSON_EXECUTION_PLAN\n    | KW_ESTIMATED_COST\n    ;\n\nuseStatement\n    : KW_USE KW_CATALOG catalogPath\n    | KW_USE databasePath\n    | useModuleStatement\n    ;\n\nuseModuleStatement\n    : KW_USE KW_MODULES uid (COMMA uid)*\n    ;\n\nshowStatement\n    : KW_SHOW (KW_CATALOGS | KW_DATABASES | KW_VIEWS | KW_JARS)\n    | KW_SHOW KW_CURRENT (KW_CATALOG | KW_DATABASE)\n    | KW_SHOW KW_TABLES (( KW_FROM | KW_IN) databasePath)? likePredicate?\n    | KW_SHOW KW_COLUMNS ( KW_FROM | KW_IN) (viewPath | tablePath) likePredicate?\n    | KW_SHOW KW_CREATE (KW_TABLE tablePath | KW_VIEW viewPath)\n    | KW_SHOW KW_USER? KW_FUNCTIONS\n    | KW_SHOW KW_FULL? KW_MODULES\n    ;\n\nloadStatement\n    : KW_LOAD KW_MODULE uid (KW_WITH tablePropertyList)?\n    ;\n\nunloadStatement\n    : KW_UNLOAD KW_MODULE uid\n    ;\n\nsetStatement\n    : KW_SET (tableProperty)?\n    ;\n\nresetStatement\n    : KW_RESET tablePropertyKey?\n    ;\n\njarStatement\n    : (KW_ADD | KW_REMOVE) KW_JAR jarFileName\n    ;\n\n// 数栈平台自研的添加文件语法\ndtAddStatement\n    : KW_ADD KW_JAR KW_WITH dtFilePath (KW_AS uid)?\n    | KW_ADD KW_FILE KW_WITH dtFilePath (KW_AS uid)? (KW_RENAME uid)?\n    | KW_ADD (\n        KW_PYTHON_FILES\n        | KW_PYTHON_REQUIREMENTS\n        | KW_PYTHON_DEPENDENCIES\n        | KW_PYTHON_JAR\n        | KW_PYTHON_ARCHIVES\n    ) KW_WITH dtFilePath KW_RENAME uid\n    | KW_ADD KW_PYTHON_PARAMETER dtFilePath\n    | KW_ADD KW_ENGINE KW_FILE KW_WITH dtFilePath KW_RENAME uid KW_KEY uid\n    | KW_ADD KW_CONFIG KW_FILE KW_WITH dtFilePath KW_FOR uid KW_AS uid\n    ;\n\ndtFilePath\n    : (SLASH_SIGN? uid)+\n    ;\n\n// Create statements\n\ncreateTable\n    : (simpleCreateTable | createTableAsSelect)\n    ;\n\nsimpleCreateTable\n    : KW_CREATE KW_TEMPORARY? KW_TABLE ifNotExists? tablePathCreate LR_BRACKET columnOptionDefinition (\n        COMMA columnOptionDefinition\n    )* (COMMA watermarkDefinition)? (COMMA tableConstraint)? (COMMA selfDefinitionClause)? RR_BRACKET (\n        KW_COMMENT comment=STRING_LITERAL\n    )? partitionDefinition? withOption likeDefinition?\n    ;\n\n/*\n * 详见 https://nightlies.apache.org/flink/flink-docs-release-1.16/docs/dev/table/sql/create/#as-select_statement\n * CTAS 不支持指定显示指定列，不支持创建分区表，临时表\n */\ncreateTableAsSelect\n    : KW_CREATE KW_TABLE ifNotExists? tablePathCreate withOption (KW_AS queryStatement)?\n    ;\n\ncolumnOptionDefinition\n    : physicalColumnDefinition\n    | metadataColumnDefinition\n    | computedColumnDefinition\n    ;\n\nphysicalColumnDefinition\n    : columnNameCreate columnType columnConstraint? (KW_COMMENT comment=STRING_LITERAL)?\n    ;\n\ncolumnNameCreate\n    : uid\n    | expression\n    ;\n\ncolumnName\n    : uid\n    ;\n\ncolumnNamePath\n    : uid\n    ;\n\ncolumnNameList\n    : LR_BRACKET columnName (COMMA columnName)* RR_BRACKET\n    ;\n\ncolumnType\n    : colType=(KW_DATE | KW_BOOLEAN | KW_NULL)\n    | colType=(\n        KW_CHAR\n        | KW_VARCHAR\n        | KW_STRING\n        | KW_BINARY\n        | KW_VARBINARY\n        | KW_BYTES\n        | KW_TINYINT\n        | KW_SMALLINT\n        | KW_INT\n        | KW_INTEGER\n        | KW_BIGINT\n        | KW_TIME\n        | KW_TIMESTAMP_LTZ\n        | KW_DATETIME\n    ) lengthOneDimension?\n    | colType=KW_TIMESTAMP lengthOneDimension? ((KW_WITHOUT | KW_WITH) KW_LOCAL? KW_TIME KW_ZONE)?\n    | colType=(KW_DECIMAL | KW_DEC | KW_NUMERIC | KW_FLOAT | KW_DOUBLE) lengthTwoOptionalDimension?\n    | colType=(KW_ARRAY | KW_MULTISET) lengthOneTypeDimension?\n    | colType=KW_MAP mapTypeDimension?\n    | colType=KW_ROW rowTypeDimension?\n    | colType=KW_RAW lengthTwoStringDimension?\n    ;\n\nlengthOneDimension\n    : LR_BRACKET decimalLiteral RR_BRACKET\n    ;\n\nlengthTwoOptionalDimension\n    : LR_BRACKET decimalLiteral (COMMA decimalLiteral)? RR_BRACKET\n    ;\n\nlengthTwoStringDimension\n    : LR_BRACKET stringLiteral (COMMA stringLiteral)? RR_BRACKET\n    ;\n\nlengthOneTypeDimension\n    : LESS_SYMBOL columnType GREATER_SYMBOL\n    ;\n\nmapTypeDimension\n    : LESS_SYMBOL columnType (COMMA columnType) GREATER_SYMBOL\n    ;\n\nrowTypeDimension\n    : LESS_SYMBOL columnName columnType (COMMA columnName columnType)* GREATER_SYMBOL\n    | LR_BRACKET columnName columnType (COMMA columnName columnType)* RR_BRACKET\n    ;\n\ncolumnConstraint\n    : (KW_CONSTRAINT constraintName)? KW_PRIMARY KW_KEY (KW_NOT KW_ENFORCED)?\n    | KW_NOT? KW_NULL\n    ;\n\nmetadataColumnDefinition\n    : columnNameCreate columnType KW_METADATA (KW_FROM metadataKey)? KW_VIRTUAL?\n    ;\n\nmetadataKey\n    : STRING_LITERAL\n    ;\n\ncomputedColumnDefinition\n    : columnNameCreate KW_AS computedColumnExpression (KW_COMMENT comment=STRING_LITERAL)?\n    ;\n\n// 计算表达式\ncomputedColumnExpression\n    : expression\n    ;\n\nwatermarkDefinition\n    : KW_WATERMARK KW_FOR columnName KW_AS expression\n    ;\n\ntableConstraint\n    : (KW_CONSTRAINT constraintName)? KW_PRIMARY KW_KEY columnNameList KW_NOT KW_ENFORCED\n    ;\n\nconstraintName\n    : identifier\n    ;\n\nselfDefinitionClause // 数栈自定义语句 ‘PERIOD KW_FOR SYSTEM_TIME’\n    : KW_PERIOD KW_FOR KW_SYSTEM_TIME\n    ;\n\npartitionDefinition\n    : KW_PARTITIONED KW_BY transformList\n    ;\n\ntransformList\n    : LR_BRACKET transform (COMMA transform)* RR_BRACKET\n    ;\n\ntransform\n    : columnName                                                         # identityTransform\n    | LR_BRACKET transformArgument (COMMA transformArgument)* RR_BRACKET # applyTransform\n    ;\n\ntransformArgument\n    : qualifiedName\n    | constant\n    ;\n\nlikeDefinition\n    : KW_LIKE tablePath (LR_BRACKET likeOption* RR_BRACKET)?\n    ;\n\nlikeOption\n    : ((KW_INCLUDING | KW_EXCLUDING) (KW_ALL | KW_CONSTRAINTS | KW_PARTITIONS))\n    | ((KW_INCLUDING | KW_EXCLUDING | KW_OVERWRITING) (KW_GENERATED | KW_OPTIONS | KW_WATERMARKS))\n    ;\n\ncreateCatalog\n    : KW_CREATE KW_CATALOG catalogPathCreate withOption\n    ;\n\ncreateDatabase\n    : KW_CREATE KW_DATABASE ifNotExists? databasePathCreate (KW_COMMENT comment=STRING_LITERAL)? withOption\n    ;\n\ncreateView\n    : KW_CREATE KW_TEMPORARY? KW_VIEW ifNotExists? viewPathCreate columnNameList? (\n        KW_COMMENT comment=STRING_LITERAL\n    )? KW_AS queryStatement\n    ;\n\ncreateFunction\n    : KW_CREATE (KW_TEMPORARY | KW_TEMPORARY KW_SYSTEM)? KW_FUNCTION ifNotExists? functionNameCreate KW_AS identifier (\n        KW_LANGUAGE (KW_JAVA | KW_SCALA | KW_PYTHON)\n    )? usingClause?\n    ;\n\nusingClause\n    : KW_USING KW_JAR jarFileName (COMMA KW_JAR jarFileName)*\n    ;\n\njarFileName\n    : STRING_LITERAL\n    ;\n\n// Alter statements\n// Just for simple alter table statements,\n// it only includes rename, set key, add constraint, drop constraint, add unique\n\nalterTable\n    : KW_ALTER KW_TABLE ifExists? tablePath (\n        renameDefinition\n        | setKeyValueDefinition\n        | addConstraint\n        | dropConstraint\n        | addUnique\n    )\n    ;\n\nrenameDefinition\n    : KW_RENAME uid? KW_TO uid\n    ;\n\nsetKeyValueDefinition\n    : KW_SET tablePropertyList\n    ;\n\naddConstraint\n    : KW_ADD KW_CONSTRAINT constraintName KW_PRIMARY KW_KEY columnNameList notForced?\n    ;\n\ndropConstraint\n    : KW_DROP KW_CONSTRAINT constraintName\n    ;\n\naddUnique\n    : KW_ADD KW_UNIQUE columnNameList\n    ;\n\nnotForced\n    : KW_NOT KW_ENFORCED\n    ;\n\nalterView\n    : KW_ALTER KW_VIEW viewPath (renameDefinition | KW_AS queryStatement)\n    ;\n\nalterDatabase\n    : KW_ALTER KW_DATABASE databasePath setKeyValueDefinition\n    ;\n\nalterFunction\n    : KW_ALTER (KW_TEMPORARY | KW_TEMPORARY KW_SYSTEM)? KW_FUNCTION ifExists? functionName KW_AS identifier (\n        KW_LANGUAGE (KW_JAVA | KW_SCALA | KW_PYTHON)\n    )? // TODO\n    ;\n\n// Drop statements\n\ndropCatalog\n    : KW_DROP KW_CATALOG ifExists? catalogPath\n    ;\n\ndropTable\n    : KW_DROP KW_TEMPORARY? KW_TABLE ifExists? tablePath\n    ;\n\ndropDatabase\n    : KW_DROP KW_DATABASE ifExists? databasePath dropType=(KW_RESTRICT | KW_CASCADE)?\n    ;\n\ndropView\n    : KW_DROP KW_TEMPORARY? KW_VIEW ifExists? viewPath\n    ;\n\ndropFunction\n    : KW_DROP (KW_TEMPORARY | KW_TEMPORARY KW_SYSTEM)? KW_FUNCTION ifExists? functionName\n    ;\n\n// Insert statements\n\ninsertStatement\n    : (KW_EXECUTE? insertSimpleStatement)\n    | insertMulStatementCompatibility\n    | (KW_EXECUTE insertMulStatement)\n    ;\n\ninsertSimpleStatement\n    : KW_INSERT (KW_INTO | KW_OVERWRITE) tablePath (\n        insertPartitionDefinition? columnNameList? queryStatement\n        | valuesDefinition\n    )\n    ;\n\ninsertPartitionDefinition\n    : KW_PARTITION tablePropertyList\n    ;\n\nvaluesDefinition\n    : KW_VALUES valuesRowDefinition (COMMA valuesRowDefinition)*\n    ;\n\nvaluesRowDefinition\n    : LR_BRACKET valueDefinition (COMMA valueDefinition)* RR_BRACKET\n    ;\n\nvalueDefinition\n    : constant\n    | functionCallExpression\n    ;\n\ninsertMulStatementCompatibility\n    : KW_BEGIN KW_STATEMENT KW_SET SEMICOLON (insertSimpleStatement SEMICOLON)+ KW_END\n    ;\n\ninsertMulStatement\n    : KW_STATEMENT KW_SET KW_BEGIN (insertSimpleStatement SEMICOLON)+ KW_END\n    ;\n\n// Select statements\n\nqueryStatement\n    : valuesClause\n    | withClause queryStatement\n    | LR_BRACKET queryStatement RR_BRACKET\n    | left=queryStatement operator=(KW_INTERSECT | KW_UNION | KW_EXCEPT) KW_ALL? right=queryStatement orderByClause? limitClause?\n    | selectClause orderByClause? limitClause?\n    | selectStatement orderByClause? limitClause?\n    ;\n\nvaluesClause\n    : KW_VALUES expression (COMMA expression)*\n    ;\n\nwithClause\n    : KW_WITH withItem (COMMA withItem)*\n    ;\n\nwithItem\n    : withItemName (LR_BRACKET columnName (COMMA columnName)* RR_BRACKET)? KW_AS LR_BRACKET queryStatement RR_BRACKET\n    ;\n\nwithItemName\n    : identifier\n    ;\n\nselectStatement\n    : selectClause fromClause? whereClause? groupByClause? havingClause? windowClause?\n    | selectClause fromClause matchRecognizeClause\n    ;\n\nselectClause\n    : KW_SELECT setQuantifier? (\n        ASTERISK_SIGN\n        | projectItemDefinition (COMMA projectItemDefinition)*\n    )\n    ;\n\nprojectItemDefinition\n    : overWindowItem\n    | expression (KW_AS? columnName)?\n    | columnName (KW_AS? expression)?\n    ;\n\noverWindowItem\n    : primaryExpression KW_OVER windowSpec KW_AS identifier\n    | primaryExpression KW_OVER errorCapturingIdentifier KW_AS identifier\n    ;\n\nfromClause\n    : KW_FROM tableExpression\n    ;\n\ntableExpression\n    : tableReference (COMMA tableReference)*\n    | tableExpression KW_NATURAL? (KW_LEFT | KW_RIGHT | KW_FULL | KW_INNER)? KW_OUTER? KW_JOIN tableExpression joinCondition?\n    | tableExpression KW_CROSS KW_JOIN tableExpression\n    | inlineDataValueClause\n    | windowTVFClause\n    ;\n\ntableReference\n    : tablePrimary tableAlias?\n    ;\n\ntablePrimary\n    : KW_TABLE? tablePath systemTimePeriod?\n    | viewPath systemTimePeriod?\n    | KW_LATERAL KW_TABLE LR_BRACKET functionCallExpression RR_BRACKET\n    | KW_LATERAL? LR_BRACKET queryStatement RR_BRACKET\n    | KW_UNNEST LR_BRACKET expression RR_BRACKET\n    ;\n\nsystemTimePeriod\n    : KW_FOR KW_SYSTEM_TIME KW_AS KW_OF dateTimeExpression\n    ;\n\ndateTimeExpression\n    : expression\n    ;\n\ninlineDataValueClause\n    : LR_BRACKET valuesDefinition RR_BRACKET tableAlias\n    ;\n\nwindowTVFClause\n    : KW_TABLE LR_BRACKET windowTVFExpression RR_BRACKET\n    ;\n\nwindowTVFExpression\n    : windowTVFName LR_BRACKET windowTVFParam (COMMA windowTVFParam)* RR_BRACKET\n    ;\n\nwindowTVFName\n    : KW_TUMBLE\n    | KW_HOP\n    | KW_CUMULATE\n    ;\n\nwindowTVFParam\n    : KW_TABLE timeAttrColumn\n    | columnDescriptor\n    | timeIntervalExpression\n    | KW_DATA DOUBLE_RIGHT_ARROW KW_TABLE timeAttrColumn\n    | KW_TIMECOL DOUBLE_RIGHT_ARROW columnDescriptor\n    | timeIntervalParamName DOUBLE_RIGHT_ARROW timeIntervalExpression\n    ;\n\ntimeIntervalParamName\n    : KW_DATA\n    | KW_TIMECOL\n    | KW_SIZE\n    | KW_OFFSET\n    | KW_STEP\n    | KW_SLIDE\n    ;\n\ncolumnDescriptor\n    : KW_DESCRIPTOR LR_BRACKET columnName RR_BRACKET\n    ;\n\njoinCondition\n    : KW_ON booleanExpression\n    | KW_USING columnNameList\n    ;\n\nwhereClause\n    : KW_WHERE booleanExpression\n    ;\n\ngroupByClause\n    : KW_GROUP KW_BY groupItemDefinition (COMMA groupItemDefinition)*\n    ;\n\ngroupItemDefinition\n    : columnName\n    | groupWindowFunction\n    | LR_BRACKET RR_BRACKET\n    | LR_BRACKET expression (COMMA expression)* RR_BRACKET\n    | groupingSetsNotationName LR_BRACKET expression (COMMA expression)* RR_BRACKET\n    | groupingSets LR_BRACKET groupItemDefinition (COMMA groupItemDefinition)* RR_BRACKET\n    | expression\n    ;\n\ngroupingSets\n    : KW_GROUPING KW_SETS\n    ;\n\ngroupingSetsNotationName\n    : KW_CUBE\n    | KW_ROLLUP\n    ;\n\ngroupWindowFunction\n    : groupWindowFunctionName LR_BRACKET timeAttrColumn COMMA timeIntervalExpression RR_BRACKET\n    ;\n\ngroupWindowFunctionName\n    : KW_TUMBLE\n    | KW_HOP\n    | KW_SESSION\n    ;\n\ntimeAttrColumn\n    : uid\n    ;\n\nhavingClause\n    : KW_HAVING booleanExpression\n    ;\n\nwindowClause\n    : KW_WINDOW namedWindow (COMMA namedWindow)*\n    ;\n\nnamedWindow\n    : name=errorCapturingIdentifier KW_AS windowSpec\n    ;\n\nwindowSpec\n    : name=errorCapturingIdentifier? LR_BRACKET partitionByClause? orderByClause? windowFrame? RR_BRACKET\n    ;\n\nmatchRecognizeClause\n    : KW_MATCH_RECOGNIZE LR_BRACKET partitionByClause? orderByClause? measuresClause? outputMode? afterMatchStrategy? patternDefinition?\n        patternVariablesDefinition RR_BRACKET (KW_AS? identifier)?\n    ;\n\norderByClause\n    : KW_ORDER KW_BY orderItemDefinition (COMMA orderItemDefinition)*\n    ;\n\norderItemDefinition\n    : columnName ordering=(KW_ASC | KW_DESC)? (KW_NULLS nullOrder=(KW_LAST | KW_FIRST))?\n    ;\n\nlimitClause\n    : KW_LIMIT (KW_ALL | limit=expression)\n    ;\n\npartitionByClause\n    : KW_PARTITION KW_BY (columnName | primaryExpression) (COMMA (columnName | primaryExpression))*\n    ;\n\nquantifiers\n    : (ASTERISK_SIGN)\n    | (ADD_SIGN)\n    | (QUESTION_MARK_SIGN)\n    | (LB_BRACKET DIG_LITERAL COMMA DIG_LITERAL RB_BRACKET)\n    | (LB_BRACKET DIG_LITERAL COMMA RB_BRACKET)\n    | (LB_BRACKET COMMA DIG_LITERAL RB_BRACKET)\n    ;\n\nmeasuresClause\n    : KW_MEASURES projectItemDefinition (COMMA projectItemDefinition)*\n    ;\n\npatternDefinition\n    : KW_PATTERN LR_BRACKET patternVariable+ RR_BRACKET withinClause?\n    ;\n\npatternVariable\n    : unquotedIdentifier quantifiers?\n    ;\n\noutputMode\n    : KW_ALL KW_ROWS KW_PER KW_MATCH\n    | KW_ONE KW_ROW KW_PER KW_MATCH\n    ;\n\nafterMatchStrategy\n    : KW_AFTER KW_MATCH KW_SKIP KW_PAST KW_LAST KW_ROW\n    | KW_AFTER KW_MATCH KW_SKIP KW_TO KW_NEXT KW_ROW\n    | KW_AFTER KW_MATCH KW_SKIP KW_TO KW_LAST unquotedIdentifier\n    | KW_AFTER KW_MATCH KW_SKIP KW_TO KW_FIRST unquotedIdentifier\n    ;\n\npatternVariablesDefinition\n    : KW_DEFINE projectItemDefinition (COMMA projectItemDefinition)*\n    ;\n\nwindowFrame\n    : KW_RANGE KW_BETWEEN timeIntervalExpression frameBound\n    | KW_ROWS KW_BETWEEN DIG_LITERAL frameBound\n    ;\n\nframeBound\n    : KW_PRECEDING KW_AND KW_CURRENT KW_ROW\n    ;\n\nwithinClause\n    : KW_WITHIN timeIntervalExpression\n    ;\n\n// expression\n\nexpression\n    : booleanExpression\n    ;\n\nbooleanExpression\n    : KW_NOT booleanExpression                                                         # logicalNot\n    | KW_EXISTS LR_BRACKET queryStatement RR_BRACKET                                   # exists\n    | valueExpression predicate?                                                       # predicated\n    | left=booleanExpression operator=KW_AND right=booleanExpression                   # logicalBinary\n    | left=booleanExpression operator=KW_OR right=booleanExpression                    # logicalBinary\n    | booleanExpression KW_IS KW_NOT? kind=(KW_TRUE | KW_FALSE | KW_UNKNOWN | KW_NULL) # logicalNested\n    ;\n\npredicate\n    : KW_NOT? kind=KW_BETWEEN (KW_ASYMMETRIC | KW_SYMMETRIC)? lower=valueExpression KW_AND upper=valueExpression\n    | KW_NOT? kind=KW_IN LR_BRACKET expression (COMMA expression)* RR_BRACKET\n    | KW_NOT? kind=KW_IN LR_BRACKET queryStatement RR_BRACKET\n    | kind=KW_EXISTS LR_BRACKET queryStatement RR_BRACKET\n    | KW_NOT? kind=KW_RLIKE pattern=valueExpression\n    | likePredicate\n    | KW_IS KW_NOT? kind=(KW_TRUE | KW_FALSE | KW_UNKNOWN | KW_NULL)\n    | KW_IS KW_NOT? kind=KW_DISTINCT KW_FROM right=valueExpression\n    | KW_NOT? kind=KW_SIMILAR KW_TO right=valueExpression (KW_ESCAPE stringLiteral)?\n    | KW_IS KW_JSON (KW_VALUE | KW_ARRAY | identifier)?\n    ;\n\njsonFunctionBranch\n    : KW_NULL\n    | KW_EMPTY KW_ARRAY\n    | KW_EMPTY uid\n    | KW_TRUE\n    | KW_FALSE\n    | KW_UNKNOWN\n    ;\n\nlikePredicate\n    : KW_NOT? kind=KW_LIKE quantifier=(KW_ANY | KW_ALL) (\n        LR_BRACKET RR_BRACKET\n        | LR_BRACKET expression (COMMA expression)* RR_BRACKET\n    )\n    | KW_NOT? kind=KW_LIKE pattern=valueExpression (KW_ESCAPE stringLiteral)?\n    ;\n\nvalueExpression\n    : primaryExpression                                                                                        # valueExpressionDefault\n    | operator=(HYPHEN_SIGN | ADD_SIGN | BIT_NOT_OP) valueExpression                                           # arithmeticUnary\n    | left=valueExpression operator=(ASTERISK_SIGN | SLASH_SIGN | PERCENT_SIGN | KW_DIV) right=valueExpression # arithmeticBinary\n    | left=valueExpression operator=(ADD_SIGN | HYPHEN_SIGN | DOUBLE_VERTICAL_SIGN) right=valueExpression      # arithmeticBinary\n    | left=valueExpression operator=BIT_AND_OP right=valueExpression                                           # arithmeticBinary\n    | left=valueExpression operator=BIT_XOR_OP right=valueExpression                                           # arithmeticBinary\n    | left=valueExpression operator=BIT_OR_OP right=valueExpression                                            # arithmeticBinary\n    | left=valueExpression comparisonOperator right=valueExpression                                            # comparison\n    ;\n\nfunctionCallExpression\n    : reservedKeywordsNoParamsUsedAsFuncName\n    | functionNameAndParams\n    | functionNameWithParams LR_BRACKET (setQuantifier? functionParam (COMMA functionParam)*)? RR_BRACKET\n    ;\n\nprimaryExpression\n    : KW_CASE whenClause+ (KW_ELSE elseExpression=expression)? KW_END                  # searchedCase\n    | KW_CASE value=expression whenClause+ (KW_ELSE elseExpression=expression)? KW_END # simpleCase\n    | KW_CAST LR_BRACKET expression KW_AS columnType RR_BRACKET                        # cast\n    // | STRUCT LR_BRACKET (argument+=namedExpression (COMMA argument+=namedExpression)*)? RR_BRACKET             #struct\n    | KW_FIRST LR_BRACKET expression (KW_IGNORE KW_NULLS)? RR_BRACKET                    # first\n    | KW_LAST LR_BRACKET expression (KW_IGNORE KW_NULLS)? RR_BRACKET                     # last\n    | KW_POSITION LR_BRACKET substr=valueExpression KW_IN str=valueExpression RR_BRACKET # position\n    | constant                                                                           # constantDefault\n    | ASTERISK_SIGN                                                                      # star\n    | uid DOT ASTERISK_SIGN                                                              # star\n    // | LR_BRACKET namedExpression (COMMA namedExpression)+ RR_BRACKET                                           #rowConstructor\n    | LR_BRACKET queryStatement RR_BRACKET # subqueryExpression\n    | functionCallExpression               # functionCall\n    // | identifier '->' expression                                                               #lambda\n    // | '(' identifier (',' identifier)+ ')' '->' expression                                     #lambda\n    | value=primaryExpression LS_BRACKET index=valueExpression RS_BRACKET # subscript\n    | columnNamePath                                                      # columnReference\n    | dereferenceDefinition                                               # dereference\n    | LR_BRACKET expression RR_BRACKET                                    # parenthesizedExpression\n    // | EXTRACT LR_BRACKET field=identifier KW_FROM source=valueExpression RR_BRACKET                             #extract\n    // | (SUBSTR | SUBSTRING) LR_BRACKET str=valueExpression (KW_FROM | COMMA) pos=valueExpression\n    //   ((KW_FOR | COMMA) len=valueExpression)? RR_BRACKET                                                   #substring\n    // | TRIM LR_BRACKET trimOption=(BOTH | LEADING | TRAILING)? (trimStr=valueExpression)?\n    //    KW_FROM srcStr=valueExpression RR_BRACKET                                                         #trim\n    // | OVERLAY LR_BRACKET input=valueExpression PLACING replace=valueExpression\n    //   KW_FROM position=valueExpression (KW_FOR length=valueExpression)? RR_BRACKET                          #overlay\n    ;\n\nfunctionNameCreate\n    : uid\n    ;\n\nfunctionName\n    : reservedKeywordsUsedAsFuncName\n    | reservedKeywordsNoParamsUsedAsFuncName\n    | reservedKeywordsFollowParamsUsedAsFuncName\n    | uid\n    ;\n\n/**\n* Built-in function name that is following with params directly without parentheses\n* Reference Link:https://nightlies.apache.org/flink/flink-docs-release-1.16/zh/docs/dev/table/functions/systemfunctions/#%E6%97%B6%E9%97%B4%E5%87%BD%E6%95%B0\n*/\nfunctionNameAndParams\n    : reservedKeywordsFollowParamsUsedAsFuncName STRING_LITERAL\n    | timeIntervalExpression\n    ;\n\n/**\n* Function name that is need to follow with parentheses and params\n*/\nfunctionNameWithParams\n    : reservedKeywordsUsedAsFuncName\n    | uid\n    ;\n\nfunctionParam\n    : reservedKeywordsUsedAsFuncParam\n    | timeIntervalUnit\n    | timePointUnit\n    | expression\n    | jsonValueParams\n    | jsonQueryParams\n    | jsonObjectParams\n    | jsonArrayParams\n    ;\n\njsonValueParams\n    : columnNamePath (uid columnType)? (\n        (uid | KW_NULL | KW_DEFAULT valueExpression) KW_ON KW_EMPTY\n    )? ((uid | KW_NULL | KW_DEFAULT valueExpression) KW_ON uid)?\n    ;\n\njsonQueryParams\n    : columnNamePath ((KW_WITHOUT | KW_WITH uid?) KW_ARRAY? uid)? (\n        jsonFunctionBranch KW_ON KW_EMPTY\n    )? (jsonFunctionBranch KW_ON uid)?\n    ;\n\n// JSON 函数只能在 JSON_OBJECT 函数中使用\njsonObjectParams\n    : (\n        KW_KEY? columnNamePath KW_VALUE? (\n            valueExpression\n            | KW_JSON LR_BRACKET (valueExpression)* RR_BRACKET\n        )\n    )* ((KW_NULL | uid) KW_ON KW_NULL)?\n    ;\n\njsonArrayParams\n    : valueExpression* ((KW_NULL | uid) KW_ON KW_NULL)?\n    ;\n\ndereferenceDefinition\n    : uid\n    ;\n\n// base common\n\ncorrelationName\n    : identifier\n    ;\n\nqualifiedName\n    : identifier\n    | dereferenceDefinition\n    ;\n\ntimeIntervalExpression\n    : KW_INTERVAL (errorCapturingMultiUnitsInterval | errorCapturingUnitToUnitInterval)?\n    ;\n\nerrorCapturingMultiUnitsInterval\n    : multiUnitsInterval unitToUnitInterval?\n    ;\n\nmultiUnitsInterval\n    : (intervalValue timeIntervalUnit)+\n    ;\n\nerrorCapturingUnitToUnitInterval\n    : body=unitToUnitInterval (error1=multiUnitsInterval | error2=unitToUnitInterval)?\n    ;\n\nunitToUnitInterval\n    : value=intervalValue from=timeIntervalUnit KW_TO to=timeIntervalUnit\n    ;\n\nintervalValue\n    : (ADD_SIGN | HYPHEN_SIGN)? (DIG_LITERAL | REAL_LITERAL)\n    | STRING_LITERAL\n    ;\n\ntableAlias\n    : KW_AS? alias=identifier identifierList?\n    ;\n\nerrorCapturingIdentifier\n    : identifier errorCapturingIdentifierExtra\n    ;\n\nerrorCapturingIdentifierExtra\n    : (KW_MINUS identifier)+ # errorIdent\n    |                        # realIdent\n    ;\n\nidentifierList\n    : LR_BRACKET identifierSeq RR_BRACKET\n    ;\n\nidentifierSeq\n    : identifier (COMMA identifier)*\n    ;\n\nidentifier\n    : unquotedIdentifier  # unquotedIdentifierAlternative\n    | quotedIdentifier    # quotedIdentifierAlternative\n    | nonReservedKeywords # nonReservedKeywordsAlternative\n    ;\n\nunquotedIdentifier\n    : DIG_LITERAL\n    | ID_LITERAL\n    ;\n\nquotedIdentifier\n    : STRING_LITERAL\n    ;\n\nwhenClause\n    : KW_WHEN condition=expression KW_THEN result=expression\n    ;\n\ncatalogPath\n    : identifier\n    ;\n\ncatalogPathCreate\n    : identifier\n    ;\n\ndatabasePath\n    : identifier (DOT identifier)?\n    ;\n\ndatabasePathCreate\n    : identifier (DOT identifier)?\n    ;\n\ntablePathCreate\n    : identifier (DOT identifier)?\n    | identifier DOT identifier (DOT identifier)?\n    ;\n\ntablePath\n    : identifier (DOT identifier)?\n    | identifier DOT identifier (DOT identifier)?\n    ;\n\nviewPath\n    : identifier (DOT identifier)?\n    | identifier DOT identifier (DOT identifier)?\n    ;\n\nviewPathCreate\n    : identifier (DOT identifier)?\n    | identifier DOT identifier (DOT identifier)?\n    ;\n\nuid\n    : identifier (DOT identifier)*?\n    ;\n\nwithOption\n    : KW_WITH tablePropertyList\n    ;\n\nifNotExists\n    : KW_IF KW_NOT KW_EXISTS\n    ;\n\nifExists\n    : KW_IF KW_EXISTS\n    ;\n\ntablePropertyList\n    : LR_BRACKET tableProperty (COMMA tableProperty)* RR_BRACKET\n    ;\n\ntableProperty\n    : key=tablePropertyKey (EQUAL_SYMBOL? value=tablePropertyValue)?\n    ;\n\ntablePropertyKey\n    : identifier\n    | dereferenceDefinition\n    | STRING_LITERAL\n    ;\n\ntablePropertyValue\n    : DIG_LITERAL\n    | REAL_LITERAL\n    | booleanLiteral\n    | STRING_LITERAL\n    ;\n\nlogicalOperator\n    : KW_AND\n    | BIT_AND_OP BIT_AND_OP\n    | KW_OR\n    | BIT_OR_OP BIT_OR_OP\n    ;\n\ncomparisonOperator\n    : EQUAL_SYMBOL\n    | GREATER_SYMBOL\n    | LESS_SYMBOL\n    | LESS_SYMBOL EQUAL_SYMBOL\n    | GREATER_SYMBOL EQUAL_SYMBOL\n    | LESS_SYMBOL GREATER_SYMBOL\n    | EXCLAMATION_SYMBOL EQUAL_SYMBOL\n    | LESS_SYMBOL EQUAL_SYMBOL GREATER_SYMBOL\n    ;\n\nbitOperator\n    : LESS_SYMBOL LESS_SYMBOL\n    | GREATER_SYMBOL GREATER_SYMBOL\n    | BIT_AND_OP\n    | BIT_XOR_OP\n    | BIT_OR_OP\n    ;\n\nmathOperator\n    : ASTERISK_SIGN\n    | SLASH_SIGN\n    | PERCENT_SIGN\n    | KW_DIV\n    | ADD_SIGN\n    | HYPHEN_SIGN\n    | DOUBLE_HYPHEN_SIGN\n    ;\n\nunaryOperator\n    : EXCLAMATION_SYMBOL\n    | BIT_NOT_OP\n    | ADD_SIGN\n    | HYPHEN_SIGN\n    | KW_NOT\n    ;\n\nconstant\n    : timeIntervalExpression\n    | timePointLiteral\n    | stringLiteral               // 引号包含的字符串\n    | HYPHEN_SIGN? decimalLiteral // 正/负整数\n    | booleanLiteral              // 布尔值\n    | REAL_LITERAL                // 小数\n    | BIT_STRING\n    | KW_NOT? KW_NULL // 空 | 非空\n    ;\n\ntimePointLiteral\n    : timePointUnit stringLiteral\n    ;\n\nstringLiteral\n    : STRING_LITERAL\n    ;\n\ndecimalLiteral\n    : DIG_LITERAL\n    ;\n\nbooleanLiteral\n    : KW_TRUE\n    | KW_FALSE\n    ;\n\nsetQuantifier\n    : KW_DISTINCT\n    | KW_ALL\n    ;\n\ntimePointUnit\n    : KW_YEAR\n    | KW_QUARTER\n    | KW_MONTH\n    | KW_WEEK\n    | KW_DAY\n    | KW_HOUR\n    | KW_MINUTE\n    | KW_SECOND\n    | KW_MILLISECOND\n    | KW_MICROSECOND\n    ;\n\ntimeIntervalUnit\n    : KW_MILLENNIUM\n    | KW_CENTURY\n    | KW_DECADE\n    | KW_YEAR\n    | KW_YEARS\n    | KW_QUARTER\n    | KW_MONTH\n    | KW_MONTHS\n    | KW_WEEK\n    | KW_WEEKS\n    | KW_DAY\n    | KW_DAYS\n    | KW_HOUR\n    | KW_HOURS\n    | KW_MINUTE\n    | KW_MINUTES\n    | KW_SECOND\n    | KW_SECONDS\n    | KW_MILLISECOND\n    | KW_MICROSECOND\n    | KW_NANOSECOND\n    | KW_EPOCH\n    ;\n\nreservedKeywordsUsedAsFuncParam\n    : KW_ARRAY\n    | KW_ALL\n    | KW_BOTH\n    | KW_CURRENT_TIMESTAMP\n    | KW_CURRENT_DATE\n    | KW_CURRENT_TIME\n    | KW_LOCALTIME\n    | KW_LOCALTIMESTAMP\n    | KW_DISTINCT\n    | KW_LEADING\n    | KW_TRAILING\n    | KW_VALUE\n    | ASTERISK_SIGN\n    ;\n\n/**\n* Built-in function name without parentheses and params\n*/\nreservedKeywordsNoParamsUsedAsFuncName\n    : KW_LOCALTIME\n    | KW_LOCALTIMESTAMP\n    | KW_CURRENT_TIME\n    | KW_CURRENT_DATE\n    | KW_CURRENT_TIMESTAMP\n    ;\n\nreservedKeywordsFollowParamsUsedAsFuncName\n    : KW_DATE\n    | KW_TIME\n    | KW_TIMESTAMP\n    ;\n\nreservedKeywordsUsedAsFuncName\n    : KW_ABS\n    | KW_ARRAY\n    | KW_AVG\n    | KW_CARDINALITY\n    | KW_CAST\n    | KW_CEIL\n    | KW_CEILING\n    | KW_COALESCE\n    | KW_COLLECT\n    | KW_COUNT\n    | KW_CUME_DIST\n    | KW_DAYOFWEEK\n    | KW_DAYOFYEAR\n    | KW_DENSE_RANK\n    | KW_ELEMENT\n    | KW_EXP\n    | KW_EXTRACT\n    | KW_FIRST_VALUE\n    | KW_FLOOR\n    | KW_GROUPING\n    | KW_HOUR\n    | KW_IF\n    | KW_LAG\n    | KW_LAST_VALUE\n    | KW_LEAD\n    | KW_LEFT\n    | KW_LN\n    | KW_LOWER\n    | KW_MAP\n    | KW_MAX\n    | KW_MIN\n    | KW_MINUTE\n    | KW_MOD\n    | KW_MONTH\n    | KW_NULLIF\n    | KW_NTILE\n    | KW_OVERLAY\n    | KW_PERCENT_RANK\n    | KW_POSITION\n    | KW_POWER\n    | KW_QUARTER\n    | KW_ROW\n    | KW_ROWS\n    | KW_ROW_NUMBER\n    | KW_RANK\n    | KW_RIGHT\n    | KW_SECOND\n    | KW_STDDEV_POP\n    | KW_STDDEV_SAMP\n    | KW_SUBSTRING\n    | KW_SUM\n    | KW_TIMESTAMP_DIFF\n    | KW_TRIM\n    | KW_TRUNCATE\n    | KW_TRY_CAST\n    | KW_UPPER\n    | KW_VAR_POP\n    | KW_VAR_SAMP\n    | KW_WEEK\n    | KW_YEAR\n    | KW_JSON_VALUE\n    | KW_JSON_EXISTS\n    | KW_JSON_QUERY\n    | KW_JSON_OBJECT\n    | KW_JSON_OBJECTAGG\n    | KW_JSON_ARRAY\n    | KW_JSON_ARRAYAGG\n    ;\n\nnonReservedKeywords\n    : KW_ADD\n    | KW_AFTER\n    | KW_ASC\n    | KW_CASCADE\n    | KW_CATALOG\n    | KW_CENTURY\n    | KW_CONFIG\n    | KW_CONSTRAINTS\n    | KW_CUMULATE\n    | KW_DATA\n    | KW_DATABASE\n    | KW_DAYS\n    | KW_DECADE\n    | KW_DESC\n    | KW_DESCRIPTOR\n    | KW_DIV\n    | KW_ENGINE\n    | KW_EPOCH\n    | KW_EXCLUDING\n    | KW_FILE\n    | KW_FIRST\n    | KW_GENERATED\n    | KW_HOP\n    | KW_HOURS\n    | KW_IGNORE\n    | KW_INCLUDING\n    | KW_JAR\n    | KW_JARS\n    | KW_JAVA\n    | KW_KEY\n    | KW_LAST\n    | KW_LOAD\n    | KW_MAP\n    | KW_MICROSECOND\n    | KW_MILLENNIUM\n    | KW_MILLISECOND\n    | KW_MINUTES\n    | KW_MONTHS\n    | KW_NANOSECOND\n    | KW_NULLS\n    | KW_OPTIONS\n    | KW_PAST\n    | KW_PLAN\n    | KW_PRECEDING\n    | KW_PYTHON\n    | KW_PYTHON_ARCHIVES\n    | KW_PYTHON_DEPENDENCIES\n    | KW_PYTHON_FILES\n    | KW_PYTHON_JAR\n    | KW_PYTHON_PARAMETER\n    | KW_PYTHON_REQUIREMENTS\n    | KW_QUARTER\n    | KW_REMOVE\n    | KW_RESTRICT\n    | KW_SECONDS\n    | KW_SESSION\n    | KW_SETS\n    | KW_SIZE\n    | KW_SLIDE\n    | KW_STEP\n    | KW_TEMPORARY\n    | KW_TIMECOL\n    | KW_TUMBLE\n    | KW_UNLOAD\n    | KW_VIEW\n    | KW_WEEK\n    | KW_YEARS\n    | KW_ZONE\n    ;\n"
  },
  {
    "path": "superior-flink-parser/src/main/kotlin/io/github/melin/superior/parser/flink/AbstractSqlParser.kt",
    "content": "package io.github.melin.superior.parser.flink\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(FlinkSqlParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: FlinkSqlParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(FlinkSqlParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-flink-parser/src/main/kotlin/io/github/melin/superior/parser/flink/FlinkSqlAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.flink\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.DefaultStatement\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.common.*\nimport io.github.melin.superior.common.relational.create.CreateCatalog\nimport io.github.melin.superior.common.relational.create.CreateTable\nimport io.github.melin.superior.common.relational.create.CreateTableAsSelect\nimport io.github.melin.superior.common.relational.create.CreateView\nimport io.github.melin.superior.common.relational.dml.InsertMode\nimport io.github.melin.superior.common.relational.dml.InsertMultiTable\nimport io.github.melin.superior.common.relational.dml.InsertTable\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport io.github.melin.superior.common.relational.drop.DropCatalog\nimport io.github.melin.superior.common.relational.table.ColumnDefType\nimport io.github.melin.superior.common.relational.table.ColumnRel\nimport io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser\nimport io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.ComputedColumnDefinitionContext\nimport io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.MetadataColumnDefinitionContext\nimport io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.PhysicalColumnDefinitionContext\nimport io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.TablePropertyContext\nimport io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.TablePropertyListContext\nimport io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.UidContext\nimport io.github.melin.superior.parser.flink.antlr4.FlinkSqlParserBaseVisitor\nimport org.antlr.v4.runtime.tree.RuleNode\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/1/10. */\nclass FlinkSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) :\n    FlinkSqlParserBaseVisitor<Statement>() {\n\n    private var currentOptType: StatementType = StatementType.UNKOWN\n    private var currentAlterActionType: AlterActionType = AlterActionType.UNKOWN\n    private var multiInsertToken: String? = null\n\n    private var limit: Int? = null\n    private var offset: Int? = null\n    private var inputTables: ArrayList<TableId> = arrayListOf()\n    private var outputTables: ArrayList<TableId> = arrayListOf()\n    private var cteTempTables: ArrayList<TableId> = arrayListOf()\n    private var functionNames: HashSet<FunctionId> = hashSetOf()\n\n    private var statements: ArrayList<Statement> = arrayListOf()\n    private val sqls: ArrayList<String> = arrayListOf()\n\n    fun getSqlStatements(): List<Statement> {\n        return statements\n    }\n\n    fun getSplitSqls(): List<String> {\n        return sqls\n    }\n\n    override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {\n        return if (currentResult == null) true else false\n    }\n\n    override fun visitSqlStatements(ctx: FlinkSqlParser.SqlStatementsContext): Statement? {\n        ctx.singleStatement().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else {\n                        var statement = this.visitSingleStatement(it)\n                        if (statement == null) {\n                            statement = DefaultStatement(StatementType.UNKOWN)\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n\n                clean()\n            }\n        }\n        return null\n    }\n\n    private fun clean() {\n        currentOptType = StatementType.UNKOWN\n\n        limit = null\n        offset = null\n        inputTables = arrayListOf()\n        outputTables = arrayListOf()\n        cteTempTables = arrayListOf()\n        functionNames = hashSetOf()\n    }\n\n    override fun visitSqlStatement(ctx: FlinkSqlParser.SqlStatementContext): Statement? {\n        val statement = super.visitSqlStatement(ctx)\n\n        if (statement == null) {\n            val startToken = StringUtils.lowerCase(ctx.getStart().text)\n            if (\"desc\".equals(startToken) || \"describe\".equals(startToken)) {\n                return DefaultStatement(StatementType.DESC)\n            } else {\n                val sql = source(ctx)\n                throw SQLParserException(\"不支持的SQL: \" + sql)\n            }\n        }\n        return statement\n    }\n\n    override fun visitSimpleCreateTable(ctx: FlinkSqlParser.SimpleCreateTableContext): Statement {\n        val tableId = parseTable(ctx.tablePathCreate().text)\n        val comment: String? = if (ctx.comment != null) ctx.comment.text else null\n        val properties = parseTableOptions(ctx.withOption().tablePropertyList())\n        val ifNotExists: Boolean = if (ctx.ifNotExists() != null) true else false\n\n        val primayKeys =\n            if (ctx.tableConstraint() != null) {\n                ctx.tableConstraint().columnNameList().columnName().map { col -> col.uid().text }\n            } else {\n                listOf()\n            }\n\n        val columnRels =\n            ctx.columnOptionDefinition().map {\n                val column = it.getChild(0)\n                if (column is PhysicalColumnDefinitionContext) {\n                    val colName = column.columnNameCreate().text\n                    val dataType = column.columnType().text\n                    val primaryKey = if (column.columnConstraint() != null) true else primayKeys.contains(colName)\n                    val colComment: String? =\n                        if (column.comment != null) column.comment.text else null\n                    ColumnRel(colName, dataType, colComment, primaryKey, ColumnDefType.PHYSICAL)\n                } else if (column is MetadataColumnDefinitionContext) {\n                    val colName = column.columnNameCreate().text\n                    val dataType = column.columnType().text\n                    var metadataKey: String? = null\n                    if (column.metadataKey() != null) {\n                        metadataKey = CommonUtils.cleanQuote(column.metadataKey().text)\n                    }\n                    val columnRel = ColumnRel(colName, dataType, null, ColumnDefType.METADATA)\n                    columnRel.metadataKey = metadataKey\n                    columnRel\n                } else {\n                    val computedColumn = column as ComputedColumnDefinitionContext\n                    val colName = computedColumn.computedColumnExpression().text\n                    val colComment: String? =\n                        if (computedColumn.comment != null) computedColumn.comment.text\n                        else null\n                    val computedExpr = source(computedColumn.computedColumnExpression().expression())\n                    val columnRel = ColumnRel(colName, null, colComment, ColumnDefType.COMPUTED)\n                    columnRel.computedExpr = computedExpr\n                    columnRel\n                }\n            }\n\n        return CreateTable(tableId, TableType.FLINK, comment, columnRels, ifNotExists, properties)\n    }\n\n    override fun visitCreateTableAsSelect(ctx: FlinkSqlParser.CreateTableAsSelectContext): Statement {\n        currentOptType = StatementType.CREATE_TABLE_AS_SELECT\n        val tableId = parseTable(ctx.tablePathCreate().text)\n        val properties = parseTableOptions(ctx.withOption().tablePropertyList())\n\n        val ifNotExists: Boolean = if (ctx.ifNotExists() != null) true else false\n        val queryStmt = this.visitQueryStatement(ctx.queryStatement()) as QueryStmt\n        return CreateTableAsSelect(tableId, queryStmt, null, ifNotExists, properties)\n    }\n\n    override fun visitCreateView(ctx: FlinkSqlParser.CreateViewContext): Statement {\n        currentOptType = StatementType.CREATE_VIEW\n        val tableId = parseTable(ctx.viewPathCreate().text)\n        val comment: String? = if (ctx.comment != null) ctx.comment.text else null\n        val queryStmt = this.visitQueryStatement(ctx.queryStatement()) as QueryStmt\n\n        val ifNotExists: Boolean = if (ctx.ifNotExists() != null) true else false\n        var columnNameList: List<ColumnRel>? = null\n        if (ctx.columnNameList() != null) {\n            columnNameList = ctx.columnNameList().columnName().map { ColumnRel(CommonUtils.cleanQuote(it.uid().text)) }\n        }\n\n        return CreateView(tableId, queryStmt, comment, ifNotExists, columnNameList)\n    }\n\n    override fun visitInsertStatement(ctx: FlinkSqlParser.InsertStatementContext): Statement {\n        if (ctx.insertSimpleStatement() != null) {\n            return this.insertSimpleStatement(ctx.insertSimpleStatement())\n        } else if (ctx.insertMulStatementCompatibility() != null) {\n            val insertTables =\n                ctx.insertMulStatementCompatibility().insertSimpleStatement().map { insertStmt ->\n                    this.insertSimpleStatement(insertStmt)\n                }\n\n            return InsertMultiTable(insertTables)\n        } else if (ctx.insertMulStatement() != null) {\n            val insertTables =\n                ctx.insertMulStatement().insertSimpleStatement().map { insertStmt ->\n                    this.insertSimpleStatement(insertStmt)\n                }\n\n            return InsertMultiTable(insertTables)\n        }\n        return super.visitInsertStatement(ctx)\n    }\n\n    private fun insertSimpleStatement(ctx: FlinkSqlParser.InsertSimpleStatementContext): InsertTable {\n        currentOptType = StatementType.INSERT\n        val tableId = parseTable(ctx.tablePath().text)\n        val insertMode = if (ctx.KW_INTO() != null) InsertMode.INTO else InsertMode.OVERWRITE\n        var columnNameList: List<ColumnRel>? = null\n        if (ctx.columnNameList() != null) {\n            columnNameList = ctx.columnNameList().columnName().map { ColumnRel(CommonUtils.cleanQuote(it.uid().text)) }\n        }\n\n        var queryStmt = QueryStmt()\n        if (ctx.queryStatement() != null) {\n            queryStmt = this.visitQueryStatement(ctx.queryStatement()) as QueryStmt\n        }\n        val insertTable = InsertTable(insertMode, queryStmt, tableId, columnNameList)\n\n        insertTable.outputTables.add(tableId)\n\n        var sql = source(ctx)\n        insertTable.setSql(sql)\n        return insertTable\n    }\n\n    override fun visitQueryStatement(ctx: FlinkSqlParser.QueryStatementContext): Statement {\n        if (currentOptType == StatementType.UNKOWN) {\n            currentOptType = StatementType.SELECT\n        }\n        super.visitQueryStatement(ctx)\n        return QueryStmt(inputTables, limit, offset)\n    }\n\n    override fun visitJarStatement(ctx: FlinkSqlParser.JarStatementContext): Statement {\n        val jarFileName = CommonUtils.cleanQuote(ctx.jarFileName().text)\n        if (ctx.KW_ADD() != null) {\n            return AddResourceStatement(jarFileName, \"jar\")\n        } else {\n            return RemoveResourceStatement(jarFileName, \"jar\")\n        }\n    }\n\n    override fun visitCreateCatalog(ctx: FlinkSqlParser.CreateCatalogContext): Statement {\n        val catalogName: String = CommonUtils.cleanQuote(ctx.catalogPathCreate().text)\n        val properties = parseTableOptions(ctx.withOption().tablePropertyList())\n        return CreateCatalog(catalogName, properties)\n    }\n\n    override fun visitDropCatalog(ctx: FlinkSqlParser.DropCatalogContext): Statement {\n        val catalogName: String = CommonUtils.cleanQuote(ctx.catalogPath().text)\n        return DropCatalog(catalogName)\n    }\n\n    override fun visitExplainStatement(ctx: FlinkSqlParser.ExplainStatementContext?): Statement {\n        return DefaultStatement(StatementType.EXPLAIN)\n    }\n\n    override fun visitUseStatement(ctx: FlinkSqlParser.UseStatementContext): Statement {\n        val catalogName: String = CommonUtils.cleanQuote(ctx.catalogPath().text)\n        return UseCatalog(catalogName)\n    }\n\n    override fun visitWindowTVFParam(ctx: FlinkSqlParser.WindowTVFParamContext): Statement? {\n        if (ctx.timeAttrColumn() != null) {\n            val tableId = parseTable(ctx.timeAttrColumn().uid().text)\n            inputTables.add(tableId)\n        }\n        return null\n    }\n\n    override fun visitTablePath(ctx: FlinkSqlParser.TablePathContext): Statement? {\n        if (\n            StatementType.SELECT == currentOptType ||\n                StatementType.INSERT == currentOptType ||\n                StatementType.UPDATE == currentOptType ||\n                StatementType.DELETE == currentOptType ||\n                StatementType.CREATE_VIEW == currentOptType ||\n                StatementType.CREATE_TABLE_AS_SELECT == currentOptType\n        ) {\n\n            val tableId = parseTable(ctx.text)\n\n            if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {\n                inputTables.add(tableId)\n            }\n        }\n        return null\n    }\n\n    override fun visitWithItem(ctx: FlinkSqlParser.WithItemContext): Statement? {\n        val tableId = TableId(ctx.withItemName().text)\n        cteTempTables.add(tableId)\n        super.visitWithItem(ctx)\n        return null\n    }\n\n    override fun visitSetStatement(ctx: FlinkSqlParser.SetStatementContext): Statement {\n        val tableProperty = ctx.tableProperty()\n        var key = tableProperty.tablePropertyKey().text\n        var value = tableProperty.tablePropertyValue().text\n        key = CommonUtils.cleanQuote(key)\n        value = CommonUtils.cleanQuote(value)\n        return SetStatement(key, value)\n    }\n\n    override fun visitLimitClause(ctx: FlinkSqlParser.LimitClauseContext): Statement? {\n        if (ctx.limit != null) {\n            limit = ctx.limit.text.toInt()\n        }\n        return super.visitLimitClause(ctx)\n    }\n\n    private fun parseTable(path: String): TableId {\n        val path = CommonUtils.cleanQuote(path)\n        val items = StringUtils.split(path, \".\")\n        if (items.size == 3) {\n            val catalog = CommonUtils.cleanQuote(items.get(0))\n            val schema = CommonUtils.cleanQuote(items.get(1))\n            val tableName = CommonUtils.cleanQuote(items.get(2))\n            return TableId(catalog, schema, tableName)\n        } else if (items.size == 2) {\n            val schema = CommonUtils.cleanQuote(items.get(0))\n            val tableName = CommonUtils.cleanQuote(items.get(1))\n            return TableId(schema, tableName)\n        } else if (items.size == 1) {\n            val tableName = CommonUtils.cleanQuote(items.get(0))\n            return TableId(tableName)\n        } else {\n            throw SQLParserException(\"parse multipart error: \" + path)\n        }\n    }\n\n    fun parseDatabase(uid: UidContext): Pair<String?, String> {\n        val nodes = uid.identifier()\n        if (nodes.size == 2) {\n            val database = CommonUtils.cleanQuote(nodes.get(0).text)\n            val schema = CommonUtils.cleanQuote(nodes.get(1).text)\n            return Pair(database, schema)\n        } else if (nodes.size == 1) {\n            val schema = CommonUtils.cleanQuote(nodes.get(0).text)\n            return Pair(null, schema)\n        } else {\n            throw SQLParserException(\"parse multipart error: \" + nodes.size)\n        }\n    }\n\n    private fun parseTableOptions(ctx: TablePropertyListContext): Map<String, String> {\n        val properties = HashMap<String, String>()\n        ctx.tableProperty().forEach { item ->\n            val property = item as TablePropertyContext\n            val key = CommonUtils.cleanQuote(property.key.text)\n            val value = CommonUtils.cleanQuote(property.value.text)\n            properties.put(key, value)\n        }\n\n        return properties\n    }\n}\n"
  },
  {
    "path": "superior-flink-parser/src/main/kotlin/io/github/melin/superior/parser/flink/FlinkSqlHelper.kt",
    "content": "package io.github.melin.superior.parser.flink\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.flink.antlr4.*\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/1/10. */\nobject FlinkSqlHelper {\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until FlinkSqlLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = FlinkSqlLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement {\n        val statements = this.parseMultiStatement(command)\n        if (statements.size != 1) {\n            throw IllegalStateException(\"only parser one sql, sql count: \" + statements.size)\n        } else {\n            return statements.get(0)\n        }\n    }\n\n    @JvmStatic\n    fun parseMultiStatement(command: String): List<Statement> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = FlinkSqlAntlr4Visitor(false, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSqlStatements()\n    }\n\n    @JvmStatic\n    fun splitSql(command: String): List<String> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = FlinkSqlAntlr4Visitor(true, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSplitSqls()\n    }\n\n    @JvmStatic\n    fun checkSqlSyntax(command: String) {\n        val sqlVisitor = FlinkSqlParserBaseVisitor<Statement>()\n        innerParseStatement(command, sqlVisitor)\n    }\n\n    private fun innerParseStatement(command: String, sqlVisitor: FlinkSqlParserBaseVisitor<Statement>) {\n        val charStream = UpperCaseCharStream(CharStreams.fromString(command))\n        val lexer = FlinkSqlLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = FlinkSqlParser(tokenStream)\n        AbstractSqlParser.installCaches(parser)\n        parser.addParseListener(FlinkSqlParserBaseListener())\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n        // parser.interpreter.predictionMode = PredictionMode.SLL\n\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visit(parser.sqlStatements())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                sqlVisitor.visit(parser.sqlStatements())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(command)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-flink-parser/src/test/kotlin/io/github/melin/superior/parser/flink/FlinkCheckSql.kt",
    "content": "package io.github.melin.superior.parser.flink\n\nimport org.junit.Test\n\nclass FlinkCheckSql {\n\n    @Test\n    fun selectSqlTest() {\n        val sql =\n            \"\"\"\n            CREATE TABLE test (\n              name VARCHAR(12)\n            ) with(key = 'name')\n        \"\"\"\n                .trimIndent()\n\n        FlinkSqlHelper.checkSqlSyntax(sql)\n    }\n}\n"
  },
  {
    "path": "superior-flink-parser/src/test/kotlin/io/github/melin/superior/parser/flink/FlinkSqlParserDdlTest.kt",
    "content": "package io.github.melin.superior.parser.flink\n\nimport io.github.melin.superior.common.relational.create.CreateTable\nimport io.github.melin.superior.common.relational.create.CreateView\nimport io.github.melin.superior.common.relational.dml.InsertTable\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2018/1/10. */\nclass FlinkSqlParserDdlTest {\n\n    @Test\n    fun parseMultiSqlTest() {\n        val sql =\n            \"\"\"\n            CREATE TABLE IF NOT EXISTS `RETEK_XX_ITEM_ATTR_TRANSLATE_PRODUCT_ENRICHMENT`(\n              `ITEM`                 STRING,\n              `UDA_ID`               DECIMAL(5,0),\n              `UDA_VALUE_ID`         DECIMAL(3,0),\n              `LANG`                 DECIMAL(6,0),\n              `TRANSLATED_VALUE`     STRING,\n              `LAST_UPDATE_ID`       STRING,\n              `CREATE_DATETIME`      TIMESTAMP(3),\n              `LAST_UPDATE_DATETIME` TIMESTAMP(3),\n              `KAFKA_PROCESS_TIME` AS PROCTIME(),\n              `record_time` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp',\n              `cost` AS price * quantity\n            ) WITH (\n                'connector' = 'kafka',\n            'properties.acks' = '-1',\n            'properties.allow.auto.create.topics' = 'true',\n                'topic' = 'test',\n                'properties.bootstrap.servers' = 'localhost:9082',\n                'value.format' = 'changelog-json',\n                'properties.group.id' = 'test',\n                'key.fields' = 'ITEM;UDA_ID;LANG',\n                'key.format'='json',\n                'scan.startup.mode' = 'earliest-offset',\n                'value.changelog-json.timestamp-format.standard'='ISO-8601',\n                'value.changelog-json.ignore-parse-errors' = 'true'\n            );\n            \n            CREATE VIEW IF NOT EXISTS `MDM_VIEW_PRODUCT_ENRICHMENT` AS \n            (SELECT 'WTCTH' BU_CODE, 'WTCTH' FORMULA_COUNTRY_ID,\n                uif.ITEM PRODUCT_ID,\n                CAST(CAST(uif.UDA_ID AS DECIMAL(5, 0)) AS STRING) ENRICHMENT_ID,\n                uif.UDA_TEXT ENRICHMENT_VALUE,\n                u.UDA_DESC ENRICHMENT_DESC,\n                u.SINGLE_VALUE_IND SINGLE_VALUE_IND,\n                u.DISPLAY_TYPE CONTROL_TYPE,\n                'EN' LANG,\n                'FLINKJDBC' CREATE_BY,\n                uif.LAST_UPDATE_ID LAST_UPDATE_BY,\n                uif.CREATE_DATETIME CREATED,\n                uif.LAST_UPDATE_DATETIME LAST_UPDATED\n            FROM RETEK_UDA_ITEM_FF_PRODUCT_ENRICHMENT uif\n            JOIN MDM_DIM_UDA_LOOKUPMAP_ORACLE FOR SYSTEM_TIME AS OF uif.KAFKA_PROCESS_TIME AS u\n                ON CAST(uif.UDA_ID AS DECIMAL(5, 0)) = u.UDA_ID\n            JOIN MDM_DIM_PRODUCT_ATTRIB_TYPE_LOOKUPMAP_MYSQL FOR SYSTEM_TIME AS OF uif.KAFKA_PROCESS_TIME AS pat\n                ON CAST(CAST(uif.UDA_ID AS DECIMAL(5, 0)) AS STRING) = pat.ATTRIB_ID\n                AND pat.ATTRIB_TYPE = 'PRODUCT_ENRICHMENT'\n            );\n            \n            INSERT INTO PROCESSED_MDM_PRODUCT_ENRICHMENT(PRODUCT_ID, ENRICHMENT_ID, LANG, ENRICHMENT_VALUE,LAST_UPDATED) \n            select PRODUCT_ID, ENRICHMENT_ID, LANG, ENRICHMENT_VALUE,LAST_UPDATED from MDM_VIEW_PRODUCT_ENRICHMENT_TRANSLATE;\n        \"\"\"\n                .trimIndent()\n\n        val statements = FlinkSqlHelper.parseMultiStatement(sql)\n        val createTable = statements.get(0)\n        if (createTable is CreateTable) {\n            Assert.assertEquals(\"RETEK_XX_ITEM_ATTR_TRANSLATE_PRODUCT_ENRICHMENT\", createTable.tableId.tableName)\n            Assert.assertEquals(11, createTable.columnRels?.size)\n            Assert.assertEquals(\"PROCTIME()\", createTable.columnRels?.get(8)?.computedExpr)\n            Assert.assertEquals(\"timestamp\", createTable.columnRels?.get(9)?.metadataKey)\n            Assert.assertEquals(\"price * quantity\", createTable.columnRels?.get(10)?.computedExpr)\n\n            Assert.assertEquals(12, createTable.properties?.size)\n        } else {\n            Assert.fail()\n        }\n\n        val createView = statements.get(1)\n        if (createView is CreateView) {\n            Assert.assertEquals(\"MDM_VIEW_PRODUCT_ENRICHMENT\", createView.tableId.tableName)\n            Assert.assertEquals(3, createView.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n\n        val insertTable = statements.get(2)\n        if (insertTable is InsertTable) {\n            Assert.assertEquals(\"PROCESSED_MDM_PRODUCT_ENRICHMENT\", insertTable.outputTables.get(0).tableName)\n            Assert.assertEquals(1, insertTable.queryStmt.inputTables.size)\n            Assert.assertEquals(5, insertTable.columnRels?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest0() {\n        val sql =\n            \"\"\"\n            CREATE TABLE Orders (\n                `user` BIGINT,\n                product STRING,\n                order_time TIMESTAMP(3),\n                WATERMARK FOR order_time AS order_time - INTERVAL '5' SECOND\n            ) WITH (\n                'connector' = 'kafka'\n            )\n        \"\"\"\n                .trimIndent()\n\n        val statements = FlinkSqlHelper.parseMultiStatement(sql)\n        val createTable = statements.get(0)\n        if (createTable is CreateTable) {\n            Assert.assertEquals(\"Orders\", createTable.tableId.tableName)\n            Assert.assertEquals(3, createTable.columnRels?.size)\n            Assert.assertEquals(1, createTable.properties?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest1() {\n        val sql =\n            \"\"\"\n            CREATE TABLE `Orders` (product STRING PRIMARY KEY NOT ENFORCED, `a.b.c` INT)\n            WITH ('type'='source', 'foo'='bar')\n        \"\"\"\n                .trimIndent()\n\n        val createTable = FlinkSqlHelper.parseStatement(sql)\n        if (createTable is CreateTable) {\n            Assert.assertEquals(\"Orders\", createTable.tableId.tableName)\n            Assert.assertEquals(2, createTable.columnRels?.size)\n            createTable.columnRels?.get(0)?.primaryKey?.let { Assert.assertTrue(it) }\n            Assert.assertEquals(2, createTable.properties?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest2() {\n        val sql =\n            \"\"\"\n            CREATE TABLE flink_meta_role (\n                id INT,\n                name STRING,\n                code STRING,\n                PRIMARY KEY (id) NOT ENFORCED\n                ) WITH (\n                'connector' = 'jdbc',\n                'url' = 'jdbc:mysql://172.18.5.44:3306/superior',\n                'table-name' = 'meta_role',\n                'username' = 'root',\n                'password' = 'root2023'\n            );\n        \"\"\"\n                .trimIndent()\n\n        val createTable = FlinkSqlHelper.parseStatement(sql)\n        if (createTable is CreateTable) {\n            Assert.assertEquals(\"flink_meta_role\", createTable.tableId.tableName)\n            Assert.assertEquals(3, createTable.columnRels?.size)\n            createTable.columnRels?.get(0)?.primaryKey?.let { Assert.assertTrue(it) }\n            Assert.assertEquals(5, createTable.properties?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-flink-parser/src/test/kotlin/io/github/melin/superior/parser/flink/FlinkSqlParserDmlTest.kt",
    "content": "package io.github.melin.superior.parser.flink\n\nimport io.github.melin.superior.common.relational.common.AddResourceStatement\nimport io.github.melin.superior.common.relational.common.SetStatement\nimport io.github.melin.superior.common.relational.create.CreateCatalog\nimport io.github.melin.superior.common.relational.dml.InsertMultiTable\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2018/1/10. */\nclass FlinkSqlParserDmlTest {\n\n    @Test\n    fun selectSqlTest() {\n        val sql =\n            \"\"\"\n            WITH orders_with_total AS (\n                SELECT order_id, price + tax AS total\n                FROM Orders\n            )\n            SELECT order_id, SUM(total)\n            FROM orders_with_total\n            GROUP BY order_id\n            limit 10;\n            \n            SELECT order_id, price FROM (VALUES (1, 2.0), (2, 3.1))  AS t (order_id, price);\n            \n            SELECT * FROM TABLE(TUMBLE(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '10' MINUTES));\n            \n            SELECT * FROM TABLE(\n               TUMBLE(\n                 DATA => TABLE Bid,\n                 TIMECOL => DESCRIPTOR(bidtime),\n                 SIZE => INTERVAL '10' MINUTES));\n                 \n            SELECT * FROM TABLE(\n                HOP(\n                  DATA => TABLE Bid,\n                  TIMECOL => DESCRIPTOR(bidtime),\n                  SLIDE => INTERVAL '5' MINUTES,\n                  SIZE => INTERVAL '10' MINUTES));\n                  \n            SELECT * FROM TABLE(\n            CUMULATE(\n              DATA => TABLE Bid,\n              TIMECOL => DESCRIPTOR(bidtime),\n              STEP => INTERVAL '2' MINUTES,\n              SIZE => INTERVAL '10' MINUTES));\n              \n            SELECT window_start, window_end, SUM(price)\n              FROM TABLE(\n                TUMBLE(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '10' MINUTES, INTERVAL '1' MINUTES))\n              GROUP BY window_start, window_end;  \n              \n            SELECT *\n            FROM (\n              SELECT *,\n                ROW_NUMBER() OVER (PARTITION BY category ORDER BY sales DESC) AS row_num\n              FROM ShopSales)\n            WHERE row_num <= 5;\n            \n            SELECT *\n            FROM Ticker\n                MATCH_RECOGNIZE (\n                    PARTITION BY symbol\n                    ORDER BY rowtime\n                    MEASURES\n                        START_ROW.rowtime AS start_tstamp,\n                        LAST(PRICE_DOWN.rowtime) AS bottom_tstamp,\n                        LAST(PRICE_UP.rowtime) AS end_tstamp\n                    ONE ROW PER MATCH\n                    AFTER MATCH SKIP TO LAST PRICE_UP\n                    PATTERN (START_ROW PRICE_DOWN+ PRICE_UP)\n                    DEFINE\n                        PRICE_DOWN AS\n                            (LAST(PRICE_DOWN.price, 1) IS NULL AND PRICE_DOWN.price < START_ROW.price) OR\n                                PRICE_DOWN.price < LAST(PRICE_DOWN.price, 1),\n                        PRICE_UP AS\n                            PRICE_UP.price > LAST(PRICE_DOWN.price, 1)\n                ) MR;\n                \n                set sfdf_1 = 'adf';\n                set sfdf_2 = true;\n        \"\"\"\n                .trimIndent()\n\n        val statements = FlinkSqlHelper.parseMultiStatement(sql)\n        var queryStmt = statements.get(0)\n        if (queryStmt is QueryStmt) {\n            Assert.assertEquals(\"Orders\", queryStmt.inputTables.get(0).tableName)\n            Assert.assertEquals(10, queryStmt.limit)\n        } else {\n            Assert.fail()\n        }\n\n        queryStmt = statements.get(1)\n        if (queryStmt is QueryStmt) {\n            Assert.assertEquals(0, queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n\n        queryStmt = statements.get(2)\n        if (queryStmt is QueryStmt) {\n            Assert.assertEquals(1, queryStmt.inputTables.size)\n            Assert.assertEquals(\"Bid\", queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n\n        queryStmt = statements.get(3)\n        if (queryStmt is QueryStmt) {\n            Assert.assertEquals(1, queryStmt.inputTables.size)\n            Assert.assertEquals(\"Bid\", queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n\n        queryStmt = statements.get(4)\n        if (queryStmt is QueryStmt) {\n            Assert.assertEquals(1, queryStmt.inputTables.size)\n            Assert.assertEquals(\"Bid\", queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n\n        queryStmt = statements.get(5)\n        if (queryStmt is QueryStmt) {\n            Assert.assertEquals(1, queryStmt.inputTables.size)\n            Assert.assertEquals(\"Bid\", queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n\n        queryStmt = statements.get(6)\n        if (queryStmt is QueryStmt) {\n            Assert.assertEquals(1, queryStmt.inputTables.size)\n            Assert.assertEquals(\"Bid\", queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n\n        queryStmt = statements.get(7)\n        if (queryStmt is QueryStmt) {\n            Assert.assertEquals(1, queryStmt.inputTables.size)\n            Assert.assertEquals(\"ShopSales\", queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n\n        queryStmt = statements.get(8)\n        if (queryStmt is QueryStmt) {\n            Assert.assertEquals(1, queryStmt.inputTables.size)\n            Assert.assertEquals(\"Ticker\", queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun selectSqlTest1() {\n        val sql =\n            \"\"\"\n            add jar \"flink-connector-jdbc-3.1.1-1.17.jar\";\n\n            CREATE TABLE flink_meta_role (\n              id INT,\n              name STRING,\n              code STRING,\n              PRIMARY KEY (id) NOT ENFORCED\n            ) WITH (\n                'connector' = 'jdbc',\n                'url' = 'jdbc:mysql://172.18.5.44:3306/superior',\n                'table-name' = 'meta_role',\n                'username' = 'root',\n                'password' = 'root2023'\n            );\n\n            set 'execution.checkpointing.checkpoints-after-tasks-finish.enabled' = false;\n            SELECT * FROM flink_meta_role;\n        \"\"\"\n                .trimIndent()\n\n        val statements = FlinkSqlHelper.parseMultiStatement(sql)\n        Assert.assertEquals(4, statements.size)\n        val addStmt = statements.get(0)\n\n        if (addStmt is AddResourceStatement) {\n            Assert.assertEquals(\"flink-connector-jdbc-3.1.1-1.17.jar\", addStmt.first())\n        } else {\n            Assert.fail()\n        }\n\n        val setStmt = statements.get(2)\n        if (setStmt is SetStatement) {\n            Assert.assertEquals(\"execution.checkpointing.checkpoints-after-tasks-finish.enabled\", setStmt.key)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun selectSqlTest2() {\n        val sql =\n            \"\"\"\n            CREATE CATALOG my_catalog WITH (\n                'type' = 'jdbc',\n                'default-database' = 'demos',\n                'username' = 'root',\n                'password' = 'root2023',\n                'base-url' = 'jdbc:mysql://172.18.5.44:3306'\n            );\n            \n            USE CATALOG my_catalog;\n            \n            DROP CATALOG IF EXISTS my_catalog\n            \n            EXPLAIN PLAN FOR select * from my_catalog.demos.orders;\n            EXPLAIN ESTIMATED_COST, CHANGELOG_MODE, PLAN_ADVICE, JSON_EXECUTION_PLAN\n             select * from my_catalog.demos.orders;\n        \"\"\"\n                .trimIndent()\n\n        val statements = FlinkSqlHelper.parseMultiStatement(sql)\n        Assert.assertEquals(5, statements.size)\n\n        val createCatalog = statements.get(0)\n        if (createCatalog is CreateCatalog) {\n            Assert.assertEquals(\"my_catalog\", createCatalog.catalogName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun multiInsertTest() {\n        val sql =\n            \"\"\"\n            CREATE TABLE pageviews (\n              user_id BIGINT,\n              page_id BIGINT,\n              viewtime TIMESTAMP,\n              proctime AS PROCTIME()\n            ) WITH (\n              'connector' = 'kafka',\n              'topic' = 'pageviews',\n              'properties.bootstrap.servers' = '...',\n              'format' = 'avro'\n            );\n            \n            CREATE TABLE pageview (\n              page_id BIGINT,\n              cnt BIGINT\n            ) WITH (\n              'connector' = 'jdbc',\n              'url' = 'jdbc:mysql://localhost:3306/mydatabase',\n              'table-name' = 'pageview'\n            );\n            \n            CREATE TABLE uniqueview (\n              page_id BIGINT,\n              cnt BIGINT\n            ) WITH (\n              'connector' = 'jdbc',\n              'url' = 'jdbc:mysql://localhost:3306/mydatabase',\n              'table-name' = 'uniqueview'\n            );\n            \n            EXECUTE STATEMENT SET\n            BEGIN\n            \n            INSERT INTO pageview\n            SELECT page_id, count(1)\n            FROM pageviews\n            GROUP BY page_id;\n            \n            INSERT INTO uniqueview\n            SELECT page_id, count(distinct user_id)\n            FROM pageviews\n            GROUP BY page_id;\n            \n           END;\n        \"\"\"\n                .trimIndent()\n\n        val statements = FlinkSqlHelper.parseMultiStatement(sql)\n        Assert.assertEquals(4, statements.size)\n\n        val statement = statements.get(3)\n        if (statement is InsertMultiTable) {\n            Assert.assertEquals(2, statement.insertTables.size)\n            val insertTable = statement.insertTables.get(0)\n\n            Assert.assertEquals(\n                \"INSERT INTO pageview\\n\" + \" SELECT page_id, count(1)\\n\" + \" FROM pageviews\\n\" + \" GROUP BY page_id\",\n                insertTable.getSql()\n            )\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-flink-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-mysql-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-mysql-parser</artifactId>\n    <name>superior-mysql-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "superior-mysql-parser/src/main/antlr4/io/github/melin/superior/parser/mysql/antlr4/MySqlLexer.g4",
    "content": "lexer grammar MySqlLexer;\n\nchannels {\n    MYSQLCOMMENT,\n    ERRORCHANNEL\n}\n\n// SKIP\n\nSPACE              : [ \\t\\r\\n]+     -> channel(HIDDEN);\nSPEC_MYSQL_COMMENT : '/*!' .+? '*/' -> channel(MYSQLCOMMENT);\nCOMMENT_INPUT      : '/*' .*? '*/'  -> channel(HIDDEN);\nLINE_COMMENT:\n    (('--' [ \\t]* | '#') ~[\\r\\n]* ('\\r'? '\\n' | EOF) | '--' ('\\r'? '\\n' | EOF)) -> channel(HIDDEN)\n;\n\n// Keywords\n// Common Keywords\n\nADD                           : 'ADD';\nALL                           : 'ALL';\nALTER                         : 'ALTER';\nALWAYS                        : 'ALWAYS';\nANALYZE                       : 'ANALYZE';\nAND                           : 'AND';\nARRAY                         : 'ARRAY';\nAS                            : 'AS';\nASC                           : 'ASC';\nATTRIBUTE                     : 'ATTRIBUTE';\nBEFORE                        : 'BEFORE';\nBETWEEN                       : 'BETWEEN';\nBOTH                          : 'BOTH';\nBUCKETS                       : 'BUCKETS';\nBY                            : 'BY';\nCALL                          : 'CALL';\nCASCADE                       : 'CASCADE';\nCASE                          : 'CASE';\nCAST                          : 'CAST';\nCHANGE                        : 'CHANGE';\nCHARACTER                     : 'CHARACTER';\nCHECK                         : 'CHECK';\nCOLLATE                       : 'COLLATE';\nCOLUMN                        : 'COLUMN';\nCONDITION                     : 'CONDITION';\nCONSTRAINT                    : 'CONSTRAINT';\nCONTINUE                      : 'CONTINUE';\nCONVERT                       : 'CONVERT';\nCREATE                        : 'CREATE';\nCROSS                         : 'CROSS';\nCURRENT                       : 'CURRENT';\nCURRENT_ROLE                  : 'CURRENT_ROLE';\nCURRENT_USER                  : 'CURRENT_USER';\nCURSOR                        : 'CURSOR';\nDATABASE                      : 'DATABASE';\nDATABASES                     : 'DATABASES';\nDECLARE                       : 'DECLARE';\nDEFAULT                       : 'DEFAULT';\nDELAYED                       : 'DELAYED';\nDELETE                        : 'DELETE';\nDESC                          : 'DESC';\nDESCRIBE                      : 'DESCRIBE';\nDETERMINISTIC                 : 'DETERMINISTIC';\nDIAGNOSTICS                   : 'DIAGNOSTICS';\nDISTINCT                      : 'DISTINCT';\nDISTINCTROW                   : 'DISTINCTROW';\nDROP                          : 'DROP';\nEACH                          : 'EACH';\nELSE                          : 'ELSE';\nELSEIF                        : 'ELSEIF';\nEMPTY                         : 'EMPTY';\nENCLOSED                      : 'ENCLOSED';\nENFORCED                      : 'ENFORCED';\nESCAPED                       : 'ESCAPED';\nEXCEPT                        : 'EXCEPT';\nEXISTS                        : 'EXISTS';\nEXIT                          : 'EXIT';\nEXPLAIN                       : 'EXPLAIN';\nFALSE                         : 'FALSE';\nFETCH                         : 'FETCH';\nFOR                           : 'FOR';\nFORCE                         : 'FORCE';\nFOREIGN                       : 'FOREIGN';\nFROM                          : 'FROM';\nFULLTEXT                      : 'FULLTEXT';\nGENERATED                     : 'GENERATED';\nGET                           : 'GET';\nGRANT                         : 'GRANT';\nGROUP                         : 'GROUP';\nHAVING                        : 'HAVING';\nHIGH_PRIORITY                 : 'HIGH_PRIORITY';\nHISTOGRAM                     : 'HISTOGRAM';\nIF                            : 'IF';\nIGNORE                        : 'IGNORE';\nIGNORED                       : 'IGNORED';\nIN                            : 'IN';\nINDEX                         : 'INDEX';\nINFILE                        : 'INFILE';\nINNER                         : 'INNER';\nINOUT                         : 'INOUT';\nINSERT                        : 'INSERT';\nINTERVAL                      : 'INTERVAL';\nINTO                          : 'INTO';\nIS                            : 'IS';\nITERATE                       : 'ITERATE';\nJOIN                          : 'JOIN';\nKEY                           : 'KEY';\nKEYS                          : 'KEYS';\nKILL                          : 'KILL';\nLATERAL                       : 'LATERAL';\nLEADING                       : 'LEADING';\nLEAVE                         : 'LEAVE';\nLEFT                          : 'LEFT';\nLIKE                          : 'LIKE';\nLIMIT                         : 'LIMIT';\nLINEAR                        : 'LINEAR';\nLINES                         : 'LINES';\nLOAD                          : 'LOAD';\nLOCK                          : 'LOCK';\nLOCKED                        : 'LOCKED';\nLOOP                          : 'LOOP';\nLOW_PRIORITY                  : 'LOW_PRIORITY';\nMASTER_BIND                   : 'MASTER_BIND';\nMASTER_SSL_VERIFY_SERVER_CERT : 'MASTER_SSL_VERIFY_SERVER_CERT';\nMATCH                         : 'MATCH';\nMAXVALUE                      : 'MAXVALUE';\nMINVALUE                      : 'MINVALUE';\nMODIFIES                      : 'MODIFIES';\nNATURAL                       : 'NATURAL';\nNOT                           : 'NOT';\nNO_WRITE_TO_BINLOG            : 'NO_WRITE_TO_BINLOG';\nNULL_LITERAL                  : 'NULL';\nNUMBER                        : 'NUMBER';\nON                            : 'ON';\nOPTIMIZE                      : 'OPTIMIZE';\nOPTION                        : 'OPTION';\nOPTIONAL                      : 'OPTIONAL';\nOPTIONALLY                    : 'OPTIONALLY';\nOR                            : 'OR';\nORDER                         : 'ORDER';\nOUT                           : 'OUT';\nOUTER                         : 'OUTER';\nOUTFILE                       : 'OUTFILE';\nOVER                          : 'OVER';\nPARTITION                     : 'PARTITION';\nPRIMARY                       : 'PRIMARY';\nPROCEDURE                     : 'PROCEDURE';\nPURGE                         : 'PURGE';\nRANGE                         : 'RANGE';\nREAD                          : 'READ';\nREADS                         : 'READS';\nREFERENCES                    : 'REFERENCES';\nREGEXP                        : 'REGEXP';\nRELEASE                       : 'RELEASE';\nRENAME                        : 'RENAME';\nREPEAT                        : 'REPEAT';\nREPLACE                       : 'REPLACE';\nREQUIRE                       : 'REQUIRE';\nRESIGNAL                      : 'RESIGNAL';\nRESTRICT                      : 'RESTRICT';\nRETAIN                        : 'RETAIN';\nRETURN                        : 'RETURN';\nREVOKE                        : 'REVOKE';\nRIGHT                         : 'RIGHT';\nRLIKE                         : 'RLIKE';\nSCHEMA                        : 'SCHEMA';\nSCHEMAS                       : 'SCHEMAS';\nSELECT                        : 'SELECT';\nSET                           : 'SET';\nSEPARATOR                     : 'SEPARATOR';\nSHOW                          : 'SHOW';\nSIGNAL                        : 'SIGNAL';\nSKIP_                         : 'SKIP';\nSKIP_QUERY_REWRITE            : 'SKIP_QUERY_REWRITE';\nSPATIAL                       : 'SPATIAL';\nSQL                           : 'SQL';\nSQLEXCEPTION                  : 'SQLEXCEPTION';\nSQLSTATE                      : 'SQLSTATE';\nSQLWARNING                    : 'SQLWARNING';\nSQL_BIG_RESULT                : 'SQL_BIG_RESULT';\nSQL_CALC_FOUND_ROWS           : 'SQL_CALC_FOUND_ROWS';\nSQL_SMALL_RESULT              : 'SQL_SMALL_RESULT';\nSSL                           : 'SSL';\nSTACKED                       : 'STACKED';\nSTARTING                      : 'STARTING';\nSTATEMENT                     : 'STATEMENT';\nSTRAIGHT_JOIN                 : 'STRAIGHT_JOIN';\nTABLE                         : 'TABLE';\nTERMINATED                    : 'TERMINATED';\nTHEN                          : 'THEN';\nTO                            : 'TO';\nTRAILING                      : 'TRAILING';\nTRIGGER                       : 'TRIGGER';\nTRUE                          : 'TRUE';\nUNDO                          : 'UNDO';\nUNION                         : 'UNION';\nUNIQUE                        : 'UNIQUE';\nUNLOCK                        : 'UNLOCK';\nUNSIGNED                      : 'UNSIGNED';\nUPDATE                        : 'UPDATE';\nUSAGE                         : 'USAGE';\nUSE                           : 'USE';\nUSING                         : 'USING';\nVALUES                        : 'VALUES';\nWHEN                          : 'WHEN';\nWHERE                         : 'WHERE';\nWHILE                         : 'WHILE';\nWITH                          : 'WITH';\nWRITE                         : 'WRITE';\nXOR                           : 'XOR';\nZEROFILL                      : 'ZEROFILL';\n\n// DATA TYPE Keywords\n\nTINYINT    : 'TINYINT';\nSMALLINT   : 'SMALLINT';\nMEDIUMINT  : 'MEDIUMINT';\nMIDDLEINT  : 'MIDDLEINT';\nINT        : 'INT';\nINT1       : 'INT1';\nINT2       : 'INT2';\nINT3       : 'INT3';\nINT4       : 'INT4';\nINT8       : 'INT8';\nINTEGER    : 'INTEGER';\nBIGINT     : 'BIGINT';\nREAL       : 'REAL';\nDOUBLE     : 'DOUBLE';\nPRECISION  : 'PRECISION';\nFLOAT      : 'FLOAT';\nFLOAT4     : 'FLOAT4';\nFLOAT8     : 'FLOAT8';\nDECIMAL    : 'DECIMAL';\nDEC        : 'DEC';\nNUMERIC    : 'NUMERIC';\nDATE       : 'DATE';\nTIME       : 'TIME';\nTIMESTAMP  : 'TIMESTAMP';\nDATETIME   : 'DATETIME';\nYEAR       : 'YEAR';\nCHAR       : 'CHAR';\nVARCHAR    : 'VARCHAR';\nNVARCHAR   : 'NVARCHAR';\nNATIONAL   : 'NATIONAL';\nBINARY     : 'BINARY';\nVARBINARY  : 'VARBINARY';\nTINYBLOB   : 'TINYBLOB';\nBLOB       : 'BLOB';\nMEDIUMBLOB : 'MEDIUMBLOB';\nLONG       : 'LONG';\nLONGBLOB   : 'LONGBLOB';\nTINYTEXT   : 'TINYTEXT';\nTEXT       : 'TEXT';\nMEDIUMTEXT : 'MEDIUMTEXT';\nLONGTEXT   : 'LONGTEXT';\nENUM       : 'ENUM';\nVARYING    : 'VARYING';\nSERIAL     : 'SERIAL';\nVECTOR     : 'VECTOR';\n\n// Interval type Keywords\n\nYEAR_MONTH         : 'YEAR_MONTH';\nDAY_HOUR           : 'DAY_HOUR';\nDAY_MINUTE         : 'DAY_MINUTE';\nDAY_SECOND         : 'DAY_SECOND';\nHOUR_MINUTE        : 'HOUR_MINUTE';\nHOUR_SECOND        : 'HOUR_SECOND';\nMINUTE_SECOND      : 'MINUTE_SECOND';\nSECOND_MICROSECOND : 'SECOND_MICROSECOND';\nMINUTE_MICROSECOND : 'MINUTE_MICROSECOND';\nHOUR_MICROSECOND   : 'HOUR_MICROSECOND';\nDAY_MICROSECOND    : 'DAY_MICROSECOND';\n\n// JSON keywords\nJSON_ARRAY                    : 'JSON_ARRAY';\nJSON_ARRAYAGG                 : 'JSON_ARRAYAGG';\nJSON_ARRAY_APPEND             : 'JSON_ARRAY_APPEND';\nJSON_ARRAY_INSERT             : 'JSON_ARRAY_INSERT';\nJSON_CONTAINS                 : 'JSON_CONTAINS';\nJSON_CONTAINS_PATH            : 'JSON_CONTAINS_PATH';\nJSON_DEPTH                    : 'JSON_DEPTH';\nJSON_EXTRACT                  : 'JSON_EXTRACT';\nJSON_INSERT                   : 'JSON_INSERT';\nJSON_KEYS                     : 'JSON_KEYS';\nJSON_LENGTH                   : 'JSON_LENGTH';\nJSON_MERGE                    : 'JSON_MERGE';\nJSON_MERGE_PATCH              : 'JSON_MERGE_PATCH';\nJSON_MERGE_PRESERVE           : 'JSON_MERGE_PRESERVE';\nJSON_OBJECT                   : 'JSON_OBJECT';\nJSON_OBJECTAGG                : 'JSON_OBJECTAGG';\nJSON_OVERLAPS                 : 'JSON_OVERLAPS';\nJSON_PRETTY                   : 'JSON_PRETTY';\nJSON_QUOTE                    : 'JSON_QUOTE';\nJSON_REMOVE                   : 'JSON_REMOVE';\nJSON_REPLACE                  : 'JSON_REPLACE';\nJSON_SCHEMA_VALID             : 'JSON_SCHEMA_VALID';\nJSON_SCHEMA_VALIDATION_REPORT : 'JSON_SCHEMA_VALIDATION_REPORT';\nJSON_SEARCH                   : 'JSON_SEARCH';\nJSON_SET                      : 'JSON_SET';\nJSON_STORAGE_FREE             : 'JSON_STORAGE_FREE';\nJSON_STORAGE_SIZE             : 'JSON_STORAGE_SIZE';\nJSON_TABLE                    : 'JSON_TABLE';\nJSON_TYPE                     : 'JSON_TYPE';\nJSON_UNQUOTE                  : 'JSON_UNQUOTE';\nJSON_VALID                    : 'JSON_VALID';\nJSON_VALUE                    : 'JSON_VALUE';\nNESTED                        : 'NESTED';\nORDINALITY                    : 'ORDINALITY';\nPATH                          : 'PATH';\n\n// Group function Keywords\n\nAVG          : 'AVG';\nBIT_AND      : 'BIT_AND';\nBIT_OR       : 'BIT_OR';\nBIT_XOR      : 'BIT_XOR';\nCOUNT        : 'COUNT';\nCUME_DIST    : 'CUME_DIST';\nDENSE_RANK   : 'DENSE_RANK';\nFIRST_VALUE  : 'FIRST_VALUE';\nGROUP_CONCAT : 'GROUP_CONCAT';\nLAG          : 'LAG';\nLAST_VALUE   : 'LAST_VALUE';\nLEAD         : 'LEAD';\nMAX          : 'MAX';\nMIN          : 'MIN';\nNTILE        : 'NTILE';\nNTH_VALUE    : 'NTH_VALUE';\nPERCENT_RANK : 'PERCENT_RANK';\nRANK         : 'RANK';\nROW_NUMBER   : 'ROW_NUMBER';\nSTD          : 'STD';\nSTDDEV       : 'STDDEV';\nSTDDEV_POP   : 'STDDEV_POP';\nSTDDEV_SAMP  : 'STDDEV_SAMP';\nSUM          : 'SUM';\nVAR_POP      : 'VAR_POP';\nVAR_SAMP     : 'VAR_SAMP';\nVARIANCE     : 'VARIANCE';\n\n// Common function Keywords\n\nCURRENT_DATE      : 'CURRENT_DATE';\nCURRENT_TIME      : 'CURRENT_TIME';\nCURRENT_TIMESTAMP : 'CURRENT_TIMESTAMP';\nLOCALTIME         : 'LOCALTIME';\nCURDATE           : 'CURDATE';\nCURTIME           : 'CURTIME';\nDATE_ADD          : 'DATE_ADD';\nDATE_SUB          : 'DATE_SUB';\nEXTRACT           : 'EXTRACT';\nLOCALTIMESTAMP    : 'LOCALTIMESTAMP';\nNOW               : 'NOW';\nPOSITION          : 'POSITION';\nSUBSTR            : 'SUBSTR';\nSUBSTRING         : 'SUBSTRING';\nSYSDATE           : 'SYSDATE';\nTRIM              : 'TRIM';\nUTC_DATE          : 'UTC_DATE';\nUTC_TIME          : 'UTC_TIME';\nUTC_TIMESTAMP     : 'UTC_TIMESTAMP';\n\n// Keywords, but can be ID\n// Common Keywords, but can be ID\n\nACCOUNT                     : 'ACCOUNT';\nACTION                      : 'ACTION';\nAFTER                       : 'AFTER';\nAGGREGATE                   : 'AGGREGATE';\nALGORITHM                   : 'ALGORITHM';\nANY                         : 'ANY';\nAT                          : 'AT';\nAUTHORS                     : 'AUTHORS';\nAUTOCOMMIT                  : 'AUTOCOMMIT';\nAUTOEXTEND_SIZE             : 'AUTOEXTEND_SIZE';\nAUTO_INCREMENT              : 'AUTO_INCREMENT';\nAVG_ROW_LENGTH              : 'AVG_ROW_LENGTH';\nBEGIN                       : 'BEGIN';\nBINLOG                      : 'BINLOG';\nBIT                         : 'BIT';\nBLOCK                       : 'BLOCK';\nBOOL                        : 'BOOL';\nBOOLEAN                     : 'BOOLEAN';\nBTREE                       : 'BTREE';\nCACHE                       : 'CACHE';\nCASCADED                    : 'CASCADED';\nCHAIN                       : 'CHAIN';\nCHANGED                     : 'CHANGED';\nCHANNEL                     : 'CHANNEL';\nCHECKSUM                    : 'CHECKSUM';\nPAGE_CHECKSUM               : 'PAGE_CHECKSUM';\nCIPHER                      : 'CIPHER';\nCLASS_ORIGIN                : 'CLASS_ORIGIN';\nCLIENT                      : 'CLIENT';\nCLOSE                       : 'CLOSE';\nCLUSTERING                  : 'CLUSTERING';\nCOALESCE                    : 'COALESCE';\nCODE                        : 'CODE';\nCOLUMNS                     : 'COLUMNS';\nCOLUMN_FORMAT               : 'COLUMN_FORMAT';\nCOLUMN_NAME                 : 'COLUMN_NAME';\nCOMMENT                     : 'COMMENT';\nCOMMIT                      : 'COMMIT';\nCOMPACT                     : 'COMPACT';\nCOMPLETION                  : 'COMPLETION';\nCOMPRESSED                  : 'COMPRESSED';\nCOMPRESSION                 : 'COMPRESSION' | QUOTE_SYMB? 'COMPRESSION' QUOTE_SYMB?;\nCONCURRENT                  : 'CONCURRENT';\nCONNECT                     : 'CONNECT';\nCONNECTION                  : 'CONNECTION';\nCONSISTENT                  : 'CONSISTENT';\nCONSTRAINT_CATALOG          : 'CONSTRAINT_CATALOG';\nCONSTRAINT_SCHEMA           : 'CONSTRAINT_SCHEMA';\nCONSTRAINT_NAME             : 'CONSTRAINT_NAME';\nCONTAINS                    : 'CONTAINS';\nCONTEXT                     : 'CONTEXT';\nCONTRIBUTORS                : 'CONTRIBUTORS';\nCOPY                        : 'COPY';\nCPU                         : 'CPU';\nCYCLE                       : 'CYCLE';\nCURSOR_NAME                 : 'CURSOR_NAME';\nDATA                        : 'DATA';\nDATAFILE                    : 'DATAFILE';\nDEALLOCATE                  : 'DEALLOCATE';\nDEFAULT_AUTH                : 'DEFAULT_AUTH';\nDEFINER                     : 'DEFINER';\nDELAY_KEY_WRITE             : 'DELAY_KEY_WRITE';\nDES_KEY_FILE                : 'DES_KEY_FILE';\nDIRECTORY                   : 'DIRECTORY';\nDISABLE                     : 'DISABLE';\nDISCARD                     : 'DISCARD';\nDISK                        : 'DISK';\nDO                          : 'DO';\nDUMPFILE                    : 'DUMPFILE';\nDUPLICATE                   : 'DUPLICATE';\nDYNAMIC                     : 'DYNAMIC';\nENABLE                      : 'ENABLE';\nENCRYPTED                   : 'ENCRYPTED';\nENCRYPTION                  : 'ENCRYPTION';\nENCRYPTION_KEY_ID           : 'ENCRYPTION_KEY_ID';\nEND                         : 'END';\nENDS                        : 'ENDS';\nENGINE                      : 'ENGINE';\nENGINES                     : 'ENGINES';\nERROR                       : 'ERROR';\nERRORS                      : 'ERRORS';\nESCAPE                      : 'ESCAPE';\nEVEN                        : 'EVEN';\nEVENT                       : 'EVENT';\nEVENTS                      : 'EVENTS';\nEVERY                       : 'EVERY';\nEXCHANGE                    : 'EXCHANGE';\nEXCLUSIVE                   : 'EXCLUSIVE';\nEXPIRE                      : 'EXPIRE';\nEXPORT                      : 'EXPORT';\nEXTENDED                    : 'EXTENDED';\nEXTENT_SIZE                 : 'EXTENT_SIZE';\nFAILED_LOGIN_ATTEMPTS       : 'FAILED_LOGIN_ATTEMPTS';\nFAST                        : 'FAST';\nFAULTS                      : 'FAULTS';\nFIELDS                      : 'FIELDS';\nFILE_BLOCK_SIZE             : 'FILE_BLOCK_SIZE';\nFILTER                      : 'FILTER';\nFIRST                       : 'FIRST';\nFIXED                       : 'FIXED';\nFLUSH                       : 'FLUSH';\nFOLLOWING                   : 'FOLLOWING';\nFOLLOWS                     : 'FOLLOWS';\nFOUND                       : 'FOUND';\nFULL                        : 'FULL';\nFUNCTION                    : 'FUNCTION';\nGENERAL                     : 'GENERAL';\nGLOBAL                      : 'GLOBAL';\nGRANTS                      : 'GRANTS';\nGROUP_REPLICATION           : 'GROUP_REPLICATION';\nHANDLER                     : 'HANDLER';\nHASH                        : 'HASH';\nHELP                        : 'HELP';\nHISTORY                     : 'HISTORY';\nHOST                        : 'HOST';\nHOSTS                       : 'HOSTS';\nIDENTIFIED                  : 'IDENTIFIED';\nIGNORE_SERVER_IDS           : 'IGNORE_SERVER_IDS';\nIMPORT                      : 'IMPORT';\nINCREMENT                   : 'INCREMENT';\nINDEXES                     : 'INDEXES';\nINITIAL_SIZE                : 'INITIAL_SIZE';\nINPLACE                     : 'INPLACE';\nINSERT_METHOD               : 'INSERT_METHOD';\nINSTALL                     : 'INSTALL';\nINSTANCE                    : 'INSTANCE';\nINSTANT                     : 'INSTANT';\nINVISIBLE                   : 'INVISIBLE';\nINVOKER                     : 'INVOKER';\nIO                          : 'IO';\nIO_THREAD                   : 'IO_THREAD';\nIPC                         : 'IPC';\nISOLATION                   : 'ISOLATION';\nISSUER                      : 'ISSUER';\nJSON                        : 'JSON';\nKEY_BLOCK_SIZE              : 'KEY_BLOCK_SIZE';\nLANGUAGE                    : 'LANGUAGE';\nLAST                        : 'LAST';\nLEAVES                      : 'LEAVES';\nLESS                        : 'LESS';\nLEVEL                       : 'LEVEL';\nLIST                        : 'LIST';\nLOCAL                       : 'LOCAL';\nLOGFILE                     : 'LOGFILE';\nLOGS                        : 'LOGS';\nMASTER                      : 'MASTER';\nMASTER_AUTO_POSITION        : 'MASTER_AUTO_POSITION';\nMASTER_CONNECT_RETRY        : 'MASTER_CONNECT_RETRY';\nMASTER_DELAY                : 'MASTER_DELAY';\nMASTER_HEARTBEAT_PERIOD     : 'MASTER_HEARTBEAT_PERIOD';\nMASTER_HOST                 : 'MASTER_HOST';\nMASTER_LOG_FILE             : 'MASTER_LOG_FILE';\nMASTER_LOG_POS              : 'MASTER_LOG_POS';\nMASTER_PASSWORD             : 'MASTER_PASSWORD';\nMASTER_PORT                 : 'MASTER_PORT';\nMASTER_RETRY_COUNT          : 'MASTER_RETRY_COUNT';\nMASTER_SSL                  : 'MASTER_SSL';\nMASTER_SSL_CA               : 'MASTER_SSL_CA';\nMASTER_SSL_CAPATH           : 'MASTER_SSL_CAPATH';\nMASTER_SSL_CERT             : 'MASTER_SSL_CERT';\nMASTER_SSL_CIPHER           : 'MASTER_SSL_CIPHER';\nMASTER_SSL_CRL              : 'MASTER_SSL_CRL';\nMASTER_SSL_CRLPATH          : 'MASTER_SSL_CRLPATH';\nMASTER_SSL_KEY              : 'MASTER_SSL_KEY';\nMASTER_TLS_VERSION          : 'MASTER_TLS_VERSION';\nMASTER_USER                 : 'MASTER_USER';\nMAX_CONNECTIONS_PER_HOUR    : 'MAX_CONNECTIONS_PER_HOUR';\nMAX_QUERIES_PER_HOUR        : 'MAX_QUERIES_PER_HOUR';\nMAX_ROWS                    : 'MAX_ROWS';\nMAX_SIZE                    : 'MAX_SIZE';\nMAX_UPDATES_PER_HOUR        : 'MAX_UPDATES_PER_HOUR';\nMAX_USER_CONNECTIONS        : 'MAX_USER_CONNECTIONS';\nMEDIUM                      : 'MEDIUM';\nMEMBER                      : 'MEMBER';\nMERGE                       : 'MERGE';\nMESSAGE_TEXT                : 'MESSAGE_TEXT';\nMID                         : 'MID';\nMIGRATE                     : 'MIGRATE';\nMIN_ROWS                    : 'MIN_ROWS';\nMODE                        : 'MODE';\nMODIFY                      : 'MODIFY';\nMUTEX                       : 'MUTEX';\nMYSQL                       : 'MYSQL';\nMYSQL_ERRNO                 : 'MYSQL_ERRNO';\nNAME                        : 'NAME';\nNAMES                       : 'NAMES';\nNCHAR                       : 'NCHAR';\nNEVER                       : 'NEVER';\nNEXT                        : 'NEXT';\nNO                          : 'NO';\nNOCACHE                     : 'NOCACHE';\nNOCOPY                      : 'NOCOPY';\nNOCYCLE                     : 'NOCYCLE';\nNOMAXVALUE                  : 'NOMAXVALUE';\nNOMINVALUE                  : 'NOMINVALUE';\nNOWAIT                      : 'NOWAIT';\nNODEGROUP                   : 'NODEGROUP';\nNONE                        : 'NONE';\nODBC                        : 'ODBC';\nOFFLINE                     : 'OFFLINE';\nOFFSET                      : 'OFFSET';\nOF                          : 'OF';\nOJ                          : 'OJ';\nOLD_PASSWORD                : 'OLD_PASSWORD';\nONE                         : 'ONE';\nONLINE                      : 'ONLINE';\nONLY                        : 'ONLY';\nOPEN                        : 'OPEN';\nOPTIMIZER_COSTS             : 'OPTIMIZER_COSTS';\nOPTIONS                     : 'OPTIONS';\nOWNER                       : 'OWNER';\nPACK_KEYS                   : 'PACK_KEYS';\nPAGE                        : 'PAGE';\nPAGE_COMPRESSED             : 'PAGE_COMPRESSED';\nPAGE_COMPRESSION_LEVEL      : 'PAGE_COMPRESSION_LEVEL';\nPARSER                      : 'PARSER';\nPARTIAL                     : 'PARTIAL';\nPARTITIONING                : 'PARTITIONING';\nPARTITIONS                  : 'PARTITIONS';\nPASSWORD                    : 'PASSWORD';\nPASSWORD_LOCK_TIME          : 'PASSWORD_LOCK_TIME';\nPHASE                       : 'PHASE';\nPLUGIN                      : 'PLUGIN';\nPLUGIN_DIR                  : 'PLUGIN_DIR';\nPLUGINS                     : 'PLUGINS';\nPORT                        : 'PORT';\nPRECEDES                    : 'PRECEDES';\nPRECEDING                   : 'PRECEDING';\nPREPARE                     : 'PREPARE';\nPRESERVE                    : 'PRESERVE';\nPREV                        : 'PREV';\nPROCESSLIST                 : 'PROCESSLIST';\nPROFILE                     : 'PROFILE';\nPROFILES                    : 'PROFILES';\nPROXY                       : 'PROXY';\nQUERY                       : 'QUERY';\nQUICK                       : 'QUICK';\nREBUILD                     : 'REBUILD';\nRECOVER                     : 'RECOVER';\nRECURSIVE                   : 'RECURSIVE';\nREDO_BUFFER_SIZE            : 'REDO_BUFFER_SIZE';\nREDUNDANT                   : 'REDUNDANT';\nRELAY                       : 'RELAY';\nRELAY_LOG_FILE              : 'RELAY_LOG_FILE';\nRELAY_LOG_POS               : 'RELAY_LOG_POS';\nRELAYLOG                    : 'RELAYLOG';\nREMOVE                      : 'REMOVE';\nREORGANIZE                  : 'REORGANIZE';\nREPAIR                      : 'REPAIR';\nREPLICATE_DO_DB             : 'REPLICATE_DO_DB';\nREPLICATE_DO_TABLE          : 'REPLICATE_DO_TABLE';\nREPLICATE_IGNORE_DB         : 'REPLICATE_IGNORE_DB';\nREPLICATE_IGNORE_TABLE      : 'REPLICATE_IGNORE_TABLE';\nREPLICATE_REWRITE_DB        : 'REPLICATE_REWRITE_DB';\nREPLICATE_WILD_DO_TABLE     : 'REPLICATE_WILD_DO_TABLE';\nREPLICATE_WILD_IGNORE_TABLE : 'REPLICATE_WILD_IGNORE_TABLE';\nREPLICATION                 : 'REPLICATION';\nRESET                       : 'RESET';\nRESTART                     : 'RESTART';\nRESUME                      : 'RESUME';\nRETURNED_SQLSTATE           : 'RETURNED_SQLSTATE';\nRETURNING                   : 'RETURNING';\nRETURNS                     : 'RETURNS';\nREUSE                       : 'REUSE';\nROLE                        : 'ROLE';\nROLLBACK                    : 'ROLLBACK';\nROLLUP                      : 'ROLLUP';\nROTATE                      : 'ROTATE';\nROW                         : 'ROW';\nROWS                        : 'ROWS';\nROW_FORMAT                  : 'ROW_FORMAT';\nRTREE                       : 'RTREE';\nSAVEPOINT                   : 'SAVEPOINT';\nSCHEDULE                    : 'SCHEDULE';\nSECURITY                    : 'SECURITY';\nSEQUENCE                    : 'SEQUENCE';\nSERVER                      : 'SERVER';\nSESSION                     : 'SESSION';\nSHARE                       : 'SHARE';\nSHARED                      : 'SHARED';\nSIGNED                      : 'SIGNED';\nSIMPLE                      : 'SIMPLE';\nSLAVE                       : 'SLAVE';\nSLOW                        : 'SLOW';\nSNAPSHOT                    : 'SNAPSHOT';\nSOCKET                      : 'SOCKET';\nSOME                        : 'SOME';\nSONAME                      : 'SONAME';\nSOUNDS                      : 'SOUNDS';\nSOURCE                      : 'SOURCE';\nSQL_AFTER_GTIDS             : 'SQL_AFTER_GTIDS';\nSQL_AFTER_MTS_GAPS          : 'SQL_AFTER_MTS_GAPS';\nSQL_BEFORE_GTIDS            : 'SQL_BEFORE_GTIDS';\nSQL_BUFFER_RESULT           : 'SQL_BUFFER_RESULT';\nSQL_CACHE                   : 'SQL_CACHE';\nSQL_NO_CACHE                : 'SQL_NO_CACHE';\nSQL_THREAD                  : 'SQL_THREAD';\nSTART                       : 'START';\nSTARTS                      : 'STARTS';\nSTATS_AUTO_RECALC           : 'STATS_AUTO_RECALC';\nSTATS_PERSISTENT            : 'STATS_PERSISTENT';\nSTATS_SAMPLE_PAGES          : 'STATS_SAMPLE_PAGES';\nSTATUS                      : 'STATUS';\nSTOP                        : 'STOP';\nSTORAGE                     : 'STORAGE';\nSTORED                      : 'STORED';\nSTRING                      : 'STRING';\nSUBCLASS_ORIGIN             : 'SUBCLASS_ORIGIN';\nSUBJECT                     : 'SUBJECT';\nSUBPARTITION                : 'SUBPARTITION';\nSUBPARTITIONS               : 'SUBPARTITIONS';\nSUSPEND                     : 'SUSPEND';\nSWAPS                       : 'SWAPS';\nSWITCHES                    : 'SWITCHES';\nTABLE_NAME                  : 'TABLE_NAME';\nTABLESPACE                  : 'TABLESPACE';\nTABLE_TYPE                  : 'TABLE_TYPE';\nTEMPORARY                   : 'TEMPORARY';\nTEMPTABLE                   : 'TEMPTABLE';\nTHAN                        : 'THAN';\nTRADITIONAL                 : 'TRADITIONAL';\nTRANSACTION                 : 'TRANSACTION';\nTRANSACTIONAL               : 'TRANSACTIONAL';\nTRIGGERS                    : 'TRIGGERS';\nTRUNCATE                    : 'TRUNCATE';\nUNBOUNDED                   : 'UNBOUNDED';\nUNDEFINED                   : 'UNDEFINED';\nUNDOFILE                    : 'UNDOFILE';\nUNDO_BUFFER_SIZE            : 'UNDO_BUFFER_SIZE';\nUNINSTALL                   : 'UNINSTALL';\nUNKNOWN                     : 'UNKNOWN';\nUNTIL                       : 'UNTIL';\nUPGRADE                     : 'UPGRADE';\nUSER                        : 'USER';\nUSE_FRM                     : 'USE_FRM';\nUSER_RESOURCES              : 'USER_RESOURCES';\nVALIDATION                  : 'VALIDATION';\nVALUE                       : 'VALUE';\nVARIABLES                   : 'VARIABLES';\nVIEW                        : 'VIEW';\nVIRTUAL                     : 'VIRTUAL';\nVISIBLE                     : 'VISIBLE';\nWAIT                        : 'WAIT';\nWARNINGS                    : 'WARNINGS';\nWINDOW                      : 'WINDOW';\nWITHOUT                     : 'WITHOUT';\nWORK                        : 'WORK';\nWRAPPER                     : 'WRAPPER';\nX509                        : 'X509';\nXA                          : 'XA';\nXML                         : 'XML';\nYES                         : 'YES';\n\n// Date format Keywords\n\nEUR      : 'EUR';\nUSA      : 'USA';\nJIS      : 'JIS';\nISO      : 'ISO';\nINTERNAL : 'INTERNAL';\n\n// Interval type Keywords\n\nQUARTER     : 'QUARTER';\nMONTH       : 'MONTH';\nDAY         : 'DAY';\nHOUR        : 'HOUR';\nMINUTE      : 'MINUTE';\nWEEK        : 'WEEK';\nSECOND      : 'SECOND';\nMICROSECOND : 'MICROSECOND';\n\n// Azure Database for MySQL Single Server instance:\nFIREWALL_RULES: 'FIREWALL_RULES';\n\n// PRIVILEGES\n\nADMIN                       : 'ADMIN';\nAPPLICATION_PASSWORD_ADMIN  : 'APPLICATION_PASSWORD_ADMIN';\nAUDIT_ABORT_EXEMPT          : 'AUDIT_ABORT_EXEMPT';\nAUDIT_ADMIN                 : 'AUDIT_ADMIN';\nAUTHENTICATION_POLICY_ADMIN : 'AUTHENTICATION_POLICY_ADMIN';\nBACKUP_ADMIN                : 'BACKUP_ADMIN';\nBINLOG_ADMIN                : 'BINLOG_ADMIN';\nBINLOG_ENCRYPTION_ADMIN     : 'BINLOG_ENCRYPTION_ADMIN';\nCLONE_ADMIN                 : 'CLONE_ADMIN';\nCONNECTION_ADMIN            : 'CONNECTION_ADMIN';\nENCRYPTION_KEY_ADMIN        : 'ENCRYPTION_KEY_ADMIN';\nEXECUTE                     : 'EXECUTE';\nFILE                        : 'FILE';\nFIREWALL_ADMIN              : 'FIREWALL_ADMIN';\nFIREWALL_EXEMPT             : 'FIREWALL_EXEMPT';\nFIREWALL_USER               : 'FIREWALL_USER';\nFLUSH_OPTIMIZER_COSTS       : 'FLUSH_OPTIMIZER_COSTS';\nFLUSH_STATUS                : 'FLUSH_STATUS';\nFLUSH_TABLES                : 'FLUSH_TABLES';\nFLUSH_USER_RESOURCES        : 'FLUSH_USER_RESOURCES';\nGROUP_REPLICATION_ADMIN     : 'GROUP_REPLICATION_ADMIN';\nINNODB_REDO_LOG_ARCHIVE     : 'INNODB_REDO_LOG_ARCHIVE';\nINNODB_REDO_LOG_ENABLE      : 'INNODB_REDO_LOG_ENABLE';\nINVOKE                      : 'INVOKE';\nLAMBDA                      : 'LAMBDA';\nNDB_STORED_USER             : 'NDB_STORED_USER';\nPASSWORDLESS_USER_ADMIN     : 'PASSWORDLESS_USER_ADMIN';\nPERSIST_RO_VARIABLES_ADMIN  : 'PERSIST_RO_VARIABLES_ADMIN';\nPRIVILEGES                  : 'PRIVILEGES';\nPROCESS                     : 'PROCESS';\nRELOAD                      : 'RELOAD';\nREPLICATION_APPLIER         : 'REPLICATION_APPLIER';\nREPLICATION_SLAVE_ADMIN     : 'REPLICATION_SLAVE_ADMIN';\nRESOURCE_GROUP_ADMIN        : 'RESOURCE_GROUP_ADMIN';\nRESOURCE_GROUP_USER         : 'RESOURCE_GROUP_USER';\nROLE_ADMIN                  : 'ROLE_ADMIN';\nROUTINE                     : 'ROUTINE';\nS3                          : 'S3';\nSERVICE_CONNECTION_ADMIN    : 'SERVICE_CONNECTION_ADMIN';\nSESSION_VARIABLES_ADMIN     : QUOTE_SYMB? 'SESSION_VARIABLES_ADMIN' QUOTE_SYMB?;\nSET_USER_ID                 : 'SET_USER_ID';\nSHOW_ROUTINE                : 'SHOW_ROUTINE';\nSHUTDOWN                    : 'SHUTDOWN';\nSUPER                       : 'SUPER';\nSYSTEM_VARIABLES_ADMIN      : 'SYSTEM_VARIABLES_ADMIN';\nTABLES                      : 'TABLES';\nTABLE_ENCRYPTION_ADMIN      : 'TABLE_ENCRYPTION_ADMIN';\nVERSION_TOKEN_ADMIN         : 'VERSION_TOKEN_ADMIN';\nXA_RECOVER_ADMIN            : 'XA_RECOVER_ADMIN';\n\n// Charsets\n\nARMSCII8 : 'ARMSCII8';\nASCII    : 'ASCII';\nBIG5     : 'BIG5';\nCP1250   : 'CP1250';\nCP1251   : 'CP1251';\nCP1256   : 'CP1256';\nCP1257   : 'CP1257';\nCP850    : 'CP850';\nCP852    : 'CP852';\nCP866    : 'CP866';\nCP932    : 'CP932';\nDEC8     : 'DEC8';\nEUCJPMS  : 'EUCJPMS';\nEUCKR    : 'EUCKR';\nGB18030  : 'GB18030';\nGB2312   : 'GB2312';\nGBK      : 'GBK';\nGEOSTD8  : 'GEOSTD8';\nGREEK    : 'GREEK';\nHEBREW   : 'HEBREW';\nHP8      : 'HP8';\nKEYBCS2  : 'KEYBCS2';\nKOI8R    : 'KOI8R';\nKOI8U    : 'KOI8U';\nLATIN1   : 'LATIN1';\nLATIN2   : 'LATIN2';\nLATIN5   : 'LATIN5';\nLATIN7   : 'LATIN7';\nMACCE    : 'MACCE';\nMACROMAN : 'MACROMAN';\nSJIS     : 'SJIS';\nSWE7     : 'SWE7';\nTIS620   : 'TIS620';\nUCS2     : 'UCS2';\nUJIS     : 'UJIS';\nUTF16    : 'UTF16';\nUTF16LE  : 'UTF16LE';\nUTF32    : 'UTF32';\nUTF8     : 'UTF8';\nUTF8MB3  : 'UTF8MB3';\nUTF8MB4  : 'UTF8MB4';\n\n// DB Engines\n\nARCHIVE            : 'ARCHIVE';\nBLACKHOLE          : 'BLACKHOLE';\nCSV                : 'CSV';\nFEDERATED          : 'FEDERATED';\nINNODB             : 'INNODB';\nMEMORY             : 'MEMORY';\nMRG_MYISAM         : 'MRG_MYISAM';\nMYISAM             : 'MYISAM';\nNDB                : 'NDB';\nNDBCLUSTER         : 'NDBCLUSTER';\nPERFORMANCE_SCHEMA : 'PERFORMANCE_SCHEMA';\nTOKUDB             : 'TOKUDB';\n\n// Transaction Levels\n\nREPEATABLE   : 'REPEATABLE';\nCOMMITTED    : 'COMMITTED';\nUNCOMMITTED  : 'UNCOMMITTED';\nSERIALIZABLE : 'SERIALIZABLE';\n\n// Spatial data types\n\nGEOMETRYCOLLECTION : 'GEOMETRYCOLLECTION';\nGEOMCOLLECTION     : 'GEOMCOLLECTION';\nGEOMETRY           : 'GEOMETRY';\nLINESTRING         : 'LINESTRING';\nMULTILINESTRING    : 'MULTILINESTRING';\nMULTIPOINT         : 'MULTIPOINT';\nMULTIPOLYGON       : 'MULTIPOLYGON';\nPOINT              : 'POINT';\nPOLYGON            : 'POLYGON';\n\n// Common function names\n\nABS                               : 'ABS';\nACOS                              : 'ACOS';\nADDDATE                           : 'ADDDATE';\nADDTIME                           : 'ADDTIME';\nAES_DECRYPT                       : 'AES_DECRYPT';\nAES_ENCRYPT                       : 'AES_ENCRYPT';\nAREA                              : 'AREA';\nASBINARY                          : 'ASBINARY';\nASIN                              : 'ASIN';\nASTEXT                            : 'ASTEXT';\nASWKB                             : 'ASWKB';\nASWKT                             : 'ASWKT';\nASYMMETRIC_DECRYPT                : 'ASYMMETRIC_DECRYPT';\nASYMMETRIC_DERIVE                 : 'ASYMMETRIC_DERIVE';\nASYMMETRIC_ENCRYPT                : 'ASYMMETRIC_ENCRYPT';\nASYMMETRIC_SIGN                   : 'ASYMMETRIC_SIGN';\nASYMMETRIC_VERIFY                 : 'ASYMMETRIC_VERIFY';\nATAN                              : 'ATAN';\nATAN2                             : 'ATAN2';\nBENCHMARK                         : 'BENCHMARK';\nBIN                               : 'BIN';\nBIT_COUNT                         : 'BIT_COUNT';\nBIT_LENGTH                        : 'BIT_LENGTH';\nBUFFER                            : 'BUFFER';\nCATALOG_NAME                      : 'CATALOG_NAME';\nCEIL                              : 'CEIL';\nCEILING                           : 'CEILING';\nCENTROID                          : 'CENTROID';\nCHARACTER_LENGTH                  : 'CHARACTER_LENGTH';\nCHARSET                           : 'CHARSET';\nCHAR_LENGTH                       : 'CHAR_LENGTH';\nCOERCIBILITY                      : 'COERCIBILITY';\nCOLLATION                         : 'COLLATION';\nCOMPRESS                          : 'COMPRESS';\nCONCAT                            : 'CONCAT';\nCONCAT_WS                         : 'CONCAT_WS';\nCONNECTION_ID                     : 'CONNECTION_ID';\nCONV                              : 'CONV';\nCONVERT_TZ                        : 'CONVERT_TZ';\nCOS                               : 'COS';\nCOT                               : 'COT';\nCRC32                             : 'CRC32';\nCREATE_ASYMMETRIC_PRIV_KEY        : 'CREATE_ASYMMETRIC_PRIV_KEY';\nCREATE_ASYMMETRIC_PUB_KEY         : 'CREATE_ASYMMETRIC_PUB_KEY';\nCREATE_DH_PARAMETERS              : 'CREATE_DH_PARAMETERS';\nCREATE_DIGEST                     : 'CREATE_DIGEST';\nCROSSES                           : 'CROSSES';\nDATEDIFF                          : 'DATEDIFF';\nDATE_FORMAT                       : 'DATE_FORMAT';\nDAYNAME                           : 'DAYNAME';\nDAYOFMONTH                        : 'DAYOFMONTH';\nDAYOFWEEK                         : 'DAYOFWEEK';\nDAYOFYEAR                         : 'DAYOFYEAR';\nDECODE                            : 'DECODE';\nDEGREES                           : 'DEGREES';\nDES_DECRYPT                       : 'DES_DECRYPT';\nDES_ENCRYPT                       : 'DES_ENCRYPT';\nDIMENSION                         : 'DIMENSION';\nDISJOINT                          : 'DISJOINT';\nDISTANCE                          : 'DISTANCE';\nELT                               : 'ELT';\nENCODE                            : 'ENCODE';\nENCRYPT                           : 'ENCRYPT';\nENDPOINT                          : 'ENDPOINT';\nENGINE_ATTRIBUTE                  : 'ENGINE_ATTRIBUTE';\nENVELOPE                          : 'ENVELOPE';\nEQUALS                            : 'EQUALS';\nEXP                               : 'EXP';\nEXPORT_SET                        : 'EXPORT_SET';\nEXTERIORRING                      : 'EXTERIORRING';\nEXTRACTVALUE                      : 'EXTRACTVALUE';\nFIELD                             : 'FIELD';\nFIND_IN_SET                       : 'FIND_IN_SET';\nFLOOR                             : 'FLOOR';\nFORMAT                            : 'FORMAT';\nFOUND_ROWS                        : 'FOUND_ROWS';\nFROM_BASE64                       : 'FROM_BASE64';\nFROM_DAYS                         : 'FROM_DAYS';\nFROM_UNIXTIME                     : 'FROM_UNIXTIME';\nGEOMCOLLFROMTEXT                  : 'GEOMCOLLFROMTEXT';\nGEOMCOLLFROMWKB                   : 'GEOMCOLLFROMWKB';\nGEOMETRYCOLLECTIONFROMTEXT        : 'GEOMETRYCOLLECTIONFROMTEXT';\nGEOMETRYCOLLECTIONFROMWKB         : 'GEOMETRYCOLLECTIONFROMWKB';\nGEOMETRYFROMTEXT                  : 'GEOMETRYFROMTEXT';\nGEOMETRYFROMWKB                   : 'GEOMETRYFROMWKB';\nGEOMETRYN                         : 'GEOMETRYN';\nGEOMETRYTYPE                      : 'GEOMETRYTYPE';\nGEOMFROMTEXT                      : 'GEOMFROMTEXT';\nGEOMFROMWKB                       : 'GEOMFROMWKB';\nGET_FORMAT                        : 'GET_FORMAT';\nGET_LOCK                          : 'GET_LOCK';\nGLENGTH                           : 'GLENGTH';\nGREATEST                          : 'GREATEST';\nGTID_SUBSET                       : 'GTID_SUBSET';\nGTID_SUBTRACT                     : 'GTID_SUBTRACT';\nHEX                               : 'HEX';\nIFNULL                            : 'IFNULL';\nINET6_ATON                        : 'INET6_ATON';\nINET6_NTOA                        : 'INET6_NTOA';\nINET_ATON                         : 'INET_ATON';\nINET_NTOA                         : 'INET_NTOA';\nINSTR                             : 'INSTR';\nINTERIORRINGN                     : 'INTERIORRINGN';\nINTERSECTS                        : 'INTERSECTS';\nISCLOSED                          : 'ISCLOSED';\nISEMPTY                           : 'ISEMPTY';\nISNULL                            : 'ISNULL';\nISSIMPLE                          : 'ISSIMPLE';\nIS_FREE_LOCK                      : 'IS_FREE_LOCK';\nIS_IPV4                           : 'IS_IPV4';\nIS_IPV4_COMPAT                    : 'IS_IPV4_COMPAT';\nIS_IPV4_MAPPED                    : 'IS_IPV4_MAPPED';\nIS_IPV6                           : 'IS_IPV6';\nIS_USED_LOCK                      : 'IS_USED_LOCK';\nLAST_INSERT_ID                    : 'LAST_INSERT_ID';\nLCASE                             : 'LCASE';\nLEAST                             : 'LEAST';\nLENGTH                            : 'LENGTH';\nLINEFROMTEXT                      : 'LINEFROMTEXT';\nLINEFROMWKB                       : 'LINEFROMWKB';\nLINESTRINGFROMTEXT                : 'LINESTRINGFROMTEXT';\nLINESTRINGFROMWKB                 : 'LINESTRINGFROMWKB';\nLN                                : 'LN';\nLOAD_FILE                         : 'LOAD_FILE';\nLOCATE                            : 'LOCATE';\nLOG                               : 'LOG';\nLOG10                             : 'LOG10';\nLOG2                              : 'LOG2';\nLOWER                             : 'LOWER';\nLPAD                              : 'LPAD';\nLTRIM                             : 'LTRIM';\nMAKEDATE                          : 'MAKEDATE';\nMAKETIME                          : 'MAKETIME';\nMAKE_SET                          : 'MAKE_SET';\nMASTER_POS_WAIT                   : 'MASTER_POS_WAIT';\nMBRCONTAINS                       : 'MBRCONTAINS';\nMBRDISJOINT                       : 'MBRDISJOINT';\nMBREQUAL                          : 'MBREQUAL';\nMBRINTERSECTS                     : 'MBRINTERSECTS';\nMBROVERLAPS                       : 'MBROVERLAPS';\nMBRTOUCHES                        : 'MBRTOUCHES';\nMBRWITHIN                         : 'MBRWITHIN';\nMD5                               : 'MD5';\nMLINEFROMTEXT                     : 'MLINEFROMTEXT';\nMLINEFROMWKB                      : 'MLINEFROMWKB';\nMONTHNAME                         : 'MONTHNAME';\nMPOINTFROMTEXT                    : 'MPOINTFROMTEXT';\nMPOINTFROMWKB                     : 'MPOINTFROMWKB';\nMPOLYFROMTEXT                     : 'MPOLYFROMTEXT';\nMPOLYFROMWKB                      : 'MPOLYFROMWKB';\nMULTILINESTRINGFROMTEXT           : 'MULTILINESTRINGFROMTEXT';\nMULTILINESTRINGFROMWKB            : 'MULTILINESTRINGFROMWKB';\nMULTIPOINTFROMTEXT                : 'MULTIPOINTFROMTEXT';\nMULTIPOINTFROMWKB                 : 'MULTIPOINTFROMWKB';\nMULTIPOLYGONFROMTEXT              : 'MULTIPOLYGONFROMTEXT';\nMULTIPOLYGONFROMWKB               : 'MULTIPOLYGONFROMWKB';\nNAME_CONST                        : 'NAME_CONST';\nNULLIF                            : 'NULLIF';\nNUMGEOMETRIES                     : 'NUMGEOMETRIES';\nNUMINTERIORRINGS                  : 'NUMINTERIORRINGS';\nNUMPOINTS                         : 'NUMPOINTS';\nOCT                               : 'OCT';\nOCTET_LENGTH                      : 'OCTET_LENGTH';\nORD                               : 'ORD';\nOVERLAPS                          : 'OVERLAPS';\nPERCONA_SEQUENCE_TABLE            : 'PERCONA_SEQUENCE_TABLE';\nPERIOD_ADD                        : 'PERIOD_ADD';\nPERIOD_DIFF                       : 'PERIOD_DIFF';\nPI                                : 'PI';\nPOINTFROMTEXT                     : 'POINTFROMTEXT';\nPOINTFROMWKB                      : 'POINTFROMWKB';\nPOINTN                            : 'POINTN';\nPOLYFROMTEXT                      : 'POLYFROMTEXT';\nPOLYFROMWKB                       : 'POLYFROMWKB';\nPOLYGONFROMTEXT                   : 'POLYGONFROMTEXT';\nPOLYGONFROMWKB                    : 'POLYGONFROMWKB';\nPOW                               : 'POW';\nPOWER                             : 'POWER';\nQUOTE                             : 'QUOTE';\nRADIANS                           : 'RADIANS';\nRAND                              : 'RAND';\nRANDOM                            : 'RANDOM';\nRANDOM_BYTES                      : 'RANDOM_BYTES';\nRELEASE_LOCK                      : 'RELEASE_LOCK';\nREVERSE                           : 'REVERSE';\nROUND                             : 'ROUND';\nROW_COUNT                         : 'ROW_COUNT';\nRPAD                              : 'RPAD';\nRTRIM                             : 'RTRIM';\nSEC_TO_TIME                       : 'SEC_TO_TIME';\nSECONDARY_ENGINE                  : 'SECONDARY_ENGINE';\nSECONDARY_ENGINE_ATTRIBUTE        : 'SECONDARY_ENGINE_ATTRIBUTE';\nSEQUENCE_TABLE                    : 'SEQUENCE_TABLE';\nSESSION_USER                      : 'SESSION_USER';\nSHA                               : 'SHA';\nSHA1                              : 'SHA1';\nSHA2                              : 'SHA2';\nSCHEMA_NAME                       : 'SCHEMA_NAME';\nSIGN                              : 'SIGN';\nSIN                               : 'SIN';\nSLEEP                             : 'SLEEP';\nSOUNDEX                           : 'SOUNDEX';\nSQL_THREAD_WAIT_AFTER_GTIDS       : 'SQL_THREAD_WAIT_AFTER_GTIDS';\nSQRT                              : 'SQRT';\nSRID                              : 'SRID';\nSTARTPOINT                        : 'STARTPOINT';\nSTRCMP                            : 'STRCMP';\nSTR_TO_DATE                       : 'STR_TO_DATE';\nST_AREA                           : 'ST_AREA';\nST_ASBINARY                       : 'ST_ASBINARY';\nST_ASTEXT                         : 'ST_ASTEXT';\nST_ASWKB                          : 'ST_ASWKB';\nST_ASWKT                          : 'ST_ASWKT';\nST_BUFFER                         : 'ST_BUFFER';\nST_CENTROID                       : 'ST_CENTROID';\nST_CONTAINS                       : 'ST_CONTAINS';\nST_CROSSES                        : 'ST_CROSSES';\nST_DIFFERENCE                     : 'ST_DIFFERENCE';\nST_DIMENSION                      : 'ST_DIMENSION';\nST_DISJOINT                       : 'ST_DISJOINT';\nST_DISTANCE                       : 'ST_DISTANCE';\nST_ENDPOINT                       : 'ST_ENDPOINT';\nST_ENVELOPE                       : 'ST_ENVELOPE';\nST_EQUALS                         : 'ST_EQUALS';\nST_EXTERIORRING                   : 'ST_EXTERIORRING';\nST_GEOMCOLLFROMTEXT               : 'ST_GEOMCOLLFROMTEXT';\nST_GEOMCOLLFROMTXT                : 'ST_GEOMCOLLFROMTXT';\nST_GEOMCOLLFROMWKB                : 'ST_GEOMCOLLFROMWKB';\nST_GEOMETRYCOLLECTIONFROMTEXT     : 'ST_GEOMETRYCOLLECTIONFROMTEXT';\nST_GEOMETRYCOLLECTIONFROMWKB      : 'ST_GEOMETRYCOLLECTIONFROMWKB';\nST_GEOMETRYFROMTEXT               : 'ST_GEOMETRYFROMTEXT';\nST_GEOMETRYFROMWKB                : 'ST_GEOMETRYFROMWKB';\nST_GEOMETRYN                      : 'ST_GEOMETRYN';\nST_GEOMETRYTYPE                   : 'ST_GEOMETRYTYPE';\nST_GEOMFROMTEXT                   : 'ST_GEOMFROMTEXT';\nST_GEOMFROMWKB                    : 'ST_GEOMFROMWKB';\nST_INTERIORRINGN                  : 'ST_INTERIORRINGN';\nST_INTERSECTION                   : 'ST_INTERSECTION';\nST_INTERSECTS                     : 'ST_INTERSECTS';\nST_ISCLOSED                       : 'ST_ISCLOSED';\nST_ISEMPTY                        : 'ST_ISEMPTY';\nST_ISSIMPLE                       : 'ST_ISSIMPLE';\nST_LINEFROMTEXT                   : 'ST_LINEFROMTEXT';\nST_LINEFROMWKB                    : 'ST_LINEFROMWKB';\nST_LINESTRINGFROMTEXT             : 'ST_LINESTRINGFROMTEXT';\nST_LINESTRINGFROMWKB              : 'ST_LINESTRINGFROMWKB';\nST_NUMGEOMETRIES                  : 'ST_NUMGEOMETRIES';\nST_NUMINTERIORRING                : 'ST_NUMINTERIORRING';\nST_NUMINTERIORRINGS               : 'ST_NUMINTERIORRINGS';\nST_NUMPOINTS                      : 'ST_NUMPOINTS';\nST_OVERLAPS                       : 'ST_OVERLAPS';\nST_POINTFROMTEXT                  : 'ST_POINTFROMTEXT';\nST_POINTFROMWKB                   : 'ST_POINTFROMWKB';\nST_POINTN                         : 'ST_POINTN';\nST_POLYFROMTEXT                   : 'ST_POLYFROMTEXT';\nST_POLYFROMWKB                    : 'ST_POLYFROMWKB';\nST_POLYGONFROMTEXT                : 'ST_POLYGONFROMTEXT';\nST_POLYGONFROMWKB                 : 'ST_POLYGONFROMWKB';\nST_SRID                           : 'ST_SRID';\nST_STARTPOINT                     : 'ST_STARTPOINT';\nST_SYMDIFFERENCE                  : 'ST_SYMDIFFERENCE';\nST_TOUCHES                        : 'ST_TOUCHES';\nST_UNION                          : 'ST_UNION';\nST_WITHIN                         : 'ST_WITHIN';\nST_X                              : 'ST_X';\nST_Y                              : 'ST_Y';\nSTRING_TO_VECTOR                  : 'STRING_TO_VECTOR';\nSUBDATE                           : 'SUBDATE';\nSUBSTRING_INDEX                   : 'SUBSTRING_INDEX';\nSUBTIME                           : 'SUBTIME';\nSYSTEM_USER                       : 'SYSTEM_USER';\nTAN                               : 'TAN';\nTELEMETRY_LOG_ADMIN               : 'TELEMETRY_LOG_ADMIN';\nTIMEDIFF                          : 'TIMEDIFF';\nTIMESTAMPADD                      : 'TIMESTAMPADD';\nTIMESTAMPDIFF                     : 'TIMESTAMPDIFF';\nTIME_FORMAT                       : 'TIME_FORMAT';\nTIME_TO_SEC                       : 'TIME_TO_SEC';\nTOUCHES                           : 'TOUCHES';\nTO_BASE64                         : 'TO_BASE64';\nTO_DAYS                           : 'TO_DAYS';\nTO_SECONDS                        : 'TO_SECONDS';\nTP_CONNECTION_ADMIN               : 'TP_CONNECTION_ADMIN';\nUCASE                             : 'UCASE';\nUNCOMPRESS                        : 'UNCOMPRESS';\nUNCOMPRESSED_LENGTH               : 'UNCOMPRESSED_LENGTH';\nUNHEX                             : 'UNHEX';\nUNIX_TIMESTAMP                    : 'UNIX_TIMESTAMP';\nUPDATEXML                         : 'UPDATEXML';\nUPPER                             : 'UPPER';\nUUID                              : 'UUID';\nUUID_SHORT                        : 'UUID_SHORT';\nVALIDATE_PASSWORD_STRENGTH        : 'VALIDATE_PASSWORD_STRENGTH';\nVECTOR_DIM                        : 'VECTOR_DIM';\nVECTOR_TO_STRING                  : 'VECTOR_TO_STRING';\nVERSION                           : 'VERSION';\nWAIT_UNTIL_SQL_THREAD_AFTER_GTIDS : 'WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS';\nWEEKDAY                           : 'WEEKDAY';\nWEEKOFYEAR                        : 'WEEKOFYEAR';\nWEIGHT_STRING                     : 'WEIGHT_STRING';\nWITHIN                            : 'WITHIN';\nYEARWEEK                          : 'YEARWEEK';\nY_FUNCTION                        : 'Y';\nX_FUNCTION                        : 'X';\n\n// Operators\n// Operators. Assigns\n\nVAR_ASSIGN   : ':=';\nPLUS_ASSIGN  : '+=';\nMINUS_ASSIGN : '-=';\nMULT_ASSIGN  : '*=';\nDIV_ASSIGN   : '/=';\nMOD_ASSIGN   : '%=';\nAND_ASSIGN   : '&=';\nXOR_ASSIGN   : '^=';\nOR_ASSIGN    : '|=';\n\n// Operators. Arithmetics\n\nSTAR   : '*';\nDIVIDE : '/';\nMODULE : '%';\nPLUS   : '+';\nMINUS  : '-';\nDIV    : 'DIV';\nMOD    : 'MOD';\n\n// Operators. Comparation\n\nEQUAL_SYMBOL       : '=';\nGREATER_SYMBOL     : '>';\nLESS_SYMBOL        : '<';\nEXCLAMATION_SYMBOL : '!';\n\n// Operators. Bit\n\nBIT_NOT_OP : '~';\nBIT_OR_OP  : '|';\nBIT_AND_OP : '&';\nBIT_XOR_OP : '^';\n\n// Constructors symbols\n\nDOT                : '.';\nLR_BRACKET         : '(';\nRR_BRACKET         : ')';\nCOMMA              : ',';\nSEMI               : ';';\nAT_SIGN            : '@';\nZERO_DECIMAL       : '0';\nONE_DECIMAL        : '1';\nTWO_DECIMAL        : '2';\nSINGLE_QUOTE_SYMB  : '\\'';\nDOUBLE_QUOTE_SYMB  : '\"';\nREVERSE_QUOTE_SYMB : '`';\nCOLON_SYMB         : ':';\n\nfragment QUOTE_SYMB: SINGLE_QUOTE_SYMB | DOUBLE_QUOTE_SYMB | REVERSE_QUOTE_SYMB;\n\n// Charsets\n\nCHARSET_REVERSE_QOUTE_STRING: '`' CHARSET_NAME '`';\n\n// File's sizes\n\nFILESIZE_LITERAL: DEC_DIGIT+ ('K' | 'M' | 'G' | 'T');\n\n// Literal Primitives\n\nSTART_NATIONAL_STRING_LITERAL : 'N' SQUOTA_STRING;\nSTRING_LITERAL                : DQUOTA_STRING | SQUOTA_STRING | BQUOTA_STRING;\nDECIMAL_LITERAL               : DEC_DIGIT+;\nHEXADECIMAL_LITERAL           : 'X' '\\'' (HEX_DIGIT HEX_DIGIT)+ '\\'' | '0X' HEX_DIGIT+;\n\nREAL_LITERAL:\n    (DEC_DIGIT+)? '.' DEC_DIGIT*\n    | DEC_DIGIT+ '.' EXPONENT_NUM_PART\n    | (DEC_DIGIT+)? '.' (DEC_DIGIT+ EXPONENT_NUM_PART)\n    | DEC_DIGIT+ EXPONENT_NUM_PART\n;\nNULL_SPEC_LITERAL   : '\\\\' 'N';\nBIT_STRING          : BIT_STRING_L;\nSTRING_CHARSET_NAME : '_' CHARSET_NAME;\n\n// Hack for dotID\n// Prevent recognize string:         .123somelatin AS ((.123), FLOAT_LITERAL), ((somelatin), ID)\n//  it must recoginze:               .123somelatin AS ((.), DOT), (123somelatin, ID)\n\nDOT_ID: '.' ID_LITERAL;\n\n// Identifiers\n\nID: ID_LITERAL;\n// DOUBLE_QUOTE_ID:                  '\"' ~'\"'+ '\"';\nREVERSE_QUOTE_ID : BQUOTA_STRING;\nHOST_IP_ADDRESS  : (AT_SIGN IP_ADDRESS);\nLOCAL_ID         : AT_SIGN ( STRING_LITERAL | [A-Z0-9._$\\u0080-\\uFFFF]+);\nGLOBAL_ID        : AT_SIGN AT_SIGN ( [A-Z0-9._$\\u0080-\\uFFFF]+ | BQUOTA_STRING);\n\n// Fragments for Literal primitives\n\nfragment CHARSET_NAME:\n    ARMSCII8\n    | ASCII\n    | BIG5\n    | BINARY\n    | CP1250\n    | CP1251\n    | CP1256\n    | CP1257\n    | CP850\n    | CP852\n    | CP866\n    | CP932\n    | DEC8\n    | EUCJPMS\n    | EUCKR\n    | GB2312\n    | GBK\n    | GEOSTD8\n    | GREEK\n    | HEBREW\n    | HP8\n    | KEYBCS2\n    | KOI8R\n    | KOI8U\n    | LATIN1\n    | LATIN2\n    | LATIN5\n    | LATIN7\n    | MACCE\n    | MACROMAN\n    | SJIS\n    | SWE7\n    | TIS620\n    | UCS2\n    | UJIS\n    | UTF16\n    | UTF16LE\n    | UTF32\n    | UTF8\n    | UTF8MB3\n    | UTF8MB4\n;\n\nfragment EXPONENT_NUM_PART : 'E' [-+]? DEC_DIGIT+;\nfragment ID_LITERAL        : [A-Z_$0-9\\u0080-\\uFFFF]*? [A-Z_$\\u0080-\\uFFFF]+? [A-Z_$0-9\\u0080-\\uFFFF]*;\nfragment DQUOTA_STRING     : '\"' ( '\\\\' . | '\"\"' | ~('\"' | '\\\\'))* '\"';\nfragment SQUOTA_STRING     : '\\'' ('\\\\' . | '\\'\\'' | ~('\\'' | '\\\\'))* '\\'';\nfragment BQUOTA_STRING     : '`' ( ~'`' | '``')* '`';\nfragment HEX_DIGIT         : [0-9A-F];\nfragment DEC_DIGIT         : [0-9];\nfragment BIT_STRING_L      : 'B' '\\'' [01]+ '\\'';\nfragment IP_ADDRESS        : [0-9]+ '.' [0-9.]+ | [0-9A-F]* ':' [0-9A-F]* ':' [0-9A-F:]+;\n\n// Last tokens must generate Errors\n\nERROR_RECONGNIGION: . -> channel(ERRORCHANNEL);\n"
  },
  {
    "path": "superior-mysql-parser/src/main/antlr4/io/github/melin/superior/parser/mysql/antlr4/MySqlParser.g4",
    "content": "/*\nMySQL (Positive Technologies) grammar\nThe MIT License (MIT).\nCopyright (c) 2015-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies.\nCopyright (c) 2017, Ivan Khudyashev (IHudyashov@ptsecurity.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n*/\n\n// $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false\n// $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging\n\nparser grammar MySqlParser;\n\noptions {\n    tokenVocab = MySqlLexer;\n}\n\n// Top Level Description\n\nroot\n    : sqlStatements? (MINUS MINUS)? EOF\n    ;\n\nsqlStatements\n    : (sqlStatement (MINUS MINUS)? SEMI? | emptyStatement_)* (\n        sqlStatement ((MINUS MINUS)? SEMI)?\n        | emptyStatement_\n    )\n    ;\n\nsqlStatement\n    : ddlStatement\n    | withStatement? dmlStatement\n    | transactionStatement\n    | replicationStatement\n    | preparedStatement\n    | administrationStatement\n    | utilityStatement\n    ;\n\nemptyStatement_\n    : SEMI\n    ;\n\nddlStatement\n    : createDatabase\n    | createEvent\n    | createIndex\n    | createLogfileGroup\n    | createProcedure\n    | createFunction\n    | createServer\n    | createTable\n    | createTablespaceInnodb\n    | createTablespaceNdb\n    | createTrigger\n    | createView\n    | createRole\n    | alterDatabase\n    | alterEvent\n    | alterFunction\n    | alterInstance\n    | alterLogfileGroup\n    | alterProcedure\n    | alterServer\n    | alterTable\n    | alterTablespace\n    | alterView\n    | dropDatabase\n    | dropEvent\n    | dropIndex\n    | dropLogfileGroup\n    | dropProcedure\n    | dropFunction\n    | dropServer\n    | dropTable\n    | dropTablespace\n    | dropTrigger\n    | dropView\n    | dropRole\n    | setRole\n    | renameTable\n    | truncateTable\n    ;\n\ndmlStatement\n    : selectStatement\n    | insertStatement\n    | updateStatement\n    | deleteStatement\n    | replaceStatement\n    | callStatement\n    | loadDataStatement\n    | loadXmlStatement\n    | doStatement\n    | handlerStatement\n    | valuesStatement\n    | tableStatement\n    ;\n\ntransactionStatement\n    : startTransaction\n    | beginWork\n    | commitWork\n    | rollbackWork\n    | savepointStatement\n    | rollbackStatement\n    | releaseStatement\n    | lockTables\n    | unlockTables\n    ;\n\nreplicationStatement\n    : changeMaster\n    | changeReplicationFilter\n    | purgeBinaryLogs\n    | resetMaster\n    | resetSlave\n    | startSlave\n    | stopSlave\n    | startGroupReplication\n    | stopGroupReplication\n    | xaStartTransaction\n    | xaEndTransaction\n    | xaPrepareStatement\n    | xaCommitWork\n    | xaRollbackWork\n    | xaRecoverWork\n    ;\n\npreparedStatement\n    : prepareStatement\n    | executeStatement\n    | deallocatePrepare\n    ;\n\n// remark: NOT INCLUDED IN sqlStatement, but include in body\n//  of routine's statements\ncompoundStatement\n    : blockStatement\n    | caseStatement\n    | ifStatement\n    | leaveStatement\n    | loopStatement\n    | repeatStatement\n    | whileStatement\n    | iterateStatement\n    | returnStatement\n    | cursorStatement\n    ;\n\nadministrationStatement\n    : alterUser\n    | createUser\n    | dropUser\n    | grantStatement\n    | grantProxy\n    | renameUser\n    | revokeStatement\n    | revokeProxy\n    | analyzeTable\n    | checkTable\n    | checksumTable\n    | optimizeTable\n    | repairTable\n    | createUdfunction\n    | installPlugin\n    | uninstallPlugin\n    | setStatement\n    | showStatement\n    | binlogStatement\n    | cacheIndexStatement\n    | flushStatement\n    | killStatement\n    | loadIndexIntoCache\n    | resetStatement\n    | shutdownStatement\n    ;\n\nutilityStatement\n    : simpleDescribeStatement\n    | fullDescribeStatement\n    | helpStatement\n    | useStatement\n    | signalStatement\n    | resignalStatement\n    | diagnosticsStatement\n    ;\n\n// Data Definition Language\n\n//    Create statements\n\ncreateDatabase\n    : CREATE dbFormat = (DATABASE | SCHEMA) ifNotExists? uid createDatabaseOption*\n    ;\n\ncreateEvent\n    : CREATE ownerStatement? EVENT ifNotExists? fullId ON SCHEDULE scheduleExpression (\n        ON COMPLETION NOT? PRESERVE\n    )? enableType? (COMMENT STRING_LITERAL)? DO routineBody\n    ;\n\ncreateIndex\n    : CREATE intimeAction = (ONLINE | OFFLINE)? indexCategory = (UNIQUE | FULLTEXT | SPATIAL)? INDEX uid indexType? ON tableName indexColumnNames\n        indexOption* (\n        ALGORITHM EQUAL_SYMBOL? algType = (DEFAULT | INPLACE | COPY)\n        | LOCK EQUAL_SYMBOL? lockType = (DEFAULT | NONE | SHARED | EXCLUSIVE)\n    )*\n    ;\n\ncreateLogfileGroup\n    : CREATE LOGFILE GROUP uid ADD UNDOFILE undoFile = STRING_LITERAL (\n        INITIAL_SIZE '='? initSize = fileSizeLiteral\n    )? (UNDO_BUFFER_SIZE '='? undoSize = fileSizeLiteral)? (\n        REDO_BUFFER_SIZE '='? redoSize = fileSizeLiteral\n    )? (NODEGROUP '='? uid)? WAIT? (COMMENT '='? comment = STRING_LITERAL)? ENGINE '='? engineName\n    ;\n\ncreateProcedure\n    : CREATE ownerStatement? PROCEDURE ifNotExists? fullId '(' procedureParameter? (',' procedureParameter)* ')' routineOption* routineBody\n    ;\n\ncreateFunction\n    : CREATE ownerStatement? AGGREGATE? FUNCTION ifNotExists? fullId '(' functionParameter? (\n        ',' functionParameter\n    )* ')' RETURNS dataType routineOption* (routineBody | returnStatement)\n    ;\n\ncreateRole\n    : CREATE ROLE ifNotExists? roleName (',' roleName)*\n    ;\n\ncreateServer\n    : CREATE SERVER uid FOREIGN DATA WRAPPER wrapperName = (MYSQL | STRING_LITERAL) OPTIONS '(' serverOption (\n        ',' serverOption\n    )* ')'\n    ;\n\ncreateTable\n    : CREATE TEMPORARY? TABLE ifNotExists? tableName (\n        LIKE tableName\n        | '(' LIKE parenthesisTable = tableName ')'\n    ) # copyCreateTable\n    | CREATE TEMPORARY? TABLE ifNotExists? tableName createDefinitions? (\n        tableOption (','? tableOption)*\n    )? partitionDefinitions? keyViolate = (IGNORE | REPLACE)? AS? selectStatement # queryCreateTable\n    | CREATE TEMPORARY? TABLE ifNotExists? tableName createDefinitions (\n        tableOption (','? tableOption)*\n    )? partitionDefinitions? # columnCreateTable\n    ;\n\ncreateTablespaceInnodb\n    : CREATE TABLESPACE uid ADD DATAFILE datafile = STRING_LITERAL (\n        FILE_BLOCK_SIZE '=' fileBlockSize = fileSizeLiteral\n    )? (ENGINE '='? engineName)?\n    ;\n\ncreateTablespaceNdb\n    : CREATE TABLESPACE uid ADD DATAFILE datafile = STRING_LITERAL USE LOGFILE GROUP uid (\n        EXTENT_SIZE '='? extentSize = fileSizeLiteral\n    )? (INITIAL_SIZE '='? initialSize = fileSizeLiteral)? (\n        AUTOEXTEND_SIZE '='? autoextendSize = fileSizeLiteral\n    )? (MAX_SIZE '='? maxSize = fileSizeLiteral)? (NODEGROUP '='? uid)? WAIT? (\n        COMMENT '='? comment = STRING_LITERAL\n    )? ENGINE '='? engineName\n    ;\n\ncreateTrigger\n    : CREATE ownerStatement? TRIGGER ifNotExists? thisTrigger = fullId triggerTime = (\n        BEFORE\n        | AFTER\n    ) triggerEvent = (INSERT | UPDATE | DELETE) ON tableName FOR EACH ROW (\n        triggerPlace = (FOLLOWS | PRECEDES) otherTrigger = fullId\n    )? routineBody\n    ;\n\nwithClause\n    : WITH RECURSIVE? commonTableExpressions\n    ;\n\ncommonTableExpressions\n    : cteName ('(' cteColumnName (',' cteColumnName)* ')')? AS '(' dmlStatement ')' (\n        ',' commonTableExpressions\n    )?\n    ;\n\ncteName\n    : uid\n    ;\n\ncteColumnName\n    : uid\n    ;\n\ncreateView\n    : CREATE orReplace? (ALGORITHM '=' algType = (UNDEFINED | MERGE | TEMPTABLE))? ownerStatement? (\n        SQL SECURITY secContext = (DEFINER | INVOKER)\n    )? VIEW fullId ('(' uidList ')')? AS (\n        '(' withClause? selectStatement ')'\n        | withClause? selectStatement (WITH checkOption = (CASCADED | LOCAL)? CHECK OPTION)?\n    )\n    ;\n\n// details\n\ncreateDatabaseOption\n    : DEFAULT? charSet '='? (charsetName | DEFAULT)\n    | DEFAULT? COLLATE '='? collationName\n    | DEFAULT? ENCRYPTION '='? STRING_LITERAL\n    | READ ONLY '='? (DEFAULT | ZERO_DECIMAL | ONE_DECIMAL)\n    ;\n\ncharSet\n    : CHARACTER SET\n    | CHARSET\n    | CHAR SET\n    ;\n\ncurrentUserExpression\n    : CURRENT_USER ('(' ')')?\n    ;\n\nownerStatement\n    : DEFINER '=' (userName | currentUserExpression)\n    ;\n\nscheduleExpression\n    : AT timestampValue intervalExpr* # preciseSchedule\n    | EVERY (decimalLiteral | expression) intervalType (\n        STARTS startTimestamp = timestampValue (startIntervals += intervalExpr)*\n    )? (ENDS endTimestamp = timestampValue (endIntervals += intervalExpr)*)? # intervalSchedule\n    ;\n\ntimestampValue\n    : CURRENT_TIMESTAMP\n    | stringLiteral\n    | decimalLiteral\n    | expression\n    ;\n\nintervalExpr\n    : '+' INTERVAL (decimalLiteral | expression) intervalType\n    ;\n\nintervalType\n    : intervalTypeBase\n    | YEAR\n    | YEAR_MONTH\n    | DAY_HOUR\n    | DAY_MINUTE\n    | DAY_SECOND\n    | HOUR_MINUTE\n    | HOUR_SECOND\n    | MINUTE_SECOND\n    | SECOND_MICROSECOND\n    | MINUTE_MICROSECOND\n    | HOUR_MICROSECOND\n    | DAY_MICROSECOND\n    ;\n\nenableType\n    : ENABLE\n    | DISABLE\n    | DISABLE ON SLAVE\n    ;\n\nindexType\n    : USING (BTREE | HASH)\n    ;\n\nindexOption\n    : KEY_BLOCK_SIZE EQUAL_SYMBOL? fileSizeLiteral\n    | indexType\n    | WITH PARSER uid\n    | COMMENT STRING_LITERAL\n    | (VISIBLE | INVISIBLE)\n    | ENGINE_ATTRIBUTE EQUAL_SYMBOL? STRING_LITERAL\n    | SECONDARY_ENGINE_ATTRIBUTE EQUAL_SYMBOL? STRING_LITERAL\n    ;\n\nprocedureParameter\n    : direction = (IN | OUT | INOUT)? uid dataType\n    ;\n\nfunctionParameter\n    : uid dataType\n    ;\n\nroutineOption\n    : COMMENT STRING_LITERAL                                        # routineComment\n    | LANGUAGE SQL                                                  # routineLanguage\n    | NOT? DETERMINISTIC                                            # routineBehavior\n    | ( CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA) # routineData\n    | SQL SECURITY context = (DEFINER | INVOKER)                    # routineSecurity\n    ;\n\nserverOption\n    : HOST STRING_LITERAL\n    | DATABASE STRING_LITERAL\n    | USER STRING_LITERAL\n    | PASSWORD STRING_LITERAL\n    | SOCKET STRING_LITERAL\n    | OWNER STRING_LITERAL\n    | PORT decimalLiteral\n    ;\n\ncreateDefinitions\n    : '(' createDefinition (',' createDefinition)* ')'\n    ;\n\ncreateDefinition\n    : fullColumnName columnDefinition # columnDeclaration\n    | tableConstraint NOT? ENFORCED?  # constraintDeclaration\n    | indexColumnDefinition           # indexDeclaration\n    ;\n\ncolumnDefinition\n    : dataType columnConstraint* NOT? ENFORCED?\n    ;\n\ncolumnConstraint\n    : nullNotnull                                                   # nullColumnConstraint\n    | DEFAULT defaultValue                                          # defaultColumnConstraint\n    | VISIBLE                                                       # visibilityColumnConstraint\n    | INVISIBLE                                                     # invisibilityColumnConstraint\n    | (AUTO_INCREMENT | ON UPDATE currentTimestamp)                 # autoIncrementColumnConstraint\n    | PRIMARY? KEY                                                  # primaryKeyColumnConstraint\n    | CLUSTERING KEY                                                # clusteringKeyColumnConstraint // Tokudb-specific only\n    | UNIQUE KEY?                                                   # uniqueKeyColumnConstraint\n    | COMMENT STRING_LITERAL                                        # commentColumnConstraint\n    | COLUMN_FORMAT colformat = (FIXED | DYNAMIC | DEFAULT)         # formatColumnConstraint\n    | STORAGE storageval = (DISK | MEMORY | DEFAULT)                # storageColumnConstraint\n    | referenceDefinition                                           # referenceColumnConstraint\n    | COLLATE collationName                                         # collateColumnConstraint\n    | (GENERATED ALWAYS)? AS '(' expression ')' (VIRTUAL | STORED)? # generatedColumnConstraint\n    | SERIAL DEFAULT VALUE                                          # serialDefaultColumnConstraint\n    | (CONSTRAINT name = uid?)? CHECK '(' expression ')'            # checkColumnConstraint\n    ;\n\ntableConstraint\n    : (CONSTRAINT name = uid?)? PRIMARY KEY index = uid? indexType? indexColumnNames indexOption*                         # primaryKeyTableConstraint\n    | (CONSTRAINT name = uid?)? UNIQUE indexFormat = (INDEX | KEY)? index = uid? indexType? indexColumnNames indexOption* # uniqueKeyTableConstraint\n    | (CONSTRAINT name = uid?)? FOREIGN KEY index = uid? indexColumnNames referenceDefinition                             # foreignKeyTableConstraint\n    | (CONSTRAINT name = uid?)? CHECK '(' expression ')'                                                                  # checkTableConstraint\n    | CLUSTERING KEY index = uid? indexColumnNames                                                                        # clusteringKeyTableConstraint\n    // Tokudb-specific only\n    ;\n\nreferenceDefinition\n    : REFERENCES tableName indexColumnNames? (MATCH matchType = (FULL | PARTIAL | SIMPLE))? referenceAction?\n    ;\n\nreferenceAction\n    : ON DELETE onDelete = referenceControlType (ON UPDATE onUpdate = referenceControlType)?\n    | ON UPDATE onUpdate = referenceControlType (ON DELETE onDelete = referenceControlType)?\n    ;\n\nreferenceControlType\n    : RESTRICT\n    | CASCADE\n    | SET NULL_LITERAL\n    | NO ACTION\n    | SET DEFAULT\n    ;\n\nindexColumnDefinition\n    : indexFormat = (INDEX | KEY) uid? indexType? indexColumnNames indexOption*            # simpleIndexDeclaration\n    | (FULLTEXT | SPATIAL) indexFormat = (INDEX | KEY)? uid? indexColumnNames indexOption* # specialIndexDeclaration\n    ;\n\ntableOption\n    : ENGINE '='? engineName?                                       # tableOptionEngine\n    | ENGINE_ATTRIBUTE '='? STRING_LITERAL                          # tableOptionEngineAttribute\n    | AUTOEXTEND_SIZE '='? decimalLiteral                           # tableOptionAutoextendSize\n    | AUTO_INCREMENT '='? decimalLiteral                            # tableOptionAutoIncrement\n    | AVG_ROW_LENGTH '='? decimalLiteral                            # tableOptionAverage\n    | DEFAULT? charSet '='? (charsetName | DEFAULT)                 # tableOptionCharset\n    | (CHECKSUM | PAGE_CHECKSUM) '='? boolValue = ('0' | '1')       # tableOptionChecksum\n    | DEFAULT? COLLATE '='? collationName                           # tableOptionCollate\n    | COMMENT '='? STRING_LITERAL                                   # tableOptionComment\n    | COMPRESSION '='? (STRING_LITERAL | ID)                        # tableOptionCompression\n    | CONNECTION '='? STRING_LITERAL                                # tableOptionConnection\n    | (DATA | INDEX) DIRECTORY '='? STRING_LITERAL                  # tableOptionDataDirectory\n    | DELAY_KEY_WRITE '='? boolValue = ('0' | '1')                  # tableOptionDelay\n    | ENCRYPTION '='? STRING_LITERAL                                # tableOptionEncryption\n    | (PAGE_COMPRESSED | STRING_LITERAL) '='? ('0' | '1')           # tableOptionPageCompressed\n    | (PAGE_COMPRESSION_LEVEL | STRING_LITERAL) '='? decimalLiteral # tableOptionPageCompressionLevel\n    | ENCRYPTION_KEY_ID '='? decimalLiteral                         # tableOptionEncryptionKeyId\n    | INDEX DIRECTORY '='? STRING_LITERAL                           # tableOptionIndexDirectory\n    | INSERT_METHOD '='? insertMethod = (NO | FIRST | LAST)         # tableOptionInsertMethod\n    | KEY_BLOCK_SIZE '='? fileSizeLiteral                           # tableOptionKeyBlockSize\n    | MAX_ROWS '='? decimalLiteral                                  # tableOptionMaxRows\n    | MIN_ROWS '='? decimalLiteral                                  # tableOptionMinRows\n    | PACK_KEYS '='? extBoolValue = ('0' | '1' | DEFAULT)           # tableOptionPackKeys\n    | PASSWORD '='? STRING_LITERAL                                  # tableOptionPassword\n    | ROW_FORMAT '='? rowFormat = (\n        DEFAULT\n        | DYNAMIC\n        | FIXED\n        | COMPRESSED\n        | REDUNDANT\n        | COMPACT\n        | ID\n    )                                                             # tableOptionRowFormat\n    | START TRANSACTION                                           # tableOptionStartTransaction\n    | SECONDARY_ENGINE '='? (ID | STRING_LITERAL)                 # tableOptionSecondaryEngine\n    // HeatWave-specific only\n    | SECONDARY_ENGINE_ATTRIBUTE '='? STRING_LITERAL              # tableOptionSecondaryEngineAttribute\n    | STATS_AUTO_RECALC '='? extBoolValue = (DEFAULT | '0' | '1') # tableOptionRecalculation\n    | STATS_PERSISTENT '='? extBoolValue = (DEFAULT | '0' | '1')  # tableOptionPersistent\n    | STATS_SAMPLE_PAGES '='? (DEFAULT | decimalLiteral)          # tableOptionSamplePage\n    | TABLESPACE uid tablespaceStorage?                           # tableOptionTablespace\n    | TABLE_TYPE '=' tableType                                    # tableOptionTableType\n    | tablespaceStorage                                           # tableOptionTablespace\n    | TRANSACTIONAL '='? ('0' | '1')                              # tableOptionTransactional\n    | UNION '='? '(' tables ')'                                   # tableOptionUnion\n    ;\n\ntableType\n    : MYSQL\n    | ODBC\n    ;\n\ntablespaceStorage\n    : STORAGE (DISK | MEMORY | DEFAULT)\n    ;\n\npartitionDefinitions\n    : PARTITION BY partitionFunctionDefinition (PARTITIONS count = decimalLiteral)? (\n        SUBPARTITION BY subpartitionFunctionDefinition (SUBPARTITIONS subCount = decimalLiteral)?\n    )? ('(' partitionDefinition (',' partitionDefinition)* ')')?\n    ;\n\npartitionFunctionDefinition\n    : LINEAR? HASH '(' expression ')'                                     # partitionFunctionHash\n    | LINEAR? KEY (ALGORITHM '=' algType = ('1' | '2'))? '(' uidList? ')' # partitionFunctionKey // Optional uidList for MySQL only\n    | RANGE ('(' expression ')' | COLUMNS '(' uidList ')')                # partitionFunctionRange\n    | LIST ('(' expression ')' | COLUMNS '(' uidList ')')                 # partitionFunctionList\n    ;\n\nsubpartitionFunctionDefinition\n    : LINEAR? HASH '(' expression ')'                                    # subPartitionFunctionHash\n    | LINEAR? KEY (ALGORITHM '=' algType = ('1' | '2'))? '(' uidList ')' # subPartitionFunctionKey\n    ;\n\npartitionDefinition\n    : PARTITION uid VALUES LESS THAN '(' partitionDefinerAtom (',' partitionDefinerAtom)* ')' partitionOption* (\n        '(' subpartitionDefinition (',' subpartitionDefinition)* ')'\n    )? # partitionComparison\n    | PARTITION uid VALUES LESS THAN partitionDefinerAtom partitionOption* (\n        '(' subpartitionDefinition (',' subpartitionDefinition)* ')'\n    )? # partitionComparison\n    | PARTITION uid VALUES IN '(' partitionDefinerAtom (',' partitionDefinerAtom)* ')' partitionOption* (\n        '(' subpartitionDefinition (',' subpartitionDefinition)* ')'\n    )? # partitionListAtom\n    | PARTITION uid VALUES IN '(' partitionDefinerVector (',' partitionDefinerVector)* ')' partitionOption* (\n        '(' subpartitionDefinition (',' subpartitionDefinition)* ')'\n    )?                                                                                               # partitionListVector\n    | PARTITION uid partitionOption* ('(' subpartitionDefinition (',' subpartitionDefinition)* ')')? # partitionSimple\n    ;\n\npartitionDefinerAtom\n    : constant\n    | expression\n    | MAXVALUE\n    ;\n\npartitionDefinerVector\n    : '(' partitionDefinerAtom (',' partitionDefinerAtom)+ ')'\n    ;\n\nsubpartitionDefinition\n    : SUBPARTITION uid partitionOption*\n    ;\n\npartitionOption\n    : DEFAULT? STORAGE? ENGINE '='? engineName             # partitionOptionEngine\n    | COMMENT '='? comment = STRING_LITERAL                # partitionOptionComment\n    | DATA DIRECTORY '='? dataDirectory = STRING_LITERAL   # partitionOptionDataDirectory\n    | INDEX DIRECTORY '='? indexDirectory = STRING_LITERAL # partitionOptionIndexDirectory\n    | MAX_ROWS '='? maxRows = decimalLiteral               # partitionOptionMaxRows\n    | MIN_ROWS '='? minRows = decimalLiteral               # partitionOptionMinRows\n    | TABLESPACE '='? tablespace = uid                     # partitionOptionTablespace\n    | NODEGROUP '='? nodegroup = uid                       # partitionOptionNodeGroup\n    ;\n\n//    Alter statements\n\nalterDatabase\n    : ALTER dbFormat = (DATABASE | SCHEMA) uid? createDatabaseOption+      # alterSimpleDatabase\n    | ALTER dbFormat = (DATABASE | SCHEMA) uid UPGRADE DATA DIRECTORY NAME # alterUpgradeName\n    ;\n\nalterEvent\n    : ALTER ownerStatement? EVENT fullId (ON SCHEDULE scheduleExpression)? (\n        ON COMPLETION NOT? PRESERVE\n    )? (RENAME TO fullId)? enableType? (COMMENT STRING_LITERAL)? (DO routineBody)?\n    ;\n\nalterFunction\n    : ALTER FUNCTION fullId routineOption*\n    ;\n\nalterInstance\n    : ALTER INSTANCE ROTATE INNODB MASTER KEY\n    ;\n\nalterLogfileGroup\n    : ALTER LOGFILE GROUP uid ADD UNDOFILE STRING_LITERAL (INITIAL_SIZE '='? fileSizeLiteral)? WAIT? ENGINE '='? engineName\n    ;\n\nalterProcedure\n    : ALTER PROCEDURE fullId routineOption*\n    ;\n\nalterServer\n    : ALTER SERVER uid OPTIONS '(' serverOption (',' serverOption)* ')'\n    ;\n\nalterTable\n    : ALTER intimeAction = (ONLINE | OFFLINE)? IGNORE? TABLE tableName (\n        alterSpecification (',' alterSpecification)*\n    )? partitionDefinitions?\n    ;\n\nalterTablespace\n    : ALTER TABLESPACE uid objectAction = (ADD | DROP) DATAFILE STRING_LITERAL (\n        INITIAL_SIZE '=' fileSizeLiteral\n    )? WAIT? ENGINE '='? engineName\n    ;\n\nalterView\n    : ALTER (ALGORITHM '=' algType = (UNDEFINED | MERGE | TEMPTABLE))? ownerStatement? (\n        SQL SECURITY secContext = (DEFINER | INVOKER)\n    )? VIEW fullId ('(' uidList ')')? AS selectStatement (\n        WITH checkOpt = (CASCADED | LOCAL)? CHECK OPTION\n    )?\n    ;\n\n// details\n\nalterSpecification\n    : tableOption (','? tableOption)*                                                                                             # alterByTableOption\n    | ADD COLUMN? uid columnDefinition (FIRST | AFTER uid)?                                                                       # alterByAddColumn\n    | ADD COLUMN? '(' uid columnDefinition (',' uid columnDefinition)* ')'                                                        # alterByAddColumns\n    | ADD indexFormat = (INDEX | KEY) uid? indexType? indexColumnNames indexOption*                                               # alterByAddIndex\n    | ADD (CONSTRAINT name = uid?)? PRIMARY KEY index = uid? indexType? indexColumnNames indexOption*                             # alterByAddPrimaryKey\n    | ADD (CONSTRAINT name = uid?)? UNIQUE indexFormat = (INDEX | KEY)? indexName = uid? indexType? indexColumnNames indexOption* # alterByAddUniqueKey\n    | ADD keyType = (FULLTEXT | SPATIAL) indexFormat = (INDEX | KEY)? uid? indexColumnNames indexOption*                          # alterByAddSpecialIndex\n    | ADD (CONSTRAINT name = uid?)? FOREIGN KEY indexName = uid? indexColumnNames referenceDefinition                             # alterByAddForeignKey\n    | ADD (CONSTRAINT name = uid?)? CHECK (uid | stringLiteral | '(' expression ')') NOT? ENFORCED?                               # alterByAddCheckTableConstraint\n    | ALTER (CONSTRAINT name = uid?)? CHECK (uid | stringLiteral | '(' expression ')') NOT? ENFORCED?                             # alterByAlterCheckTableConstraint\n    | ADD (CONSTRAINT name = uid?)? CHECK '(' expression ')'                                                                      # alterByAddCheckTableConstraint\n    | ALGORITHM '='? algType = (DEFAULT | INSTANT | INPLACE | COPY)                                                               # alterBySetAlgorithm\n    | ALTER COLUMN? uid (SET DEFAULT defaultValue | DROP DEFAULT)                                                                 # alterByChangeDefault\n    | CHANGE COLUMN? oldColumn = uid newColumn = uid columnDefinition (\n        FIRST\n        | AFTER afterColumn = uid\n    )?                                                           # alterByChangeColumn\n    | RENAME COLUMN oldColumn = uid TO newColumn = uid           # alterByRenameColumn\n    | LOCK '='? lockType = (DEFAULT | NONE | SHARED | EXCLUSIVE) # alterByLock\n    | MODIFY COLUMN? uid columnDefinition (FIRST | AFTER uid)?   # alterByModifyColumn\n    | DROP COLUMN? uid RESTRICT?                                 # alterByDropColumn\n    | DROP (CONSTRAINT | CHECK) uid                              # alterByDropConstraintCheck\n    | DROP PRIMARY KEY                                           # alterByDropPrimaryKey\n    | DROP indexFormat = (INDEX | KEY) uid                       # alterByDropIndex\n    | RENAME indexFormat = (INDEX | KEY) uid TO uid              # alterByRenameIndex\n    | ALTER COLUMN? uid (\n        SET DEFAULT ( stringLiteral | '(' expression ')')\n        | SET (VISIBLE | INVISIBLE)\n        | DROP DEFAULT\n    )                                                                           # alterByAlterColumnDefault\n    | ALTER INDEX uid (VISIBLE | INVISIBLE)                                     # alterByAlterIndexVisibility\n    | DROP FOREIGN KEY uid dottedId?                                            # alterByDropForeignKey\n    | DISABLE KEYS                                                              # alterByDisableKeys\n    | ENABLE KEYS                                                               # alterByEnableKeys\n    | RENAME renameFormat = (TO | AS)? (uid | fullId)                           # alterByRename\n    | ORDER BY uidList                                                          # alterByOrder\n    | CONVERT TO (CHARSET | CHARACTER SET) charsetName (COLLATE collationName)? # alterByConvertCharset\n    | DEFAULT? CHARACTER SET '=' charsetName (COLLATE '=' collationName)?       # alterByDefaultCharset\n    | DISCARD TABLESPACE                                                        # alterByDiscardTablespace\n    | IMPORT TABLESPACE                                                         # alterByImportTablespace\n    | FORCE                                                                     # alterByForce\n    | validationFormat = (WITHOUT | WITH) VALIDATION                            # alterByValidate\n    | ADD COLUMN? '(' createDefinition (',' createDefinition)* ')'              # alterByAddDefinitions\n    | alterPartitionSpecification                                               # alterPartition\n    ;\n\nalterPartitionSpecification\n    : ADD PARTITION '(' partitionDefinition (',' partitionDefinition)* ')'                          # alterByAddPartition\n    | DROP PARTITION uidList                                                                        # alterByDropPartition\n    | DISCARD PARTITION (uidList | ALL) TABLESPACE                                                  # alterByDiscardPartition\n    | IMPORT PARTITION (uidList | ALL) TABLESPACE                                                   # alterByImportPartition\n    | TRUNCATE PARTITION (uidList | ALL)                                                            # alterByTruncatePartition\n    | COALESCE PARTITION decimalLiteral                                                             # alterByCoalescePartition\n    | REORGANIZE PARTITION uidList INTO '(' partitionDefinition (',' partitionDefinition)* ')'      # alterByReorganizePartition\n    | EXCHANGE PARTITION uid WITH TABLE tableName (validationFormat = (WITH | WITHOUT) VALIDATION)? # alterByExchangePartition\n    | ANALYZE PARTITION (uidList | ALL)                                                             # alterByAnalyzePartition\n    | CHECK PARTITION (uidList | ALL)                                                               # alterByCheckPartition\n    | OPTIMIZE PARTITION (uidList | ALL)                                                            # alterByOptimizePartition\n    | REBUILD PARTITION (uidList | ALL)                                                             # alterByRebuildPartition\n    | REPAIR PARTITION (uidList | ALL)                                                              # alterByRepairPartition\n    | REMOVE PARTITIONING                                                                           # alterByRemovePartitioning\n    | UPGRADE PARTITIONING                                                                          # alterByUpgradePartitioning\n    ;\n\n//    Drop statements\n\ndropDatabase\n    : DROP dbFormat = (DATABASE | SCHEMA) ifExists? uid\n    ;\n\ndropEvent\n    : DROP EVENT ifExists? fullId\n    ;\n\ndropIndex\n    : DROP INDEX intimeAction = (ONLINE | OFFLINE)? uid ON tableName (\n        ALGORITHM '='? algType = (DEFAULT | INPLACE | COPY)\n        | LOCK '='? lockType = (DEFAULT | NONE | SHARED | EXCLUSIVE)\n    )*\n    ;\n\ndropLogfileGroup\n    : DROP LOGFILE GROUP uid ENGINE '=' engineName\n    ;\n\ndropProcedure\n    : DROP PROCEDURE ifExists? fullId\n    ;\n\ndropFunction\n    : DROP FUNCTION ifExists? fullId\n    ;\n\ndropServer\n    : DROP SERVER ifExists? uid\n    ;\n\ndropTable\n    : DROP TEMPORARY? TABLE ifExists? tables dropType = (RESTRICT | CASCADE)?\n    ;\n\ndropTablespace\n    : DROP TABLESPACE uid (ENGINE '='? engineName)?\n    ;\n\ndropTrigger\n    : DROP TRIGGER ifExists? fullId\n    ;\n\ndropView\n    : DROP VIEW ifExists? fullId (',' fullId)* dropType = (RESTRICT | CASCADE)?\n    ;\n\ndropRole\n    : DROP ROLE ifExists? roleName (',' roleName)*\n    ;\n\nsetRole\n    : SET DEFAULT ROLE (NONE | ALL | roleName (',' roleName)*) TO (userName | uid) (\n        ',' (userName | uid)\n    )*\n    | SET ROLE roleOption\n    ;\n\n//    Other DDL statements\n\nrenameTable\n    : RENAME TABLE renameTableClause (',' renameTableClause)*\n    ;\n\nrenameTableClause\n    : tableName TO tableName\n    ;\n\ntruncateTable\n    : TRUNCATE TABLE? tableName\n    ;\n\n// Data Manipulation Language\n\n//    Primary DML Statements\n\ncallStatement\n    : CALL fullId ('(' (constants | expressions)? ')')?\n    ;\n\ndeleteStatement\n    : singleDeleteStatement\n    | multipleDeleteStatement\n    ;\n\ndoStatement\n    : DO expressions\n    ;\n\nhandlerStatement\n    : handlerOpenStatement\n    | handlerReadIndexStatement\n    | handlerReadStatement\n    | handlerCloseStatement\n    ;\n\ninsertStatement\n    : INSERT priority = (LOW_PRIORITY | DELAYED | HIGH_PRIORITY)? IGNORE? INTO? tableName (\n        PARTITION '(' partitions = uidList? ')'\n    )? (\n        ('(' columns = fullColumnNameList? ')')? insertStatementValue (AS? uid)?\n        | SET setFirst = updatedElement (',' setElements += updatedElement)*\n    ) (\n        ON DUPLICATE KEY UPDATE duplicatedFirst = updatedElement (\n            ',' duplicatedElements += updatedElement\n        )*\n    )?\n    ;\n\nloadDataStatement\n    : LOAD DATA priority = (LOW_PRIORITY | CONCURRENT)? LOCAL? INFILE filename = STRING_LITERAL violation = (\n        REPLACE\n        | IGNORE\n    )? INTO TABLE tableName (PARTITION '(' uidList ')')? (CHARACTER SET charset = charsetName)? (\n        fieldsFormat = (FIELDS | COLUMNS) selectFieldsInto+\n    )? (LINES selectLinesInto+)? (IGNORE decimalLiteral linesFormat = (LINES | ROWS))? (\n        '(' assignmentField (',' assignmentField)* ')'\n    )? (SET updatedElement (',' updatedElement)*)?\n    ;\n\nloadXmlStatement\n    : LOAD XML priority = (LOW_PRIORITY | CONCURRENT)? LOCAL? INFILE filename = STRING_LITERAL violation = (\n        REPLACE\n        | IGNORE\n    )? INTO TABLE tableName (CHARACTER SET charset = charsetName)? (\n        ROWS IDENTIFIED BY '<' tag = STRING_LITERAL '>'\n    )? (IGNORE decimalLiteral linesFormat = (LINES | ROWS))? (\n        '(' assignmentField (',' assignmentField)* ')'\n    )? (SET updatedElement (',' updatedElement)*)?\n    ;\n\nreplaceStatement\n    : REPLACE priority = (LOW_PRIORITY | DELAYED)? INTO? tableName (\n        PARTITION '(' partitions = uidList ')'\n    )? (\n        ('(' columns = uidList ')')? insertStatementValue\n        | SET setFirst = updatedElement (',' setElements += updatedElement)*\n    )\n    ;\n\nselectStatement\n    : withStatement? querySpecification lockClause?\n    | withStatement? queryExpression lockClause?\n    | withStatement? (querySpecificationNointo | queryExpressionNointo) unionStatement+ (\n        UNION unionType = (ALL | DISTINCT)? (querySpecification | queryExpression)\n    )? orderByClause? limitClause? lockClause?\n    | withStatement? queryExpressionNointo unionParenthesis+ (UNION unionType = (ALL | DISTINCT)? queryExpression)? orderByClause? limitClause? lockClause?\n    | withStatement? querySpecificationNointo (',' lateralStatement)+\n    ;\n\nupdateStatement\n    : singleUpdateStatement\n    | multipleUpdateStatement\n    ;\n\n// https://dev.mysql.com/doc/refman/8.0/en/values.html\nvaluesStatement\n    : VALUES '(' expressionsWithDefaults? ')' (',' '(' expressionsWithDefaults? ')')*\n    ;\n\n// details\n\ninsertStatementValue\n    : selectStatement\n    | insertFormat = (VALUES | VALUE) '(' expressionsWithDefaults? ')' (\n        ',' '(' expressionsWithDefaults? ')'\n    )*\n    ;\n\nupdatedElement\n    : fullColumnName '=' (expression | DEFAULT)\n    ;\n\nassignmentField\n    : uid\n    | LOCAL_ID\n    ;\n\nlockClause\n    : FOR UPDATE\n    | LOCK IN SHARE MODE\n    ;\n\n//    Detailed DML Statements\n\nsingleDeleteStatement\n    : DELETE priority = LOW_PRIORITY? QUICK? IGNORE? FROM tableName (AS? uid)? (\n        PARTITION '(' uidList ')'\n    )? (WHERE expression)? orderByClause? (LIMIT limitClauseAtom)?\n    ;\n\nmultipleDeleteStatement\n    : DELETE priority = LOW_PRIORITY? QUICK? IGNORE? (\n        tableName ('.' '*')? ( ',' tableName ('.' '*')?)* FROM tableSources\n        | FROM tableName ('.' '*')? ( ',' tableName ('.' '*')?)* USING tableSources\n    ) (WHERE expression)?\n    ;\n\nhandlerOpenStatement\n    : HANDLER tableName OPEN (AS? uid)?\n    ;\n\nhandlerReadIndexStatement\n    : HANDLER tableName READ index = uid (\n        comparisonOperator '(' constants ')'\n        | moveOrder = (FIRST | NEXT | PREV | LAST)\n    ) (WHERE expression)? (LIMIT limitClauseAtom)?\n    ;\n\nhandlerReadStatement\n    : HANDLER tableName READ moveOrder = (FIRST | NEXT) (WHERE expression)? (LIMIT limitClauseAtom)?\n    ;\n\nhandlerCloseStatement\n    : HANDLER tableName CLOSE\n    ;\n\nsingleUpdateStatement\n    : UPDATE priority = LOW_PRIORITY? IGNORE? tableSources (AS? uid)? SET updatedElement (\n        ',' updatedElement\n    )* (WHERE expression)? orderByClause? limitClause?\n    ;\n\nmultipleUpdateStatement\n    : UPDATE priority = LOW_PRIORITY? IGNORE? tableSources SET updatedElement (',' updatedElement)* (\n        WHERE expression\n    )?\n    ;\n\n// details\n\norderByClause\n    : ORDER BY orderByExpression (',' orderByExpression)*\n    ;\n\norderByExpression\n    : expression order = (ASC | DESC)?\n    ;\n\ntableSources\n    : tableSource (',' tableSource)*\n    ;\n\ntableSource\n    : tableSourceItem joinPart*         # tableSourceBase\n    | '(' tableSourceItem joinPart* ')' # tableSourceNested\n    | jsonTable                         # tableJson\n    ;\n\ntableSourceItem\n    : tableName (PARTITION '(' uidList ')')? (AS? alias = uid)? (indexHint (',' indexHint)*)? # atomTableItem\n    | sequenceFunctionName '(' DECIMAL_LITERAL ')' (AS? alias = uid)?                         # sequenceTableItem\n    | (selectStatement | '(' parenthesisSubquery = selectStatement ')') AS? alias = uid       # subqueryTableItem\n    | '(' tableSources ')'                                                                    # tableSourcesItem\n    ;\n\nindexHint\n    : indexHintAction = (USE | IGNORE | FORCE) keyFormat = (INDEX | KEY) (FOR indexHintType)? '(' uidList ')'\n    ;\n\nindexHintType\n    : JOIN\n    | ORDER BY\n    | GROUP BY\n    ;\n\njoinPart\n    : (INNER | CROSS)? JOIN LATERAL? tableSourceItem joinSpec*      # innerJoin\n    | STRAIGHT_JOIN tableSourceItem (ON expression)*                # straightJoin\n    | (LEFT | RIGHT) OUTER? JOIN LATERAL? tableSourceItem joinSpec* # outerJoin\n    | NATURAL ((LEFT | RIGHT) OUTER?)? JOIN tableSourceItem         # naturalJoin\n    ;\n\njoinSpec\n    : (ON expression)\n    | USING '(' uidList ')'\n    ;\n\n//    Select Statement's Details\n\nqueryExpression\n    : '(' querySpecification ')'\n    | '(' queryExpression ')'\n    ;\n\nqueryExpressionNointo\n    : '(' querySpecificationNointo ')'\n    | '(' queryExpressionNointo ')'\n    ;\n\nquerySpecification\n    : SELECT selectSpec* selectElements selectIntoExpression? fromClause? groupByClause? havingClause? windowClause? orderByClause? limitClause?\n    | SELECT selectSpec* selectElements fromClause? groupByClause? havingClause? windowClause? orderByClause? limitClause? selectIntoExpression?\n    ;\n\nquerySpecificationNointo\n    : SELECT selectSpec* selectElements fromClause? groupByClause? havingClause? windowClause? orderByClause? limitClause? unionStatement?\n    ;\n\nunionParenthesis\n    : UNION unionType = (ALL | DISTINCT)? queryExpressionNointo\n    ;\n\nunionStatement\n    : UNION unionType = (ALL | DISTINCT)? (querySpecificationNointo | queryExpressionNointo)\n    ;\n\nlateralStatement\n    : LATERAL (\n        querySpecificationNointo\n        | queryExpressionNointo\n        | ('(' (querySpecificationNointo | queryExpressionNointo) ')' (AS? uid)?)\n    )\n    ;\n\n// JSON\n\n// https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html\njsonTable\n    : JSON_TABLE '(' expression ',' STRING_LITERAL COLUMNS '(' jsonColumnList ')' ')' (AS? uid)?\n    ;\n\njsonColumnList\n    : jsonColumn (',' jsonColumn)*\n    ;\n\njsonColumn\n    : fullColumnName (\n        FOR ORDINALITY\n        | dataType (PATH STRING_LITERAL jsonOnEmpty? jsonOnError? | EXISTS PATH STRING_LITERAL)\n    )\n    | NESTED PATH? STRING_LITERAL COLUMNS '(' jsonColumnList ')'\n    ;\n\njsonOnEmpty\n    : (NULL_LITERAL | ERROR | DEFAULT defaultValue) ON EMPTY\n    ;\n\njsonOnError\n    : (NULL_LITERAL | ERROR | DEFAULT defaultValue) ON ERROR\n    ;\n\n// details\n\nselectSpec\n    : (ALL | DISTINCT | DISTINCTROW)\n    | HIGH_PRIORITY\n    | STRAIGHT_JOIN\n    | SQL_SMALL_RESULT\n    | SQL_BIG_RESULT\n    | SQL_BUFFER_RESULT\n    | (SQL_CACHE | SQL_NO_CACHE)\n    | SQL_CALC_FOUND_ROWS\n    ;\n\nselectElements\n    : (star = '*' | selectElement) (',' selectElement)*\n    ;\n\nselectElement\n    : fullId '.' '*'                               # selectStarElement\n    | fullColumnName (AS? uid)?                    # selectColumnElement\n    | functionCall (AS? uid)?                      # selectFunctionElement\n    | (LOCAL_ID VAR_ASSIGN)? expression (AS? uid)? # selectExpressionElement\n    ;\n\nselectIntoExpression\n    : INTO assignmentField (',' assignmentField)* # selectIntoVariables\n    | INTO DUMPFILE STRING_LITERAL                # selectIntoDumpFile\n    | (\n        INTO OUTFILE filename = STRING_LITERAL (CHARACTER SET charset = charsetName)? (\n            fieldsFormat = (FIELDS | COLUMNS) selectFieldsInto+\n        )? (LINES selectLinesInto+)?\n    ) # selectIntoTextFile\n    ;\n\nselectFieldsInto\n    : TERMINATED BY terminationField = STRING_LITERAL\n    | OPTIONALLY? ENCLOSED BY enclosion = STRING_LITERAL\n    | ESCAPED BY escaping = STRING_LITERAL\n    ;\n\nselectLinesInto\n    : STARTING BY starting = STRING_LITERAL\n    | TERMINATED BY terminationLine = STRING_LITERAL\n    ;\n\nfromClause\n    : (FROM tableSources)? (WHERE whereExpr = expression)?\n    ;\n\ngroupByClause\n    : GROUP BY groupByItem (',' groupByItem)* (WITH ROLLUP)?\n    ;\n\nhavingClause\n    : HAVING havingExpr = expression\n    ;\n\nwindowClause\n    : WINDOW windowName AS '(' windowSpec ')' (',' windowName AS '(' windowSpec ')')*\n    ;\n\ngroupByItem\n    : expression order = (ASC | DESC)?\n    ;\n\nlimitClause\n    : LIMIT (\n        (offset = limitClauseAtom ',')? limit = limitClauseAtom\n        | limit = limitClauseAtom OFFSET offset = limitClauseAtom\n    )\n    ;\n\nlimitClauseAtom\n    : decimalLiteral\n    | mysqlVariable\n    | simpleId\n    ;\n\n// Transaction's Statements\n\nstartTransaction\n    : START TRANSACTION (transactionMode (',' transactionMode)*)?\n    ;\n\nbeginWork\n    : BEGIN WORK?\n    ;\n\ncommitWork\n    : COMMIT WORK? (AND nochain = NO? CHAIN)? (norelease = NO? RELEASE)?\n    ;\n\nrollbackWork\n    : ROLLBACK WORK? (AND nochain = NO? CHAIN)? (norelease = NO? RELEASE)?\n    ;\n\nsavepointStatement\n    : SAVEPOINT uid\n    ;\n\nrollbackStatement\n    : ROLLBACK WORK? TO SAVEPOINT? uid\n    ;\n\nreleaseStatement\n    : RELEASE SAVEPOINT uid\n    ;\n\nlockTables\n    : LOCK (TABLE | TABLES) lockTableElement (',' lockTableElement)*\n    ;\n\nunlockTables\n    : UNLOCK TABLES\n    ;\n\n// details\n\nsetAutocommitStatement\n    : SET AUTOCOMMIT '=' autocommitValue = ('0' | '1')\n    ;\n\nsetTransactionStatement\n    : SET transactionContext = (GLOBAL | SESSION)? TRANSACTION transactionOption (\n        ',' transactionOption\n    )*\n    ;\n\ntransactionMode\n    : WITH CONSISTENT SNAPSHOT\n    | READ WRITE\n    | READ ONLY\n    ;\n\nlockTableElement\n    : tableName (AS? uid)? lockAction\n    ;\n\nlockAction\n    : READ LOCAL?\n    | LOW_PRIORITY? WRITE\n    ;\n\ntransactionOption\n    : ISOLATION LEVEL transactionLevel\n    | READ WRITE\n    | READ ONLY\n    ;\n\ntransactionLevel\n    : REPEATABLE READ\n    | READ COMMITTED\n    | READ UNCOMMITTED\n    | SERIALIZABLE\n    ;\n\n// Replication's Statements\n\n//    Base Replication\n\nchangeMaster\n    : CHANGE MASTER TO masterOption (',' masterOption)* channelOption?\n    ;\n\nchangeReplicationFilter\n    : CHANGE REPLICATION FILTER replicationFilter (',' replicationFilter)*\n    ;\n\npurgeBinaryLogs\n    : PURGE purgeFormat = (BINARY | MASTER) LOGS (\n        TO fileName = STRING_LITERAL\n        | BEFORE timeValue = STRING_LITERAL\n    )\n    ;\n\nresetMaster\n    : RESET MASTER\n    ;\n\nresetSlave\n    : RESET SLAVE ALL? channelOption?\n    ;\n\nstartSlave\n    : START SLAVE (threadType (',' threadType)*)? (UNTIL untilOption)? connectionOption* channelOption?\n    ;\n\nstopSlave\n    : STOP SLAVE (threadType (',' threadType)*)?\n    ;\n\nstartGroupReplication\n    : START GROUP_REPLICATION\n    ;\n\nstopGroupReplication\n    : STOP GROUP_REPLICATION\n    ;\n\n// details\n\nmasterOption\n    : stringMasterOption '=' STRING_LITERAL           # masterStringOption\n    | decimalMasterOption '=' decimalLiteral          # masterDecimalOption\n    | boolMasterOption '=' boolVal = ('0' | '1')      # masterBoolOption\n    | MASTER_HEARTBEAT_PERIOD '=' REAL_LITERAL        # masterRealOption\n    | IGNORE_SERVER_IDS '=' '(' (uid (',' uid)*)? ')' # masterUidListOption\n    ;\n\nstringMasterOption\n    : MASTER_BIND\n    | MASTER_HOST\n    | MASTER_USER\n    | MASTER_PASSWORD\n    | MASTER_LOG_FILE\n    | RELAY_LOG_FILE\n    | MASTER_SSL_CA\n    | MASTER_SSL_CAPATH\n    | MASTER_SSL_CERT\n    | MASTER_SSL_CRL\n    | MASTER_SSL_CRLPATH\n    | MASTER_SSL_KEY\n    | MASTER_SSL_CIPHER\n    | MASTER_TLS_VERSION\n    ;\n\ndecimalMasterOption\n    : MASTER_PORT\n    | MASTER_CONNECT_RETRY\n    | MASTER_RETRY_COUNT\n    | MASTER_DELAY\n    | MASTER_LOG_POS\n    | RELAY_LOG_POS\n    ;\n\nboolMasterOption\n    : MASTER_AUTO_POSITION\n    | MASTER_SSL\n    | MASTER_SSL_VERIFY_SERVER_CERT\n    ;\n\nchannelOption\n    : FOR CHANNEL STRING_LITERAL\n    ;\n\nreplicationFilter\n    : REPLICATE_DO_DB '=' '(' uidList ')'                         # doDbReplication\n    | REPLICATE_IGNORE_DB '=' '(' uidList ')'                     # ignoreDbReplication\n    | REPLICATE_DO_TABLE '=' '(' tables ')'                       # doTableReplication\n    | REPLICATE_IGNORE_TABLE '=' '(' tables ')'                   # ignoreTableReplication\n    | REPLICATE_WILD_DO_TABLE '=' '(' simpleStrings ')'           # wildDoTableReplication\n    | REPLICATE_WILD_IGNORE_TABLE '=' '(' simpleStrings ')'       # wildIgnoreTableReplication\n    | REPLICATE_REWRITE_DB '=' '(' tablePair (',' tablePair)* ')' # rewriteDbReplication\n    ;\n\ntablePair\n    : '(' firstTable = tableName ',' secondTable = tableName ')'\n    ;\n\nthreadType\n    : IO_THREAD\n    | SQL_THREAD\n    ;\n\nuntilOption\n    : gtids = (SQL_BEFORE_GTIDS | SQL_AFTER_GTIDS) '=' gtuidSet                # gtidsUntilOption\n    | MASTER_LOG_FILE '=' STRING_LITERAL ',' MASTER_LOG_POS '=' decimalLiteral # masterLogUntilOption\n    | RELAY_LOG_FILE '=' STRING_LITERAL ',' RELAY_LOG_POS '=' decimalLiteral   # relayLogUntilOption\n    | SQL_AFTER_MTS_GAPS                                                       # sqlGapsUntilOption\n    ;\n\nconnectionOption\n    : USER '=' conOptUser = STRING_LITERAL            # userConnectionOption\n    | PASSWORD '=' conOptPassword = STRING_LITERAL    # passwordConnectionOption\n    | DEFAULT_AUTH '=' conOptDefAuth = STRING_LITERAL # defaultAuthConnectionOption\n    | PLUGIN_DIR '=' conOptPluginDir = STRING_LITERAL # pluginDirConnectionOption\n    ;\n\ngtuidSet\n    : uuidSet (',' uuidSet)*\n    | STRING_LITERAL\n    ;\n\n//    XA Transactions\n\nxaStartTransaction\n    : XA xaStart = (START | BEGIN) xid xaAction = (JOIN | RESUME)?\n    ;\n\nxaEndTransaction\n    : XA END xid (SUSPEND (FOR MIGRATE)?)?\n    ;\n\nxaPrepareStatement\n    : XA PREPARE xid\n    ;\n\nxaCommitWork\n    : XA COMMIT xid (ONE PHASE)?\n    ;\n\nxaRollbackWork\n    : XA ROLLBACK xid\n    ;\n\nxaRecoverWork\n    : XA RECOVER (CONVERT xid)?\n    ;\n\n// Prepared Statements\n\nprepareStatement\n    : PREPARE uid FROM (query = STRING_LITERAL | variable = LOCAL_ID)\n    ;\n\nexecuteStatement\n    : EXECUTE uid (USING userVariables)?\n    ;\n\ndeallocatePrepare\n    : dropFormat = (DEALLOCATE | DROP) PREPARE uid\n    ;\n\n// Compound Statements\n\nroutineBody\n    : blockStatement\n    | sqlStatement\n    ;\n\n// details\n\nblockStatement\n    : (uid ':')? BEGIN (declareVariable SEMI)* (declareCondition SEMI)* (declareCursor SEMI)* (\n        declareHandler SEMI\n    )* procedureSqlStatement* END uid?\n    ;\n\ncaseStatement\n    : CASE (uid | expression)? caseAlternative+ (ELSE procedureSqlStatement+)? END CASE\n    ;\n\nifStatement\n    : IF expression THEN thenStatements += procedureSqlStatement+ elifAlternative* (\n        ELSE elseStatements += procedureSqlStatement+\n    )? END IF\n    ;\n\niterateStatement\n    : ITERATE uid\n    ;\n\nleaveStatement\n    : LEAVE uid\n    ;\n\nloopStatement\n    : (uid ':')? LOOP procedureSqlStatement+ END LOOP uid?\n    ;\n\nrepeatStatement\n    : (uid ':')? REPEAT procedureSqlStatement+ UNTIL expression END REPEAT uid?\n    ;\n\nreturnStatement\n    : RETURN expression\n    ;\n\nwhileStatement\n    : (uid ':')? WHILE expression DO procedureSqlStatement+ END WHILE uid?\n    ;\n\ncursorStatement\n    : CLOSE uid                            # CloseCursor\n    | FETCH (NEXT? FROM)? uid INTO uidList # FetchCursor\n    | OPEN uid                             # OpenCursor\n    ;\n\n// details\n\ndeclareVariable\n    : DECLARE uidList dataType (DEFAULT expression)?\n    ;\n\ndeclareCondition\n    : DECLARE uid CONDITION FOR (decimalLiteral | SQLSTATE VALUE? STRING_LITERAL)\n    ;\n\ndeclareCursor\n    : DECLARE uid CURSOR FOR selectStatement\n    ;\n\ndeclareHandler\n    : DECLARE handlerAction = (CONTINUE | EXIT | UNDO) HANDLER FOR handlerConditionValue (\n        ',' handlerConditionValue\n    )* routineBody\n    ;\n\nhandlerConditionValue\n    : decimalLiteral                 # handlerConditionCode\n    | SQLSTATE VALUE? STRING_LITERAL # handlerConditionState\n    | uid                            # handlerConditionName\n    | SQLWARNING                     # handlerConditionWarning\n    | NOT FOUND                      # handlerConditionNotfound\n    | SQLEXCEPTION                   # handlerConditionException\n    ;\n\nprocedureSqlStatement\n    : (compoundStatement | sqlStatement) SEMI\n    ;\n\ncaseAlternative\n    : WHEN (constant | expression) THEN procedureSqlStatement+\n    ;\n\nelifAlternative\n    : ELSEIF expression THEN procedureSqlStatement+\n    ;\n\n// Administration Statements\n\n//    Account management statements\n\nalterUser\n    : ALTER USER userSpecification (',' userSpecification)* # alterUserMysqlV56\n    | ALTER USER ifExists? userAuthOption (',' userAuthOption)* (\n        REQUIRE (tlsNone = NONE | tlsOption (AND? tlsOption)*)\n    )? (WITH userResourceOption+)? (userPasswordOption | userLockOption)* (\n        COMMENT STRING_LITERAL\n        | ATTRIBUTE STRING_LITERAL\n    )?                                                              # alterUserMysqlV80\n    | ALTER USER ifExists? (userName | uid) DEFAULT ROLE roleOption # alterUserMysqlV80\n    ;\n\ncreateUser\n    : CREATE USER userAuthOption (',' userAuthOption)* # createUserMysqlV56\n    | CREATE USER ifNotExists? userAuthOption (',' userAuthOption)* (DEFAULT ROLE roleOption)? (\n        REQUIRE (tlsNone = NONE | tlsOption (AND? tlsOption)*)\n    )? (WITH userResourceOption+)? (userPasswordOption | userLockOption)* (\n        COMMENT STRING_LITERAL\n        | ATTRIBUTE STRING_LITERAL\n    )? # createUserMysqlV80\n    ;\n\ndropUser\n    : DROP USER ifExists? userName (',' userName)*\n    ;\n\ngrantStatement\n    : GRANT privelegeClause (',' privelegeClause)* ON privilegeObject = (\n        TABLE\n        | FUNCTION\n        | PROCEDURE\n    )? privilegeLevel TO userAuthOption (',' userAuthOption)* (\n        REQUIRE (tlsNone = NONE | tlsOption (AND? tlsOption)*)\n    )? (WITH (GRANT OPTION | userResourceOption)*)? (AS userName WITH ROLE roleOption)?\n    | GRANT (userName | uid) (',' (userName | uid))* TO (userName | uid) (',' (userName | uid))* (\n        WITH ADMIN OPTION\n    )?\n    ;\n\nroleOption\n    : DEFAULT\n    | NONE\n    | ALL (EXCEPT userName (',' userName)*)?\n    | userName (',' userName)*\n    ;\n\ngrantProxy\n    : GRANT PROXY ON fromFirst = userName TO toFirst = userName (',' toOther += userName)* (\n        WITH GRANT OPTION\n    )?\n    ;\n\nrenameUser\n    : RENAME USER renameUserClause (',' renameUserClause)*\n    ;\n\nrevokeStatement\n    : REVOKE ifExists? (privelegeClause | uid) (',' privelegeClause | uid)* ON privilegeObject = (\n        TABLE\n        | FUNCTION\n        | PROCEDURE\n    )? privilegeLevel FROM userName (',' userName)* (IGNORE UNKNOWN USER)? # detailRevoke\n    | REVOKE ifExists? ALL PRIVILEGES? ',' GRANT OPTION FROM userName (',' userName)* (\n        IGNORE UNKNOWN USER\n    )? # shortRevoke\n    | REVOKE ifExists? (userName | uid) (',' (userName | uid))* FROM (userName | uid) (\n        ',' (userName | uid)\n    )* (IGNORE UNKNOWN USER)? # roleRevoke\n    ;\n\nrevokeProxy\n    : REVOKE PROXY ON onUser = userName FROM fromFirst = userName (',' fromOther += userName)*\n    ;\n\nsetPasswordStatement\n    : SET PASSWORD (FOR userName)? '=' (passwordFunctionClause | STRING_LITERAL)\n    ;\n\n// details\n\nuserSpecification\n    : userName userPasswordOption\n    ;\n\nuserAuthOption\n    : userName IDENTIFIED BY PASSWORD hashed = STRING_LITERAL # hashAuthOption\n    | userName IDENTIFIED BY RANDOM PASSWORD authOptionClause # randomAuthOption\n    | userName IDENTIFIED BY STRING_LITERAL authOptionClause  # stringAuthOption\n    | userName IDENTIFIED WITH authenticationRule             # moduleAuthOption\n    | userName                                                # simpleAuthOption\n    ;\n\nauthOptionClause\n    : (REPLACE STRING_LITERAL)? (RETAIN CURRENT PASSWORD)?\n    ;\n\nauthenticationRule\n    : authPlugin ((BY | USING | AS) (STRING_LITERAL | RANDOM PASSWORD) authOptionClause)? # module\n    | authPlugin USING passwordFunctionClause                                             # passwordModuleOption\n    ;\n\ntlsOption\n    : SSL\n    | X509\n    | CIPHER STRING_LITERAL\n    | ISSUER STRING_LITERAL\n    | SUBJECT STRING_LITERAL\n    ;\n\nuserResourceOption\n    : MAX_QUERIES_PER_HOUR decimalLiteral\n    | MAX_UPDATES_PER_HOUR decimalLiteral\n    | MAX_CONNECTIONS_PER_HOUR decimalLiteral\n    | MAX_USER_CONNECTIONS decimalLiteral\n    ;\n\nuserPasswordOption\n    : PASSWORD EXPIRE (\n        expireType = DEFAULT\n        | expireType = NEVER\n        | expireType = INTERVAL decimalLiteral DAY\n    )?\n    | PASSWORD HISTORY (DEFAULT | decimalLiteral)\n    | PASSWORD REUSE INTERVAL (DEFAULT | decimalLiteral DAY)\n    | PASSWORD REQUIRE CURRENT (OPTIONAL | DEFAULT)?\n    | FAILED_LOGIN_ATTEMPTS decimalLiteral\n    | PASSWORD_LOCK_TIME (decimalLiteral | UNBOUNDED)\n    ;\n\nuserLockOption\n    : ACCOUNT lockType = (LOCK | UNLOCK)\n    ;\n\nprivelegeClause\n    : privilege ('(' uidList ')')?\n    ;\n\nprivilege\n    : ALL PRIVILEGES?\n    | ALTER ROUTINE?\n    | CREATE (TEMPORARY TABLES | ROUTINE | VIEW | USER | TABLESPACE | ROLE)?\n    | DELETE\n    | DROP (ROLE)?\n    | EVENT\n    | EXECUTE\n    | FILE\n    | GRANT OPTION\n    | INDEX\n    | INSERT\n    | LOCK TABLES\n    | PROCESS\n    | PROXY\n    | REFERENCES\n    | RELOAD\n    | REPLICATION (CLIENT | SLAVE)\n    | SELECT\n    | SHOW (VIEW | DATABASES)\n    | SHUTDOWN\n    | SUPER\n    | TRIGGER\n    | UPDATE\n    | USAGE\n    | APPLICATION_PASSWORD_ADMIN\n    | AUDIT_ABORT_EXEMPT\n    | AUDIT_ADMIN\n    | AUTHENTICATION_POLICY_ADMIN\n    | BACKUP_ADMIN\n    | BINLOG_ADMIN\n    | BINLOG_ENCRYPTION_ADMIN\n    | CLONE_ADMIN\n    | CONNECTION_ADMIN\n    | ENCRYPTION_KEY_ADMIN\n    | FIREWALL_ADMIN\n    | FIREWALL_EXEMPT\n    | FIREWALL_USER\n    | FLUSH_OPTIMIZER_COSTS\n    | FLUSH_STATUS\n    | FLUSH_TABLES\n    | FLUSH_USER_RESOURCES\n    | GROUP_REPLICATION_ADMIN\n    | INNODB_REDO_LOG_ARCHIVE\n    | INNODB_REDO_LOG_ENABLE\n    | NDB_STORED_USER\n    | PASSWORDLESS_USER_ADMIN\n    | PERSIST_RO_VARIABLES_ADMIN\n    | REPLICATION_APPLIER\n    | REPLICATION_SLAVE_ADMIN\n    | RESOURCE_GROUP_ADMIN\n    | RESOURCE_GROUP_USER\n    | ROLE_ADMIN\n    | SERVICE_CONNECTION_ADMIN\n    | SESSION_VARIABLES_ADMIN\n    | SET_USER_ID\n    | SKIP_QUERY_REWRITE\n    | SHOW_ROUTINE\n    | SYSTEM_USER\n    | SYSTEM_VARIABLES_ADMIN\n    | TABLE_ENCRYPTION_ADMIN\n    | TELEMETRY_LOG_ADMIN\n    | TP_CONNECTION_ADMIN\n    | VERSION_TOKEN_ADMIN\n    | XA_RECOVER_ADMIN\n    // MySQL on Amazon RDS\n    | LOAD FROM S3\n    | SELECT INTO S3\n    | INVOKE LAMBDA\n    ;\n\nprivilegeLevel\n    : '*'          # currentSchemaPriviLevel\n    | '*' '.' '*'  # globalPrivLevel\n    | uid '.' '*'  # definiteSchemaPrivLevel\n    | uid '.' uid  # definiteFullTablePrivLevel\n    | uid dottedId # definiteFullTablePrivLevel2\n    | uid          # definiteTablePrivLevel\n    ;\n\nrenameUserClause\n    : fromFirst = userName TO toFirst = userName\n    ;\n\n//    Table maintenance statements\n\nanalyzeTable\n    : ANALYZE actionOption = (NO_WRITE_TO_BINLOG | LOCAL)? (TABLE | TABLES) tables (\n        UPDATE HISTOGRAM ON fullColumnName (',' fullColumnName)* (WITH decimalLiteral BUCKETS)?\n    )? (DROP HISTOGRAM ON fullColumnName (',' fullColumnName)*)?\n    ;\n\ncheckTable\n    : CHECK TABLE tables checkTableOption*\n    ;\n\nchecksumTable\n    : CHECKSUM TABLE tables actionOption = (QUICK | EXTENDED)?\n    ;\n\noptimizeTable\n    : OPTIMIZE actionOption = (NO_WRITE_TO_BINLOG | LOCAL)? (TABLE | TABLES) tables\n    ;\n\nrepairTable\n    : REPAIR actionOption = (NO_WRITE_TO_BINLOG | LOCAL)? TABLE tables QUICK? EXTENDED? USE_FRM?\n    ;\n\n// details\n\ncheckTableOption\n    : FOR UPGRADE\n    | QUICK\n    | FAST\n    | MEDIUM\n    | EXTENDED\n    | CHANGED\n    ;\n\n//    Plugin and udf statements\n\ncreateUdfunction\n    : CREATE AGGREGATE? FUNCTION ifNotExists? uid RETURNS returnType = (\n        STRING\n        | INTEGER\n        | REAL\n        | DECIMAL\n    ) SONAME STRING_LITERAL\n    ;\n\ninstallPlugin\n    : INSTALL PLUGIN uid SONAME STRING_LITERAL\n    ;\n\nuninstallPlugin\n    : UNINSTALL PLUGIN uid\n    ;\n\n//    Set and show statements\n\nsetStatement\n    : SET variableClause ('=' | ':=') (expression | ON) (\n        ',' variableClause ('=' | ':=') (expression | ON)\n    )*                                                                         # setVariable\n    | SET charSet (charsetName | DEFAULT)                                      # setCharset\n    | SET NAMES (charsetName (COLLATE collationName)? | DEFAULT)               # setNames\n    | setPasswordStatement                                                     # setPassword\n    | setTransactionStatement                                                  # setTransaction\n    | setAutocommitStatement                                                   # setAutocommit\n    | SET fullId ('=' | ':=') expression (',' fullId ('=' | ':=') expression)* # setNewValueInsideTrigger\n    ;\n\nshowStatement\n    : SHOW logFormat = (BINARY | MASTER) LOGS # showMasterLogs\n    | SHOW logFormat = (BINLOG | RELAYLOG) EVENTS (IN filename = STRING_LITERAL)? (\n        FROM fromPosition = decimalLiteral\n    )? (LIMIT (offset = decimalLiteral ',')? rowCount = decimalLiteral)? # showLogEvents\n    | SHOW showCommonEntity showFilter?                                  # showObjectFilter\n    | SHOW FULL? columnsFormat = (COLUMNS | FIELDS) tableFormat = (FROM | IN) tableName (\n        schemaFormat = (FROM | IN) uid\n    )? showFilter?                                                                             # showColumns\n    | SHOW CREATE schemaFormat = (DATABASE | SCHEMA) ifNotExists? uid                          # showCreateDb\n    | SHOW CREATE namedEntity = (EVENT | FUNCTION | PROCEDURE | TABLE | TRIGGER | VIEW) fullId # showCreateFullIdObject\n    | SHOW CREATE USER userName                                                                # showCreateUser\n    | SHOW ENGINE engineName engineOption = (STATUS | MUTEX)                                   # showEngine\n    | SHOW showGlobalInfoClause                                                                # showGlobalInfo\n    | SHOW errorFormat = (ERRORS | WARNINGS) (\n        LIMIT (offset = decimalLiteral ',')? rowCount = decimalLiteral\n    )?                                                                    # showErrors\n    | SHOW COUNT '(' '*' ')' errorFormat = (ERRORS | WARNINGS)            # showCountErrors\n    | SHOW showSchemaEntity (schemaFormat = (FROM | IN) uid)? showFilter? # showSchemaFilter\n    | SHOW routine = (FUNCTION | PROCEDURE) CODE fullId                   # showRoutine\n    | SHOW GRANTS (FOR userName)?                                         # showGrants\n    | SHOW indexFormat = (INDEX | INDEXES | KEYS) tableFormat = (FROM | IN) tableName (\n        schemaFormat = (FROM | IN) uid\n    )? (WHERE expression)?                                           # showIndexes\n    | SHOW OPEN TABLES (schemaFormat = (FROM | IN) uid)? showFilter? # showOpenTables\n    | SHOW PROFILE showProfileType (',' showProfileType)* (FOR QUERY queryCount = decimalLiteral)? (\n        LIMIT (offset = decimalLiteral ',')? rowCount = decimalLiteral\n    )                                                 # showProfile\n    | SHOW SLAVE STATUS (FOR CHANNEL STRING_LITERAL)? # showSlaveStatus\n    ;\n\n// details\n\nvariableClause\n    : LOCAL_ID\n    | GLOBAL_ID\n    | ( ('@' '@')? (GLOBAL | SESSION | LOCAL))? uid\n    ;\n\nshowCommonEntity\n    : CHARACTER SET\n    | COLLATION\n    | DATABASES\n    | SCHEMAS\n    | FUNCTION STATUS\n    | PROCEDURE STATUS\n    | (GLOBAL | SESSION)? (STATUS | VARIABLES)\n    ;\n\nshowFilter\n    : LIKE STRING_LITERAL\n    | WHERE expression\n    ;\n\nshowGlobalInfoClause\n    : STORAGE? ENGINES\n    | MASTER STATUS\n    | PLUGINS\n    | PRIVILEGES\n    | FULL? PROCESSLIST\n    | PROFILES\n    | SLAVE HOSTS\n    | AUTHORS\n    | CONTRIBUTORS\n    ;\n\nshowSchemaEntity\n    : EVENTS\n    | TABLE STATUS\n    | FULL? TABLES\n    | TRIGGERS\n    ;\n\nshowProfileType\n    : ALL\n    | BLOCK IO\n    | CONTEXT SWITCHES\n    | CPU\n    | IPC\n    | MEMORY\n    | PAGE FAULTS\n    | SOURCE\n    | SWAPS\n    ;\n\n//    Other administrative statements\n\nbinlogStatement\n    : BINLOG STRING_LITERAL\n    ;\n\ncacheIndexStatement\n    : CACHE INDEX tableIndexes (',' tableIndexes)* (PARTITION '(' (uidList | ALL) ')')? IN schema = uid\n    ;\n\nflushStatement\n    : FLUSH flushFormat = (NO_WRITE_TO_BINLOG | LOCAL)? flushOption (',' flushOption)*\n    // Specific for Azure Database for MySQL Single Server instance.\n    | FLUSH FIREWALL_RULES\n    ;\n\nkillStatement\n    : KILL connectionFormat = (CONNECTION | QUERY)? expression\n    ;\n\nloadIndexIntoCache\n    : LOAD INDEX INTO CACHE loadedTableIndexes (',' loadedTableIndexes)*\n    ;\n\n// remark reset (maser | slave) describe in replication's\n//  statements section\nresetStatement\n    : RESET QUERY CACHE\n    ;\n\nshutdownStatement\n    : SHUTDOWN\n    ;\n\n// details\n\ntableIndexes\n    : tableName (indexFormat = (INDEX | KEY)? '(' uidList ')')?\n    ;\n\nflushOption\n    : (\n        DES_KEY_FILE\n        | HOSTS\n        | ( BINARY | ENGINE | ERROR | GENERAL | RELAY | SLOW)? LOGS\n        | OPTIMIZER_COSTS\n        | PRIVILEGES\n        | QUERY CACHE\n        | STATUS\n        | USER_RESOURCES\n        | TABLES (WITH READ LOCK)?\n    )                                            # simpleFlushOption\n    | RELAY LOGS channelOption?                  # channelFlushOption\n    | (TABLE | TABLES) tables? flushTableOption? # tableFlushOption\n    ;\n\nflushTableOption\n    : WITH READ LOCK\n    | FOR EXPORT\n    ;\n\nloadedTableIndexes\n    : tableName (PARTITION '(' (partitionList = uidList | ALL) ')')? (\n        indexFormat = (INDEX | KEY)? '(' indexList = uidList ')'\n    )? (IGNORE LEAVES)?\n    ;\n\n// Utility Statements\n\nsimpleDescribeStatement\n    : command = (EXPLAIN | DESCRIBE | DESC) tableName (column = uid | pattern = STRING_LITERAL)?\n    ;\n\nfullDescribeStatement\n    : command = (EXPLAIN | DESCRIBE | DESC) (\n        formatType = (EXTENDED | PARTITIONS | FORMAT) '=' formatValue = (TRADITIONAL | JSON)\n    )? describeObjectClause\n    ;\n\nhelpStatement\n    : HELP STRING_LITERAL\n    ;\n\nuseStatement\n    : USE uid\n    ;\n\nsignalStatement\n    : SIGNAL (( SQLSTATE VALUE? stringLiteral) | ID | REVERSE_QUOTE_ID) (\n        SET signalConditionInformation ( ',' signalConditionInformation)*\n    )?\n    ;\n\nresignalStatement\n    : RESIGNAL (( SQLSTATE VALUE? stringLiteral) | ID | REVERSE_QUOTE_ID)? (\n        SET signalConditionInformation ( ',' signalConditionInformation)*\n    )?\n    ;\n\nsignalConditionInformation\n    : (\n        CLASS_ORIGIN\n        | SUBCLASS_ORIGIN\n        | MESSAGE_TEXT\n        | MYSQL_ERRNO\n        | CONSTRAINT_CATALOG\n        | CONSTRAINT_SCHEMA\n        | CONSTRAINT_NAME\n        | CATALOG_NAME\n        | SCHEMA_NAME\n        | TABLE_NAME\n        | COLUMN_NAME\n        | CURSOR_NAME\n    ) '=' (stringLiteral | DECIMAL_LITERAL | mysqlVariable | simpleId)\n    ;\n\nwithStatement\n    : WITH RECURSIVE? commonTableExpressions (',' commonTableExpressions)*\n    ;\n\ntableStatement\n    : TABLE tableName orderByClause? limitClause?\n    ;\n\ndiagnosticsStatement\n    : GET (CURRENT | STACKED)? DIAGNOSTICS (\n        (variableClause '=' ( NUMBER | ROW_COUNT) ( ',' variableClause '=' ( NUMBER | ROW_COUNT))*)\n        | (\n            CONDITION (decimalLiteral | variableClause) variableClause '=' diagnosticsConditionInformationName (\n                ',' variableClause '=' diagnosticsConditionInformationName\n            )*\n        )\n    )\n    ;\n\ndiagnosticsConditionInformationName\n    : CLASS_ORIGIN\n    | SUBCLASS_ORIGIN\n    | RETURNED_SQLSTATE\n    | MESSAGE_TEXT\n    | MYSQL_ERRNO\n    | CONSTRAINT_CATALOG\n    | CONSTRAINT_SCHEMA\n    | CONSTRAINT_NAME\n    | CATALOG_NAME\n    | SCHEMA_NAME\n    | TABLE_NAME\n    | COLUMN_NAME\n    | CURSOR_NAME\n    ;\n\n// details\n\ndescribeObjectClause\n    : (selectStatement | deleteStatement | insertStatement | replaceStatement | updateStatement) # describeStatements\n    | FOR CONNECTION uid                                                                         # describeConnection\n    ;\n\n// Common Clauses\n\n//    DB Objects\n\nfullId\n    : uid (DOT_ID | '.' uid)?\n    ;\n\ntableName\n    : fullId\n    ;\n\nroleName\n    : userName\n    | uid\n    ;\n\nfullColumnName\n    : uid (dottedId dottedId?)?\n    | .? dottedId dottedId?\n    ;\n\nindexColumnName\n    : ((uid | STRING_LITERAL) ('(' decimalLiteral ')')? | expression) sortType = (ASC | DESC)?\n    ;\n\nsimpleUserName\n    : STRING_LITERAL\n    | ID\n    | ADMIN\n    | keywordsCanBeId\n    ;\n\nhostName\n    : (LOCAL_ID | HOST_IP_ADDRESS | '@')\n    ;\n\nuserName\n    : simpleUserName\n    | simpleUserName hostName\n    | currentUserExpression\n    ;\n\nmysqlVariable\n    : LOCAL_ID\n    | GLOBAL_ID\n    ;\n\ncharsetName\n    : BINARY\n    | charsetNameBase\n    | STRING_LITERAL\n    | CHARSET_REVERSE_QOUTE_STRING\n    ;\n\ncollationName\n    : uid\n    | STRING_LITERAL\n    ;\n\nengineName\n    : engineNameBase\n    | ID\n    | STRING_LITERAL\n    ;\n\nengineNameBase\n    : ARCHIVE\n    | BLACKHOLE\n    | CONNECT\n    | CSV\n    | FEDERATED\n    | INNODB\n    | MEMORY\n    | MRG_MYISAM\n    | MYISAM\n    | NDB\n    | NDBCLUSTER\n    | PERFORMANCE_SCHEMA\n    | TOKUDB\n    ;\n\nuuidSet\n    : decimalLiteral '-' decimalLiteral '-' decimalLiteral '-' decimalLiteral '-' decimalLiteral (\n        ':' decimalLiteral '-' decimalLiteral\n    )+\n    ;\n\nxid\n    : globalTableUid = xuidStringId (',' qualifier = xuidStringId (',' idFormat = decimalLiteral)?)?\n    ;\n\nxuidStringId\n    : STRING_LITERAL\n    | BIT_STRING\n    | HEXADECIMAL_LITERAL+\n    ;\n\nauthPlugin\n    : uid\n    | STRING_LITERAL\n    ;\n\nuid\n    : simpleId\n    //| DOUBLE_QUOTE_ID\n    //| REVERSE_QUOTE_ID\n    | CHARSET_REVERSE_QOUTE_STRING\n    | STRING_LITERAL\n    ;\n\nsimpleId\n    : ID\n    | charsetNameBase\n    | transactionLevelBase\n    | engineNameBase\n    | privilegesBase\n    | intervalTypeBase\n    | dataTypeBase\n    | keywordsCanBeId\n    | scalarFunctionName\n    ;\n\ndottedId\n    : DOT_ID\n    | '.' uid\n    ;\n\n//    Literals\n\ndecimalLiteral\n    : DECIMAL_LITERAL\n    | ZERO_DECIMAL\n    | ONE_DECIMAL\n    | TWO_DECIMAL\n    | REAL_LITERAL\n    ;\n\nfileSizeLiteral\n    : FILESIZE_LITERAL\n    | decimalLiteral\n    ;\n\nstringLiteral\n    : (STRING_CHARSET_NAME? STRING_LITERAL | START_NATIONAL_STRING_LITERAL) STRING_LITERAL+\n    | (STRING_CHARSET_NAME? STRING_LITERAL | START_NATIONAL_STRING_LITERAL) (COLLATE collationName)?\n    ;\n\nbooleanLiteral\n    : TRUE\n    | FALSE\n    ;\n\nhexadecimalLiteral\n    : STRING_CHARSET_NAME? HEXADECIMAL_LITERAL\n    ;\n\nnullNotnull\n    : NOT? (NULL_LITERAL | NULL_SPEC_LITERAL)\n    ;\n\nconstant\n    : stringLiteral\n    | decimalLiteral\n    | '-' decimalLiteral\n    | hexadecimalLiteral\n    | booleanLiteral\n    | REAL_LITERAL\n    | BIT_STRING\n    | NOT? nullLiteral = (NULL_LITERAL | NULL_SPEC_LITERAL)\n    ;\n\n//    Data Types\n\ndataType\n    : typeName = (\n        CHAR\n        | CHARACTER\n        | VARCHAR\n        | TINYTEXT\n        | TEXT\n        | MEDIUMTEXT\n        | LONGTEXT\n        | NCHAR\n        | NVARCHAR\n        | LONG\n    ) VARYING? lengthOneDimension? BINARY? (charSet charsetName)? (COLLATE collationName | BINARY)? # stringDataType\n    | NATIONAL typeName = (CHAR | CHARACTER) VARYING lengthOneDimension? BINARY?                    # nationalVaryingStringDataType\n    | NATIONAL typeName = (VARCHAR | CHARACTER | CHAR) lengthOneDimension? BINARY?                  # nationalStringDataType\n    | NCHAR typeName = VARCHAR lengthOneDimension? BINARY?                                          # nationalStringDataType\n    | typeName = (\n        TINYINT\n        | SMALLINT\n        | MEDIUMINT\n        | INT\n        | INTEGER\n        | BIGINT\n        | MIDDLEINT\n        | INT1\n        | INT2\n        | INT3\n        | INT4\n        | INT8\n    ) lengthOneDimension? (SIGNED | UNSIGNED | ZEROFILL)*                              # dimensionDataType\n    | typeName = REAL lengthTwoDimension? (SIGNED | UNSIGNED | ZEROFILL)*              # dimensionDataType\n    | typeName = DOUBLE PRECISION? lengthTwoDimension? (SIGNED | UNSIGNED | ZEROFILL)* # dimensionDataType\n    | typeName = (DECIMAL | DEC | FIXED | NUMERIC | FLOAT | FLOAT4 | FLOAT8) lengthTwoOptionalDimension? (\n        SIGNED\n        | UNSIGNED\n        | ZEROFILL\n    )*                                                                                                               # dimensionDataType\n    | typeName = (DATE | TINYBLOB | MEDIUMBLOB | LONGBLOB | BOOL | BOOLEAN | SERIAL)                                 # simpleDataType\n    | typeName = (BIT | TIME | TIMESTAMP | DATETIME | BINARY | VARBINARY | BLOB | YEAR | VECTOR) lengthOneDimension? # dimensionDataType\n    | typeName = (ENUM | SET) collectionOptions BINARY? (charSet charsetName)?                                       # collectionDataType\n    | typeName = (\n        GEOMETRYCOLLECTION\n        | GEOMCOLLECTION\n        | LINESTRING\n        | MULTILINESTRING\n        | MULTIPOINT\n        | MULTIPOLYGON\n        | POINT\n        | POLYGON\n        | JSON\n        | GEOMETRY\n    ) (SRID decimalLiteral)?                                                           # spatialDataType\n    | typeName = LONG VARCHAR? BINARY? (charSet charsetName)? (COLLATE collationName)? # longVarcharDataType // LONG VARCHAR is the same as LONG\n    | LONG VARBINARY                                                                   # longVarbinaryDataType\n    ;\n\ncollectionOptions\n    : '(' collectionOption (',' collectionOption)* ')'\n    ;\n\ncollectionOption\n    : STRING_LITERAL\n    ;\n\nconvertedDataType\n    : (\n        typeName = (BINARY | NCHAR | FLOAT) lengthOneDimension?\n        | typeName = CHAR lengthOneDimension? (charSet charsetName)?\n        | typeName = (DATE | DATETIME | TIME | YEAR | JSON | INT | INTEGER | DOUBLE)\n        | typeName = (DECIMAL | DEC) lengthTwoOptionalDimension?\n        | (SIGNED | UNSIGNED) (INTEGER | INT)?\n    ) ARRAY?\n    ;\n\nlengthOneDimension\n    : '(' decimalLiteral ')'\n    ;\n\nlengthTwoDimension\n    : '(' decimalLiteral ',' decimalLiteral ')'\n    ;\n\nlengthTwoOptionalDimension\n    : '(' decimalLiteral (',' decimalLiteral)? ')'\n    ;\n\n//    Common Lists\n\nuidList\n    : uid (',' uid)*\n    ;\n\nfullColumnNameList\n    : fullColumnName (',' fullColumnName)*\n    ;\n\ntables\n    : tableName (',' tableName)*\n    ;\n\nindexColumnNames\n    : '(' indexColumnName (',' indexColumnName)* ')'\n    ;\n\nexpressions\n    : expression (',' expression)*\n    ;\n\nexpressionsWithDefaults\n    : expressionOrDefault (',' expressionOrDefault)*\n    ;\n\nconstants\n    : constant (',' constant)*\n    ;\n\nsimpleStrings\n    : STRING_LITERAL (',' STRING_LITERAL)*\n    ;\n\nuserVariables\n    : LOCAL_ID (',' LOCAL_ID)*\n    ;\n\n//    Common Expressons\n\ndefaultValue\n    : NULL_LITERAL\n    | CAST '(' expression AS convertedDataType ')'\n    | unaryOperator? constant\n    | currentTimestamp (ON UPDATE currentTimestamp)?\n    | '(' expression ')'\n    | '(' fullId ')'\n    ;\n\ncurrentTimestamp\n    : (\n        (CURRENT_TIMESTAMP | LOCALTIME | LOCALTIMESTAMP) ('(' decimalLiteral? ')')?\n        | NOW '(' decimalLiteral? ')'\n    )\n    ;\n\nexpressionOrDefault\n    : expression\n    | DEFAULT\n    ;\n\nifExists\n    : IF EXISTS\n    ;\n\nifNotExists\n    : IF NOT EXISTS\n    ;\n\norReplace\n    : OR REPLACE\n    ;\n\n//    Functions\n\nfunctionCall\n    : specificFunction                         # specificFunctionCall\n    | aggregateWindowedFunction                # aggregateFunctionCall\n    | nonAggregateWindowedFunction             # nonAggregateFunctionCall\n    | scalarFunctionName '(' functionArgs? ')' # scalarFunctionCall\n    | fullId '(' functionArgs? ')'             # udfFunctionCall\n    | passwordFunctionClause                   # passwordFunctionCall\n    ;\n\nspecificFunction\n    : (CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP | LOCALTIME | UTC_TIMESTAMP | SCHEMA) (\n        '(' ')'\n    )?                                                                       # simpleFunctionCall\n    | currentUserExpression                                                  # currentUser\n    | CONVERT '(' expression separator = ',' convertedDataType ')'           # dataTypeFunctionCall\n    | CONVERT '(' expression USING charsetName ')'                           # dataTypeFunctionCall\n    | CAST '(' expression AS convertedDataType ')'                           # dataTypeFunctionCall\n    | VALUES '(' fullColumnName ')'                                          # valuesFunctionCall\n    | CASE expression caseFuncAlternative+ (ELSE elseArg = functionArg)? END # caseExpressionFunctionCall\n    | CASE caseFuncAlternative+ (ELSE elseArg = functionArg)? END            # caseFunctionCall\n    | CHAR '(' functionArgs (USING charsetName)? ')'                         # charFunctionCall\n    | POSITION '(' (positionString = stringLiteral | positionExpression = expression) IN (\n        inString = stringLiteral\n        | inExpression = expression\n    ) ')' # positionFunctionCall\n    | (SUBSTR | SUBSTRING) '(' (sourceString = stringLiteral | sourceExpression = expression) FROM (\n        fromDecimal = decimalLiteral\n        | fromExpression = expression\n    ) (FOR ( forDecimal = decimalLiteral | forExpression = expression))? ')' # substrFunctionCall\n    | TRIM '(' positioinForm = (BOTH | LEADING | TRAILING) (\n        sourceString = stringLiteral\n        | sourceExpression = expression\n    )? FROM (fromString = stringLiteral | fromExpression = expression) ')' # trimFunctionCall\n    | TRIM '(' (sourceString = stringLiteral | sourceExpression = expression) FROM (\n        fromString = stringLiteral\n        | fromExpression = expression\n    ) ')' # trimFunctionCall\n    | WEIGHT_STRING '(' (stringLiteral | expression) (\n        AS stringFormat = (CHAR | BINARY) '(' decimalLiteral ')'\n    )? levelsInWeightString? ')'                                                                            # weightFunctionCall\n    | EXTRACT '(' intervalType FROM (sourceString = stringLiteral | sourceExpression = expression) ')'      # extractFunctionCall\n    | GET_FORMAT '(' datetimeFormat = (DATE | TIME | DATETIME) ',' stringLiteral ')'                        # getFormatFunctionCall\n    | JSON_VALUE '(' expression ',' expression (RETURNING convertedDataType)? jsonOnEmpty? jsonOnError? ')' # jsonValueFunctionCall\n    ;\n\ncaseFuncAlternative\n    : WHEN condition = functionArg THEN consequent = functionArg\n    ;\n\nlevelsInWeightString\n    : LEVEL levelInWeightListElement (',' levelInWeightListElement)*   # levelWeightList\n    | LEVEL firstLevel = decimalLiteral '-' lastLevel = decimalLiteral # levelWeightRange\n    ;\n\nlevelInWeightListElement\n    : decimalLiteral orderType = (ASC | DESC | REVERSE)?\n    ;\n\naggregateWindowedFunction\n    : (AVG | MAX | MIN | SUM) '(' aggregator = (ALL | DISTINCT)? functionArg ')' overClause?\n    | COUNT '(' (\n        starArg = '*'\n        | aggregator = ALL? functionArg\n        | aggregator = DISTINCT functionArgs\n    ) ')' overClause?\n    | (\n        BIT_AND\n        | BIT_OR\n        | BIT_XOR\n        | STD\n        | STDDEV\n        | STDDEV_POP\n        | STDDEV_SAMP\n        | VAR_POP\n        | VAR_SAMP\n        | VARIANCE\n    ) '(' aggregator = ALL? functionArg ')' overClause?\n    | GROUP_CONCAT '(' aggregator = DISTINCT? functionArgs (\n        ORDER BY orderByExpression (',' orderByExpression)*\n    )? (SEPARATOR separator = STRING_LITERAL)? ')'\n    ;\n\nnonAggregateWindowedFunction\n    : (LAG | LEAD) '(' expression (',' decimalLiteral)? (',' (decimalLiteral | NULL_LITERAL))? ')' overClause\n    | (FIRST_VALUE | LAST_VALUE) '(' expression ')' overClause\n    | (CUME_DIST | DENSE_RANK | PERCENT_RANK | RANK | ROW_NUMBER) '(' ')' overClause\n    | NTH_VALUE '(' expression ',' decimalLiteral ')' overClause\n    | NTILE '(' decimalLiteral ')' overClause\n    ;\n\noverClause\n    : OVER ('(' windowSpec? ')' | windowName)\n    ;\n\nwindowSpec\n    : windowName? partitionClause? orderByClause? frameClause?\n    ;\n\nwindowName\n    : uid\n    ;\n\nframeClause\n    : frameUnits frameExtent\n    ;\n\nframeUnits\n    : ROWS\n    | RANGE\n    ;\n\nframeExtent\n    : frameRange\n    | frameBetween\n    ;\n\nframeBetween\n    : BETWEEN frameRange AND frameRange\n    ;\n\nframeRange\n    : CURRENT ROW\n    | UNBOUNDED (PRECEDING | FOLLOWING)\n    | expression (PRECEDING | FOLLOWING)\n    ;\n\npartitionClause\n    : PARTITION BY expression (',' expression)*\n    ;\n\nsequenceFunctionName\n    : SEQUENCE_TABLE\n    | PERCONA_SEQUENCE_TABLE\n    ;\n\nscalarFunctionName\n    : functionNameBase\n    | ASCII\n    | CURDATE\n    | CURRENT_DATE\n    | CURRENT_TIME\n    | CURRENT_TIMESTAMP\n    | CURTIME\n    | DATE_ADD\n    | DATE_SUB\n    | IF\n    | INSERT\n    | LOCALTIME\n    | LOCALTIMESTAMP\n    | MID\n    | NOW\n    | REPEAT\n    | REPLACE\n    | SUBSTR\n    | SUBSTRING\n    | SYSDATE\n    | TRIM\n    | UTC_DATE\n    | UTC_TIME\n    | UTC_TIMESTAMP\n    ;\n\npasswordFunctionClause\n    : functionName = (PASSWORD | OLD_PASSWORD) '(' functionArg ')'\n    ;\n\nfunctionArgs\n    : (constant | fullColumnName | functionCall | expression) (\n        ',' (constant | fullColumnName | functionCall | expression)\n    )*\n    ;\n\nfunctionArg\n    : constant\n    | fullColumnName\n    | functionCall\n    | expression\n    ;\n\n//    Expressions, predicates\n\n// Simplified approach for expression\nexpression\n    : notOperator = (NOT | '!') expression                   # notExpression\n    | expression logicalOperator expression                  # logicalExpression\n    | predicate IS NOT? testValue = (TRUE | FALSE | UNKNOWN) # isExpression\n    | predicate                                              # predicateExpression\n    ;\n\npredicate\n    : predicate NOT? IN '(' (selectStatement | expressions) ')'                            # inPredicate\n    | predicate IS nullNotnull                                                             # isNullPredicate\n    | left = predicate comparisonOperator right = predicate                                # binaryComparisonPredicate\n    | predicate comparisonOperator quantifier = (ALL | ANY | SOME) '(' selectStatement ')' # subqueryComparisonPredicate\n    | predicate NOT? BETWEEN predicate AND predicate                                       # betweenPredicate\n    | predicate SOUNDS LIKE predicate                                                      # soundsLikePredicate\n    | predicate NOT? LIKE predicate (ESCAPE STRING_LITERAL)?                               # likePredicate\n    | predicate NOT? regex = (REGEXP | RLIKE) predicate                                    # regexpPredicate\n    | predicate MEMBER OF '(' predicate ')'                                                # jsonMemberOfPredicate\n    | expressionAtom                                                                       # expressionAtomPredicate\n    ;\n\n// Add in ASTVisitor nullNotnull in constant\nexpressionAtom\n    : constant                                                  # constantExpressionAtom\n    | fullColumnName                                            # fullColumnNameExpressionAtom\n    | functionCall                                              # functionCallExpressionAtom\n    | expressionAtom COLLATE collationName                      # collateExpressionAtom\n    | mysqlVariable                                             # mysqlVariableExpressionAtom\n    | unaryOperator expressionAtom                              # unaryExpressionAtom\n    | BINARY expressionAtom                                     # binaryExpressionAtom\n    | LOCAL_ID VAR_ASSIGN expressionAtom                        # variableAssignExpressionAtom\n    | '(' expression (',' expression)* ')'                      # nestedExpressionAtom\n    | ROW '(' expression (',' expression)+ ')'                  # nestedRowExpressionAtom\n    | EXISTS '(' selectStatement ')'                            # existsExpressionAtom\n    | '(' selectStatement ')'                                   # subqueryExpressionAtom\n    | INTERVAL expression intervalType                          # intervalExpressionAtom\n    | left = expressionAtom bitOperator right = expressionAtom  # bitExpressionAtom\n    | left = expressionAtom multOperator right = expressionAtom # mathExpressionAtom\n    | left = expressionAtom addOperator right = expressionAtom  # mathExpressionAtom\n    | left = expressionAtom jsonOperator right = expressionAtom # jsonExpressionAtom\n    ;\n\nunaryOperator\n    : '!'\n    | '~'\n    | '+'\n    | '-'\n    | NOT\n    ;\n\ncomparisonOperator\n    : '='\n    | '>'\n    | '<'\n    | '<' '='\n    | '>' '='\n    | '<' '>'\n    | '!' '='\n    | '<' '=' '>'\n    ;\n\nlogicalOperator\n    : AND\n    | '&' '&'\n    | XOR\n    | OR\n    | '|' '|'\n    ;\n\nbitOperator\n    : '<' '<'\n    | '>' '>'\n    | '&'\n    | '^'\n    | '|'\n    ;\n\nmultOperator\n    : '*'\n    | '/'\n    | '%'\n    | DIV\n    | MOD\n    ;\n\naddOperator\n    : '+'\n    | '-'\n    ;\n\njsonOperator\n    : '-' '>'\n    | '-' '>' '>'\n    ;\n\n//    Simple id sets\n//     (that keyword, which can be id)\n\ncharsetNameBase\n    : ARMSCII8\n    | ASCII\n    | BIG5\n    | BINARY\n    | CP1250\n    | CP1251\n    | CP1256\n    | CP1257\n    | CP850\n    | CP852\n    | CP866\n    | CP932\n    | DEC8\n    | EUCJPMS\n    | EUCKR\n    | GB18030\n    | GB2312\n    | GBK\n    | GEOSTD8\n    | GREEK\n    | HEBREW\n    | HP8\n    | KEYBCS2\n    | KOI8R\n    | KOI8U\n    | LATIN1\n    | LATIN2\n    | LATIN5\n    | LATIN7\n    | MACCE\n    | MACROMAN\n    | SJIS\n    | SWE7\n    | TIS620\n    | UCS2\n    | UJIS\n    | UTF16\n    | UTF16LE\n    | UTF32\n    | UTF8\n    | UTF8MB3\n    | UTF8MB4\n    ;\n\ntransactionLevelBase\n    : REPEATABLE\n    | COMMITTED\n    | UNCOMMITTED\n    | SERIALIZABLE\n    ;\n\nprivilegesBase\n    : TABLES\n    | ROUTINE\n    | EXECUTE\n    | FILE\n    | PROCESS\n    | RELOAD\n    | SHUTDOWN\n    | SUPER\n    | PRIVILEGES\n    ;\n\nintervalTypeBase\n    : QUARTER\n    | MONTH\n    | DAY\n    | HOUR\n    | MINUTE\n    | WEEK\n    | SECOND\n    | MICROSECOND\n    ;\n\ndataTypeBase\n    : DATE\n    | TIME\n    | TIMESTAMP\n    | DATETIME\n    | YEAR\n    | ENUM\n    | TEXT\n    ;\n\nkeywordsCanBeId\n    : ACCOUNT\n    | ACTION\n    | ADMIN\n    | AFTER\n    | AGGREGATE\n    | ALGORITHM\n    | ANY\n    | APPLICATION_PASSWORD_ADMIN\n    | ARRAY\n    | AT\n    | AUDIT_ADMIN\n    | AUDIT_ABORT_EXEMPT\n    | AUTHORS\n    | AUTOCOMMIT\n    | AUTOEXTEND_SIZE\n    | AUTO_INCREMENT\n    | AUTHENTICATION_POLICY_ADMIN\n    | AVG\n    | AVG_ROW_LENGTH\n    | ATTRIBUTE\n    | BACKUP_ADMIN\n    | BEGIN\n    | BINLOG\n    | BINLOG_ADMIN\n    | BINLOG_ENCRYPTION_ADMIN\n    | BIT\n    | BIT_AND\n    | BIT_OR\n    | BIT_XOR\n    | BLOCK\n    | BOOL\n    | BOOLEAN\n    | BTREE\n    | BUCKETS\n    | CACHE\n    | CASCADED\n    | CHAIN\n    | CHANGED\n    | CHANNEL\n    | CHECKSUM\n    | PAGE_CHECKSUM\n    | CATALOG_NAME\n    | CIPHER\n    | CLASS_ORIGIN\n    | CLIENT\n    | CLONE_ADMIN\n    | CLOSE\n    | CLUSTERING\n    | COALESCE\n    | CODE\n    | COLUMNS\n    | COLUMN_FORMAT\n    | COLUMN_NAME\n    | COMMENT\n    | COMMIT\n    | COMPACT\n    | COMPLETION\n    | COMPRESSED\n    | COMPRESSION\n    | CONCURRENT\n    | CONDITION\n    | CONNECT\n    | CONNECTION\n    | CONNECTION_ADMIN\n    | CONSISTENT\n    | CONSTRAINT_CATALOG\n    | CONSTRAINT_NAME\n    | CONSTRAINT_SCHEMA\n    | CONTAINS\n    | CONTEXT\n    | CONTRIBUTORS\n    | COPY\n    | COUNT\n    | CPU\n    | CURRENT\n    | CURRENT_USER\n    | CURSOR_NAME\n    | DATA\n    | DATAFILE\n    | DEALLOCATE\n    | DEFAULT\n    | DEFAULT_AUTH\n    | DEFINER\n    | DELAY_KEY_WRITE\n    | DES_KEY_FILE\n    | DIAGNOSTICS\n    | DIRECTORY\n    | DISABLE\n    | DISCARD\n    | DISK\n    | DO\n    | DUMPFILE\n    | DUPLICATE\n    | DYNAMIC\n    | EMPTY\n    | ENABLE\n    | ENCRYPTION\n    | ENCRYPTION_KEY_ADMIN\n    | END\n    | ENDS\n    | ENGINE\n    | ENGINE_ATTRIBUTE\n    | ENGINES\n    | ENFORCED\n    | ERROR\n    | ERRORS\n    | ESCAPE\n    | EUR\n    | EVEN\n    | EVENT\n    | EVENTS\n    | EVERY\n    | EXCEPT\n    | EXCHANGE\n    | EXCLUSIVE\n    | EXPIRE\n    | EXPORT\n    | EXTENDED\n    | EXTENT_SIZE\n    | FAILED_LOGIN_ATTEMPTS\n    | FAST\n    | FAULTS\n    | FIELDS\n    | FILE_BLOCK_SIZE\n    | FILTER\n    | FIREWALL_ADMIN\n    | FIREWALL_EXEMPT\n    | FIREWALL_USER\n    | FIRST\n    | FIXED\n    | FLUSH\n    | FLUSH_OPTIMIZER_COSTS\n    | FLUSH_STATUS\n    | FLUSH_TABLES\n    | FLUSH_USER_RESOURCES\n    | FOLLOWS\n    | FOUND\n    | FULL\n    | FUNCTION\n    | GENERAL\n    | GEOMETRY\n    | GLOBAL\n    | GRANTS\n    | GROUP\n    | GROUP_CONCAT\n    | GROUP_REPLICATION\n    | GROUP_REPLICATION_ADMIN\n    | HANDLER\n    | HASH\n    | HELP\n    | HISTORY\n    | HOST\n    | HOSTS\n    | IDENTIFIED\n    | IGNORED\n    | IGNORE_SERVER_IDS\n    | IMPORT\n    | INDEXES\n    | INITIAL_SIZE\n    | INNODB_REDO_LOG_ARCHIVE\n    | INNODB_REDO_LOG_ENABLE\n    | INPLACE\n    | INSERT_METHOD\n    | INSTALL\n    | INSTANCE\n    | INSTANT\n    | INTERNAL\n    | INVOKE\n    | INVOKER\n    | IO\n    | IO_THREAD\n    | IPC\n    | ISO\n    | ISOLATION\n    | ISSUER\n    | JIS\n    | JSON\n    | KEY_BLOCK_SIZE\n    | LAMBDA\n    | LANGUAGE\n    | LAST\n    | LATERAL\n    | LEAVES\n    | LESS\n    | LEVEL\n    | LIST\n    | LOCAL\n    | LOGFILE\n    | LOGS\n    | MASTER\n    | MASTER_AUTO_POSITION\n    | MASTER_CONNECT_RETRY\n    | MASTER_DELAY\n    | MASTER_HEARTBEAT_PERIOD\n    | MASTER_HOST\n    | MASTER_LOG_FILE\n    | MASTER_LOG_POS\n    | MASTER_PASSWORD\n    | MASTER_PORT\n    | MASTER_RETRY_COUNT\n    | MASTER_SSL\n    | MASTER_SSL_CA\n    | MASTER_SSL_CAPATH\n    | MASTER_SSL_CERT\n    | MASTER_SSL_CIPHER\n    | MASTER_SSL_CRL\n    | MASTER_SSL_CRLPATH\n    | MASTER_SSL_KEY\n    | MASTER_TLS_VERSION\n    | MASTER_USER\n    | MAX_CONNECTIONS_PER_HOUR\n    | MAX_QUERIES_PER_HOUR\n    | MAX\n    | MAX_ROWS\n    | MAX_SIZE\n    | MAX_UPDATES_PER_HOUR\n    | MAX_USER_CONNECTIONS\n    | MEDIUM\n    | MEMBER\n    | MEMORY\n    | MERGE\n    | MESSAGE_TEXT\n    | MID\n    | MIGRATE\n    | MIN\n    | MIN_ROWS\n    | MODE\n    | MODIFY\n    | MUTEX\n    | MYSQL\n    | MYSQL_ERRNO\n    | NAME\n    | NAMES\n    | NATIONAL\n    | NCHAR\n    | NDB_STORED_USER\n    | NESTED\n    | NEVER\n    | NEXT\n    | NO\n    | NOCOPY\n    | NODEGROUP\n    | NONE\n    | NOWAIT\n    | NUMBER\n    | ODBC\n    | OFFLINE\n    | OFFSET\n    | OF\n    | OJ\n    | OLD_PASSWORD\n    | ONE\n    | ONLINE\n    | ONLY\n    | OPEN\n    | OPTIMIZER_COSTS\n    | OPTIONAL\n    | OPTIONS\n    | ORDER\n    | ORDINALITY\n    | OWNER\n    | PACK_KEYS\n    | PAGE\n    | PARSER\n    | PARTIAL\n    | PARTITIONING\n    | PARTITIONS\n    | PASSWORD\n    | PASSWORDLESS_USER_ADMIN\n    | PASSWORD_LOCK_TIME\n    | PATH\n    | PERCONA_SEQUENCE_TABLE\n    | PERSIST_RO_VARIABLES_ADMIN\n    | PHASE\n    | PLUGINS\n    | PLUGIN_DIR\n    | PLUGIN\n    | PORT\n    | PRECEDES\n    | PREPARE\n    | PRESERVE\n    | PREV\n    | PRIMARY\n    | PROCESSLIST\n    | PROFILE\n    | PROFILES\n    | PROXY\n    | QUERY\n    | QUICK\n    | REBUILD\n    | RECOVER\n    | RECURSIVE\n    | REDO_BUFFER_SIZE\n    | REDUNDANT\n    | RELAY\n    | RELAYLOG\n    | RELAY_LOG_FILE\n    | RELAY_LOG_POS\n    | REMOVE\n    | REORGANIZE\n    | REPAIR\n    | REPLICATE_DO_DB\n    | REPLICATE_DO_TABLE\n    | REPLICATE_IGNORE_DB\n    | REPLICATE_IGNORE_TABLE\n    | REPLICATE_REWRITE_DB\n    | REPLICATE_WILD_DO_TABLE\n    | REPLICATE_WILD_IGNORE_TABLE\n    | REPLICATION\n    | REPLICATION_APPLIER\n    | REPLICATION_SLAVE_ADMIN\n    | RESET\n    | RESOURCE_GROUP_ADMIN\n    | RESOURCE_GROUP_USER\n    | RESUME\n    | RETURNED_SQLSTATE\n    | RETURNING\n    | RETURNS\n    | REUSE\n    | ROLE\n    | ROLE_ADMIN\n    | ROLLBACK\n    | ROLLUP\n    | ROTATE\n    | ROW\n    | ROWS\n    | ROW_FORMAT\n    | RTREE\n    | S3\n    | SAVEPOINT\n    | SCHEDULE\n    | SCHEMA_NAME\n    | SECURITY\n    | SECONDARY_ENGINE_ATTRIBUTE\n    | SEQUENCE_TABLE\n    | SERIAL\n    | SERVER\n    | SESSION\n    | SESSION_VARIABLES_ADMIN\n    | SET_USER_ID\n    | SHARE\n    | SHARED\n    | SHOW_ROUTINE\n    | SIGNED\n    | SIMPLE\n    | SLAVE\n    | SLOW\n    | SKIP_QUERY_REWRITE\n    | SNAPSHOT\n    | SOCKET\n    | SOME\n    | SONAME\n    | SOUNDS\n    | SOURCE\n    | SQL_AFTER_GTIDS\n    | SQL_AFTER_MTS_GAPS\n    | SQL_BEFORE_GTIDS\n    | SQL_BUFFER_RESULT\n    | SQL_CACHE\n    | SQL_NO_CACHE\n    | SQL_THREAD\n    | STACKED\n    | START\n    | STARTS\n    | STATS_AUTO_RECALC\n    | STATS_PERSISTENT\n    | STATS_SAMPLE_PAGES\n    | STATUS\n    | STD\n    | STDDEV\n    | STDDEV_POP\n    | STDDEV_SAMP\n    | STOP\n    | STORAGE\n    | STRING\n    | SUBCLASS_ORIGIN\n    | SUBJECT\n    | SUBPARTITION\n    | SUBPARTITIONS\n    | SUM\n    | SUSPEND\n    | SWAPS\n    | SWITCHES\n    | SYSTEM_VARIABLES_ADMIN\n    | SYSTEM_USER\n    | TABLE_NAME\n    | TABLESPACE\n    | TABLE_ENCRYPTION_ADMIN\n    | TABLE_TYPE\n    | TELEMETRY_LOG_ADMIN\n    | TEMPORARY\n    | TEMPTABLE\n    | THAN\n    | TP_CONNECTION_ADMIN\n    | TRADITIONAL\n    | TRANSACTION\n    | TRANSACTIONAL\n    | TRIGGERS\n    | TRUNCATE\n    | UNBOUNDED\n    | UNDEFINED\n    | UNDOFILE\n    | UNDO_BUFFER_SIZE\n    | UNINSTALL\n    | UNKNOWN\n    | UNTIL\n    | UPGRADE\n    | USA\n    | USER\n    | USE_FRM\n    | USER_RESOURCES\n    | VALIDATION\n    | VALUE\n    | VAR_POP\n    | VAR_SAMP\n    | VARIABLES\n    | VARIANCE\n    | VERSION_TOKEN_ADMIN\n    | VIEW\n    | VIRTUAL\n    | WAIT\n    | WARNINGS\n    | WITHOUT\n    | WORK\n    | WRAPPER\n    | X509\n    | XA\n    | XA_RECOVER_ADMIN\n    | XML\n    | YES\n    ;\n\nfunctionNameBase\n    : ABS\n    | ACOS\n    | ADDDATE\n    | ADDTIME\n    | AES_DECRYPT\n    | AES_ENCRYPT\n    | AREA\n    | ASBINARY\n    | ASIN\n    | ASTEXT\n    | ASWKB\n    | ASWKT\n    | ASYMMETRIC_DECRYPT\n    | ASYMMETRIC_DERIVE\n    | ASYMMETRIC_ENCRYPT\n    | ASYMMETRIC_SIGN\n    | ASYMMETRIC_VERIFY\n    | ATAN\n    | ATAN2\n    | BENCHMARK\n    | BIN\n    | BIT_COUNT\n    | BIT_LENGTH\n    | BUFFER\n    | CEIL\n    | CEILING\n    | CENTROID\n    | CHARACTER_LENGTH\n    | CHARSET\n    | CHAR_LENGTH\n    | COERCIBILITY\n    | COLLATION\n    | COMPRESS\n    | CONCAT\n    | CONCAT_WS\n    | CONNECTION_ID\n    | CONV\n    | CONVERT_TZ\n    | COS\n    | COT\n    | COUNT\n    | CRC32\n    | CREATE_ASYMMETRIC_PRIV_KEY\n    | CREATE_ASYMMETRIC_PUB_KEY\n    | CREATE_DH_PARAMETERS\n    | CREATE_DIGEST\n    | CROSSES\n    | CUME_DIST\n    | DATABASE\n    | DATE\n    | DATEDIFF\n    | DATE_FORMAT\n    | DAY\n    | DAYNAME\n    | DAYOFMONTH\n    | DAYOFWEEK\n    | DAYOFYEAR\n    | DECODE\n    | DEGREES\n    | DENSE_RANK\n    | DES_DECRYPT\n    | DES_ENCRYPT\n    | DIMENSION\n    | DISJOINT\n    | DISTANCE\n    | ELT\n    | ENCODE\n    | ENCRYPT\n    | ENDPOINT\n    | ENVELOPE\n    | EQUALS\n    | EXP\n    | EXPORT_SET\n    | EXTERIORRING\n    | EXTRACTVALUE\n    | FIELD\n    | FIND_IN_SET\n    | FIRST_VALUE\n    | FLOOR\n    | FORMAT\n    | FOUND_ROWS\n    | FROM_BASE64\n    | FROM_DAYS\n    | FROM_UNIXTIME\n    | GEOMCOLLFROMTEXT\n    | GEOMCOLLFROMWKB\n    | GEOMETRYCOLLECTION\n    | GEOMETRYCOLLECTIONFROMTEXT\n    | GEOMETRYCOLLECTIONFROMWKB\n    | GEOMETRYFROMTEXT\n    | GEOMETRYFROMWKB\n    | GEOMETRYN\n    | GEOMETRYTYPE\n    | GEOMFROMTEXT\n    | GEOMFROMWKB\n    | GET_FORMAT\n    | GET_LOCK\n    | GLENGTH\n    | GREATEST\n    | GTID_SUBSET\n    | GTID_SUBTRACT\n    | HEX\n    | HOUR\n    | IFNULL\n    | INET6_ATON\n    | INET6_NTOA\n    | INET_ATON\n    | INET_NTOA\n    | INSTR\n    | INTERIORRINGN\n    | INTERSECTS\n    | INVISIBLE\n    | ISCLOSED\n    | ISEMPTY\n    | ISNULL\n    | ISSIMPLE\n    | IS_FREE_LOCK\n    | IS_IPV4\n    | IS_IPV4_COMPAT\n    | IS_IPV4_MAPPED\n    | IS_IPV6\n    | IS_USED_LOCK\n    | LAG\n    | LAST_INSERT_ID\n    | LAST_VALUE\n    | LCASE\n    | LEAD\n    | LEAST\n    | LEFT\n    | LENGTH\n    | LINEFROMTEXT\n    | LINEFROMWKB\n    | LINESTRING\n    | LINESTRINGFROMTEXT\n    | LINESTRINGFROMWKB\n    | LN\n    | LOAD_FILE\n    | LOCATE\n    | LOG\n    | LOG10\n    | LOG2\n    | LOWER\n    | LPAD\n    | LTRIM\n    | MAKEDATE\n    | MAKETIME\n    | MAKE_SET\n    | MASTER_POS_WAIT\n    | MBRCONTAINS\n    | MBRDISJOINT\n    | MBREQUAL\n    | MBRINTERSECTS\n    | MBROVERLAPS\n    | MBRTOUCHES\n    | MBRWITHIN\n    | MD5\n    | MICROSECOND\n    | MINUTE\n    | MLINEFROMTEXT\n    | MLINEFROMWKB\n    | MOD\n    | MONTH\n    | MONTHNAME\n    | MPOINTFROMTEXT\n    | MPOINTFROMWKB\n    | MPOLYFROMTEXT\n    | MPOLYFROMWKB\n    | MULTILINESTRING\n    | MULTILINESTRINGFROMTEXT\n    | MULTILINESTRINGFROMWKB\n    | MULTIPOINT\n    | MULTIPOINTFROMTEXT\n    | MULTIPOINTFROMWKB\n    | MULTIPOLYGON\n    | MULTIPOLYGONFROMTEXT\n    | MULTIPOLYGONFROMWKB\n    | NAME_CONST\n    | NTH_VALUE\n    | NTILE\n    | NULLIF\n    | NUMGEOMETRIES\n    | NUMINTERIORRINGS\n    | NUMPOINTS\n    | OCT\n    | OCTET_LENGTH\n    | ORD\n    | OVERLAPS\n    | PERCENT_RANK\n    | PERIOD_ADD\n    | PERIOD_DIFF\n    | PI\n    | POINT\n    | POINTFROMTEXT\n    | POINTFROMWKB\n    | POINTN\n    | POLYFROMTEXT\n    | POLYFROMWKB\n    | POLYGON\n    | POLYGONFROMTEXT\n    | POLYGONFROMWKB\n    | POSITION\n    | POW\n    | POWER\n    | QUARTER\n    | QUOTE\n    | RADIANS\n    | RAND\n    | RANDOM\n    | RANK\n    | RANDOM_BYTES\n    | RELEASE_LOCK\n    | REVERSE\n    | RIGHT\n    | ROUND\n    | ROW_COUNT\n    | ROW_NUMBER\n    | RPAD\n    | RTRIM\n    | SCHEMA\n    | SECOND\n    | SEC_TO_TIME\n    | SESSION_USER\n    | SESSION_VARIABLES_ADMIN\n    | SHA\n    | SHA1\n    | SHA2\n    | SIGN\n    | SIN\n    | SLEEP\n    | SOUNDEX\n    | SQL_THREAD_WAIT_AFTER_GTIDS\n    | SQRT\n    | SRID\n    | STARTPOINT\n    | STRCMP\n    | STR_TO_DATE\n    | ST_AREA\n    | ST_ASBINARY\n    | ST_ASTEXT\n    | ST_ASWKB\n    | ST_ASWKT\n    | ST_BUFFER\n    | ST_CENTROID\n    | ST_CONTAINS\n    | ST_CROSSES\n    | ST_DIFFERENCE\n    | ST_DIMENSION\n    | ST_DISJOINT\n    | ST_DISTANCE\n    | ST_ENDPOINT\n    | ST_ENVELOPE\n    | ST_EQUALS\n    | ST_EXTERIORRING\n    | ST_GEOMCOLLFROMTEXT\n    | ST_GEOMCOLLFROMTXT\n    | ST_GEOMCOLLFROMWKB\n    | ST_GEOMETRYCOLLECTIONFROMTEXT\n    | ST_GEOMETRYCOLLECTIONFROMWKB\n    | ST_GEOMETRYFROMTEXT\n    | ST_GEOMETRYFROMWKB\n    | ST_GEOMETRYN\n    | ST_GEOMETRYTYPE\n    | ST_GEOMFROMTEXT\n    | ST_GEOMFROMWKB\n    | ST_INTERIORRINGN\n    | ST_INTERSECTION\n    | ST_INTERSECTS\n    | ST_ISCLOSED\n    | ST_ISEMPTY\n    | ST_ISSIMPLE\n    | ST_LINEFROMTEXT\n    | ST_LINEFROMWKB\n    | ST_LINESTRINGFROMTEXT\n    | ST_LINESTRINGFROMWKB\n    | ST_NUMGEOMETRIES\n    | ST_NUMINTERIORRING\n    | ST_NUMINTERIORRINGS\n    | ST_NUMPOINTS\n    | ST_OVERLAPS\n    | ST_POINTFROMTEXT\n    | ST_POINTFROMWKB\n    | ST_POINTN\n    | ST_POLYFROMTEXT\n    | ST_POLYFROMWKB\n    | ST_POLYGONFROMTEXT\n    | ST_POLYGONFROMWKB\n    | ST_SRID\n    | ST_STARTPOINT\n    | ST_SYMDIFFERENCE\n    | ST_TOUCHES\n    | ST_UNION\n    | ST_WITHIN\n    | ST_X\n    | ST_Y\n    | STRING_TO_VECTOR\n    | SUBDATE\n    | SUBSTRING_INDEX\n    | SUBTIME\n    | SYSTEM_USER\n    | TAN\n    | TIME\n    | TIMEDIFF\n    | TIMESTAMP\n    | TIMESTAMPADD\n    | TIMESTAMPDIFF\n    | TIME_FORMAT\n    | TIME_TO_SEC\n    | TOUCHES\n    | TO_BASE64\n    | TO_DAYS\n    | TO_SECONDS\n    | UCASE\n    | UNCOMPRESS\n    | UNCOMPRESSED_LENGTH\n    | UNHEX\n    | UNIX_TIMESTAMP\n    | UPDATEXML\n    | UPPER\n    | UUID\n    | UUID_SHORT\n    | VALIDATE_PASSWORD_STRENGTH\n    | VECTOR_DIM\n    | VECTOR_TO_STRING\n    | VERSION\n    | VISIBLE\n    | WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS\n    | WEEK\n    | WEEKDAY\n    | WEEKOFYEAR\n    | WEIGHT_STRING\n    | WITHIN\n    | YEAR\n    | YEARWEEK\n    | Y_FUNCTION\n    | X_FUNCTION\n    | JSON_ARRAY\n    | JSON_OBJECT\n    | JSON_QUOTE\n    | JSON_CONTAINS\n    | JSON_CONTAINS_PATH\n    | JSON_EXTRACT\n    | JSON_KEYS\n    | JSON_OVERLAPS\n    | JSON_SEARCH\n    | JSON_VALUE\n    | JSON_ARRAY_APPEND\n    | JSON_ARRAY_INSERT\n    | JSON_INSERT\n    | JSON_MERGE\n    | JSON_MERGE_PATCH\n    | JSON_MERGE_PRESERVE\n    | JSON_REMOVE\n    | JSON_REPLACE\n    | JSON_SET\n    | JSON_UNQUOTE\n    | JSON_DEPTH\n    | JSON_LENGTH\n    | JSON_TYPE\n    | JSON_VALID\n    | JSON_TABLE\n    | JSON_SCHEMA_VALID\n    | JSON_SCHEMA_VALIDATION_REPORT\n    | JSON_PRETTY\n    | JSON_STORAGE_FREE\n    | JSON_STORAGE_SIZE\n    | JSON_ARRAYAGG\n    | JSON_OBJECTAGG\n    | STATEMENT\n    ;\n"
  },
  {
    "path": "superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/AbstractSqlParser.kt",
    "content": "package io.github.melin.superior.parser.mysql\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(MySqlParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: MySqlParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(MySqlParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/MySqlAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.mysql\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.AlterActionType.*\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.*\nimport io.github.melin.superior.common.relational.alter.*\nimport io.github.melin.superior.common.relational.common.ShowStatement\nimport io.github.melin.superior.common.relational.common.UseDatabase\nimport io.github.melin.superior.common.relational.create.*\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.drop.DropDatabase\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport io.github.melin.superior.common.relational.table.ColumnRel\nimport io.github.melin.superior.common.relational.table.TruncateTable\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParser\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParser.AlterByAddIndexContext\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParser.AlterByAddPrimaryKeyContext\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParser.AlterByDropPrimaryKeyContext\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParser.AlterByTruncatePartitionContext\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParser.PartitionFunctionHashContext\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParser.PartitionFunctionKeyContext\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParser.PartitionFunctionListContext\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParser.PartitionFunctionRangeContext\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParserBaseVisitor\nimport org.antlr.v4.runtime.tree.TerminalNodeImpl\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/2/8. */\nclass MySqlAntlr4Visitor(val splitSql: Boolean = false) : MySqlParserBaseVisitor<Statement>() {\n\n    private var currentOptType: StatementType = StatementType.UNKOWN\n    private var limit: Int? = null\n    private var offset: Int? = null\n    private val primaryKeys = ArrayList<String>()\n\n    private var inputTables: ArrayList<TableId> = arrayListOf()\n    private var inCte = false\n\n    private var cteTempTables: ArrayList<TableId> = arrayListOf()\n\n    // 多语句解析结果\n    private var statements: ArrayList<Statement> = arrayListOf()\n    // 存储过程和函数中包含的子语句\n    private var childStatements: ArrayList<Statement> = arrayListOf()\n    private val sqls: ArrayList<String> = arrayListOf()\n\n    fun getSqlStatements(): List<Statement> {\n        return statements\n    }\n\n    fun getSplitSqls(): List<String> {\n        return sqls\n    }\n\n    override fun visitSqlStatements(ctx: MySqlParser.SqlStatementsContext): Statement? {\n        ctx.sqlStatement().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else {\n                        var statement = this.visitSqlStatement(it)\n                        if (statement == null) {\n                            statement = DefaultStatement(StatementType.UNKOWN)\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n\n                clean()\n            }\n        }\n        return null\n    }\n\n    override fun visitSqlStatement(ctx: MySqlParser.SqlStatementContext): Statement? {\n        val statement = super.visitSqlStatement(ctx)\n\n        if (\n            statement != null &&\n                statement.statementType != StatementType.CREATE_FUNCTION &&\n                statement.statementType != StatementType.CREATE_PROCEDURE\n        ) {\n            childStatements.add(statement)\n        }\n\n        return statement\n    }\n\n    override fun visitDeclareCursor(ctx: MySqlParser.DeclareCursorContext): Statement? {\n        val statement = super.visitDeclareCursor(ctx)\n        if (\n            statement != null &&\n                statement.statementType != StatementType.CREATE_FUNCTION &&\n                statement.statementType != StatementType.CREATE_PROCEDURE\n        ) {\n            childStatements.add(statement)\n        }\n        return statement\n    }\n\n    private fun clean() {\n        currentOptType = StatementType.UNKOWN\n\n        limit = null\n        offset = null\n        inputTables = arrayListOf()\n        inCte = false\n        cteTempTables = arrayListOf()\n    }\n\n    // -----------------------------------database-------------------------------------------------\n\n    override fun visitCreateDatabase(ctx: MySqlParser.CreateDatabaseContext): Statement {\n        val databaseName = CommonUtils.cleanQuote(ctx.uid().text)\n        return CreateDatabase(databaseName)\n    }\n\n    override fun visitDropDatabase(ctx: MySqlParser.DropDatabaseContext): Statement {\n        val databaseName = CommonUtils.cleanQuote(ctx.uid().text)\n        return DropDatabase(databaseName)\n    }\n\n    // -----------------------------------table-------------------------------------------------\n\n    override fun visitColumnCreateTable(ctx: MySqlParser.ColumnCreateTableContext): Statement {\n        val tableId = parseFullId(ctx.tableName().fullId())\n        var comment: String? = null\n        ctx.tableOption().forEach {\n            when (it) {\n                is MySqlParser.TableOptionCommentContext -> {\n                    comment = CommonUtils.cleanQuote(it.STRING_LITERAL().text)\n                }\n            }\n        }\n        val columnRels = ArrayList<ColumnRel>()\n\n        ctx.createDefinitions().children.forEach { column ->\n            if (column is MySqlParser.ColumnDeclarationContext) {\n                val name = CommonUtils.cleanQuote(column.fullColumnName().text)\n\n                var dataType = column.columnDefinition().dataType().getChild(0).text.lowercase()\n                val count = column.columnDefinition().dataType().childCount\n                if (count > 1) {\n                    val item = column.columnDefinition().dataType().getChild(1)\n                    if (\n                        item is MySqlParser.LengthOneDimensionContext ||\n                            item is MySqlParser.LengthTwoDimensionContext ||\n                            item is MySqlParser.LengthTwoOptionalDimensionContext\n                    ) {\n                        dataType = dataType + item.text\n                    }\n                }\n\n                var colComment: String? = null\n                column.columnDefinition().columnConstraint().forEach {\n                    if (it is MySqlParser.CommentColumnConstraintContext) {\n                        colComment = CommonUtils.cleanQuote(it.STRING_LITERAL().text)\n                    }\n                }\n                columnRels.add(ColumnRel(name, dataType, colComment))\n            }\n        }\n\n        super.visitColumnCreateTable(ctx)\n\n        val ifNotExists: Boolean = if (ctx.ifNotExists() != null) true else false\n        columnRels.forEach { columnRel: ColumnRel ->\n            if (primaryKeys.contains(columnRel.columnName)) {\n                columnRel.primaryKey = true\n            }\n        }\n        val createTable =\n            CreateTable(tableId, TableType.MYSQL, comment, null, null, columnRels, null, null, ifNotExists)\n\n        if (ctx.partitionDefinitions() != null) {\n            val def = ctx.partitionDefinitions().partitionFunctionDefinition()\n            if (def is PartitionFunctionHashContext) {\n                createTable.partitionType = PartitionType.HASH\n            } else if (def is PartitionFunctionKeyContext) {\n                createTable.partitionType = PartitionType.KEY\n            } else if (def is PartitionFunctionRangeContext) {\n                createTable.partitionType = PartitionType.RANGE\n            } else if (def is PartitionFunctionListContext) {\n                createTable.partitionType = PartitionType.LIST\n            }\n        }\n\n        return createTable\n    }\n\n    override fun visitQueryCreateTable(ctx: MySqlParser.QueryCreateTableContext): Statement {\n        currentOptType = StatementType.CREATE_TABLE_AS_SELECT\n        val tableId = parseFullId(ctx.tableName().fullId())\n        var comment: String? = null\n        ctx.tableOption().forEach {\n            when (it) {\n                is MySqlParser.TableOptionCommentContext -> {\n                    comment = CommonUtils.cleanQuote(it.STRING_LITERAL().text)\n                }\n            }\n        }\n\n        val ifNotExists: Boolean = if (ctx.ifNotExists() != null) true else false\n        val queryStmt = this.visitSelectStatement(ctx.selectStatement()) as QueryStmt\n        val createTable = CreateTableAsSelect(tableId, queryStmt, comment, null, null, null, null, null, ifNotExists)\n        return createTable\n    }\n\n    override fun visitCopyCreateTable(ctx: MySqlParser.CopyCreateTableContext): Statement? {\n        currentOptType = StatementType.CREATE_TABLE_AS_LIKE\n        val tableId = parseFullId(ctx.tableName().get(0).fullId())\n        var likeTableId = parseFullId(ctx.tableName().get(1).fullId())\n        var createTableLike = CreateTableLike(likeTableId, tableId, false, false, false);\n        return createTableLike;\n    }\n\n\n    override fun visitPrimaryKeyTableConstraint(ctx: MySqlParser.PrimaryKeyTableConstraintContext): Statement? {\n        val count = ctx.indexColumnNames().childCount\n\n        for (i in 1..(count - 2)) {\n            var column = ctx.indexColumnNames().getChild(i).text\n            column = CommonUtils.cleanQuote(column)\n            primaryKeys.add(column)\n        }\n\n        return null\n    }\n\n    override fun visitDropTable(ctx: MySqlParser.DropTableContext): Statement {\n        if (ctx.tables().tableName().size > 1) {\n            throw SQLParserException(\"不支持drop多个表\")\n        }\n        val tableId = parseFullId(ctx.tables().tableName(0).fullId())\n\n        val dropTable = DropTable(tableId)\n        dropTable.ifExists = if (ctx.ifExists() != null) true else false\n        return dropTable\n    }\n\n    override fun visitTruncateTable(ctx: MySqlParser.TruncateTableContext): Statement {\n        val tableId = parseFullId(ctx.tableName().fullId())\n        return TruncateTable(tableId)\n    }\n\n    override fun visitRenameTable(ctx: MySqlParser.RenameTableContext): Statement {\n        val tableId = parseFullId(ctx.renameTableClause().get(0).tableName(0).fullId())\n        val newTableId = parseFullId(ctx.renameTableClause().get(0).tableName(1).fullId())\n\n        val action = RenameAction(newTableId)\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitUseStatement(ctx: MySqlParser.UseStatementContext): Statement {\n        val databaseName = ctx.uid().text\n        return UseDatabase(databaseName)\n    }\n\n    // -----------------------------------Alter-----------------------------------------------\n\n    override fun visitAlterTable(ctx: MySqlParser.AlterTableContext): Statement? {\n        val tableId = parseFullId(ctx.tableName().fullId())\n        val alterTable = AlterTable(tableId)\n        ctx.alterSpecification().forEach { statement ->\n            if (statement is MySqlParser.AlterByChangeColumnContext) {\n                val columnName = CommonUtils.cleanQuote(statement.oldColumn.text)\n                val newColumnName = CommonUtils.cleanQuote(statement.newColumn.text)\n                val dataType = source(statement.columnDefinition().dataType())\n                var comment: String? = null\n                var nullable: Boolean = true\n                var defaultExpr: String? = null\n\n                statement.columnDefinition().children.forEach {\n                    if (it is MySqlParser.CommentColumnConstraintContext) {\n                        comment = CommonUtils.cleanQuote(it.STRING_LITERAL().text)\n                    } else if (it is MySqlParser.NullColumnConstraintContext) {\n                        nullable = it.nullNotnull().NOT() == null\n                    } else if (it is MySqlParser.DefaultColumnConstraintContext) {\n                        defaultExpr = source(it.defaultValue())\n                    }\n                }\n\n                val action = AlterColumnAction(ALTER_COLUMN, columnName, dataType, comment)\n                action.newColumName = newColumnName\n                action.nullable = nullable\n                action.defaultExpression = defaultExpr\n                alterTable.addAction(action)\n            } else if (statement is MySqlParser.AlterByAddColumnContext) {\n                val columnName = CommonUtils.cleanQuote(statement.uid().get(0).text)\n                val dataType = statement.columnDefinition().dataType().text\n                var comment: String? = null\n                var nullable: Boolean = true\n                var defaultExpr: String? = null\n                statement.columnDefinition().children.forEach {\n                    if (it is MySqlParser.CommentColumnConstraintContext) {\n                        comment = CommonUtils.cleanQuote(it.STRING_LITERAL().text)\n                    } else if (it is MySqlParser.NullColumnConstraintContext) {\n                        nullable = it.nullNotnull().NOT() == null\n                    } else if (it is MySqlParser.DefaultColumnConstraintContext) {\n                        defaultExpr = source(it.defaultValue())\n                    }\n                }\n\n                val action = AlterColumnAction(ADD_COLUMN, columnName, dataType, comment)\n                action.nullable = nullable\n                action.defaultExpression = defaultExpr\n                alterTable.addAction(action)\n            } else if (statement is MySqlParser.AlterByDropColumnContext) {\n                val columnName = CommonUtils.cleanQuote(statement.uid().text)\n                val action = DropColumnAction(columnName)\n                return AlterTable(tableId, action)\n            } else if (statement is MySqlParser.AlterByModifyColumnContext) {\n                val columnName = CommonUtils.cleanQuote(statement.uid().get(0).text)\n                val dataType = statement.columnDefinition().dataType().text\n\n                val action = AlterColumnAction(ALTER_COLUMN, columnName, dataType)\n                alterTable.addAction(action)\n            } else if (statement is AlterByAddIndexContext) {\n                val createIndex = CreateIndex(statement.uid().text)\n                alterTable.addAction(createIndex)\n            } else if (statement is MySqlParser.AlterByDropIndexContext) {\n                val dropIndex = DropIndex(statement.uid().text)\n                alterTable.addAction(dropIndex)\n            } else if (statement is AlterByAddPrimaryKeyContext) {\n                val action = AlterTableAction(ADD_PRIMARY_KEY)\n                alterTable.addAction(action)\n            } else if (statement is AlterByDropPrimaryKeyContext) {\n                val action = AlterTableAction(DROP_PRIMARY_KEY)\n                alterTable.addAction(action)\n            } else if (statement is MySqlParser.AlterByAddUniqueKeyContext) {\n                val action = AlterTableAction(ADD_UNIQUE_KEY)\n                alterTable.addAction(action)\n            } else if (statement is MySqlParser.AlterPartitionContext) {\n                val alterPartition = statement.alterPartitionSpecification()\n                if (alterPartition is AlterByTruncatePartitionContext) {\n                    val action = AlterTableAction(TRUNCATE_PARTITION)\n                    alterTable.addAction(action)\n                } else if (alterPartition is MySqlParser.AlterByDropPartitionContext) {\n                    val action = AlterTableAction(DROP_PARTITION)\n                    alterTable.addAction(action)\n                } else if (alterPartition is MySqlParser.AlterByAddPartitionContext) {\n                    val action = AlterTableAction(ADD_PARTITION)\n                    alterTable.addAction(action)\n                }\n            }\n        }\n\n        if (alterTable.actions.size > 0) {\n            return alterTable\n        } else {\n            return super.visitAlterTable(ctx)\n        }\n    }\n\n    override fun visitAnalyzeTable(ctx: MySqlParser.AnalyzeTableContext): Statement {\n        val tables = ArrayList<TableId>()\n        ctx.tables().tableName().forEach { context ->\n            val tableId = parseFullId(context.fullId())\n            tables.add(tableId)\n        }\n\n        return AnalyzeTable(tables)\n    }\n\n    // -----------------------------------DML-------------------------------------------------\n\n    override fun visitSelectStatement(ctx: MySqlParser.SelectStatementContext): Statement {\n        if (currentOptType == StatementType.UNKOWN) {\n            currentOptType = StatementType.SELECT\n        }\n        super.visitSelectStatement(ctx)\n        return QueryStmt(inputTables, limit, offset)\n    }\n\n    override fun visitInsertStatement(ctx: MySqlParser.InsertStatementContext): Statement {\n        val tableId = parseFullId(ctx.tableName().fullId())\n\n        currentOptType = StatementType.INSERT\n        if (ctx.insertStatementValue().selectStatement() != null) {\n            val queryStmt = this.visitSelectStatement(ctx.insertStatementValue().selectStatement()) as QueryStmt\n            val insertTable = InsertTable(InsertMode.INTO, queryStmt, tableId)\n            insertTable?.setSql(source(ctx))\n            return insertTable\n        } else {\n            val insertTable = InsertTable(InsertMode.INTO, QueryStmt(), tableId)\n            insertTable?.setSql(source(ctx))\n            return insertTable\n        }\n    }\n\n    override fun visitReplaceStatement(ctx: MySqlParser.ReplaceStatementContext): Statement {\n        val tableId = parseFullId(ctx.tableName().fullId())\n\n        currentOptType = StatementType.INSERT\n        if (ctx.insertStatementValue().selectStatement() != null) {\n            val queryStmt = this.visitSelectStatement(ctx.insertStatementValue().selectStatement()) as QueryStmt\n            val insertTable = InsertTable(InsertMode.INTO, queryStmt, tableId)\n            insertTable.mysqlReplace = true\n            return insertTable\n        } else {\n            return InsertTable(InsertMode.INTO, QueryStmt(), tableId)\n        }\n    }\n\n    override fun visitDeleteStatement(ctx: MySqlParser.DeleteStatementContext): Statement {\n        currentOptType = StatementType.DELETE\n\n        val deleteTable =\n            if (ctx.multipleDeleteStatement() != null) {\n                this.visit(ctx.multipleDeleteStatement().expression())\n\n                val outputTables = ctx.multipleDeleteStatement().tableName().map { parseFullId(it.fullId()) }\n                val deleteTable = DeleteTable(outputTables.first(), inputTables)\n                super.visitTableSources(ctx.multipleDeleteStatement().tableSources())\n                deleteTable.outputTables.addAll(outputTables.subList(1, outputTables.size))\n                deleteTable\n            } else {\n                if (ctx.singleDeleteStatement().expression() != null) {\n                    this.visit(ctx.singleDeleteStatement().expression())\n                }\n\n                val tableId = parseFullId(ctx.singleDeleteStatement().tableName().fullId())\n                DeleteTable(tableId, inputTables)\n            }\n\n        return deleteTable\n    }\n\n    override fun visitUpdateStatement(ctx: MySqlParser.UpdateStatementContext): Statement {\n        currentOptType = StatementType.UPDATE\n        val updateTable =\n            if (ctx.multipleUpdateStatement() != null) {\n                super.visitTableSources(ctx.multipleUpdateStatement().tableSources())\n\n                val expression = ctx.singleUpdateStatement().expression()\n                if (expression != null) {\n                    this.visit(expression)\n                }\n                val updateTable = UpdateTable(inputTables.first(), inputTables.toMutableList())\n                updateTable\n            } else {\n                super.visitTableSources(ctx.singleUpdateStatement().tableSources())\n                val expression = ctx.singleUpdateStatement().expression()\n                if (expression != null) {\n                    this.visit(expression)\n                }\n\n                val updateTable = UpdateTable(inputTables.first(), inputTables.toMutableList())\n                updateTable\n            }\n\n        return updateTable\n    }\n\n    override fun visitCreateIndex(ctx: MySqlParser.CreateIndexContext): Statement {\n        val tableId = parseFullId(ctx.tableName().fullId())\n        val createIndex = CreateIndex(ctx.uid().text)\n        return AlterTable(tableId, createIndex)\n    }\n\n    override fun visitDropIndex(ctx: MySqlParser.DropIndexContext): Statement {\n        val tableId = parseFullId(ctx.tableName().fullId())\n        val dropIndex = DropIndex(ctx.uid().text)\n        return AlterTable(tableId, dropIndex)\n    }\n\n    override fun visitCreateProcedure(ctx: MySqlParser.CreateProcedureContext): Statement {\n        super.visitCreateProcedure(ctx)\n        val tableId = parseFullId(ctx.fullId())\n        val procedureId = ProcedureId(tableId.schemaName, tableId.tableName)\n        return CreateProcedure(procedureId, childStatements, false)\n    }\n\n    override fun visitCreateFunction(ctx: MySqlParser.CreateFunctionContext): Statement {\n        super.visitCreateFunction(ctx)\n        val tableId = parseFullId(ctx.fullId())\n        val functionId = FunctionId(tableId.schemaName, tableId.tableName)\n        return CreateFunction(functionId, childStatements, false)\n    }\n\n    // -----------------------------------private\n    // method-------------------------------------------------\n\n    override fun visitWithStatement(ctx: MySqlParser.WithStatementContext): Statement? {\n        inCte = true\n        ctx.commonTableExpressions().forEach {\n            val tableId = TableId(it.cteName().text)\n            cteTempTables.add(tableId)\n            super.visitDmlStatement(it.dmlStatement())\n        }\n        inCte = false\n        return null\n    }\n\n    override fun visitTableName(ctx: MySqlParser.TableNameContext): Statement? {\n        if (\n            StatementType.SELECT == currentOptType ||\n                StatementType.INSERT == currentOptType ||\n                StatementType.UPDATE == currentOptType ||\n                StatementType.DELETE == currentOptType ||\n                StatementType.CREATE_TABLE_AS_SELECT == currentOptType\n        ) {\n\n            val tableId = parseFullId(ctx.fullId())\n\n            // 别名和表名一样的场景\n            if (inCte && cteTempTables.last() == tableId) {\n                cteTempTables.remove(tableId)\n            }\n\n            if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {\n                inputTables.add(tableId)\n            }\n        }\n        return null\n    }\n\n    override fun visitLimitClause(ctx: MySqlParser.LimitClauseContext): Statement? {\n        if (ctx.limit != null && ctx.limit.decimalLiteral() != null) {\n            limit = ctx.limit.text.toInt()\n        }\n        if (ctx.offset != null && ctx.offset.decimalLiteral() != null) {\n            offset = ctx.offset.text.toInt()\n        }\n        return super.visitLimitClause(ctx)\n    }\n\n    private fun parseFullId(fullId: MySqlParser.FullIdContext): TableId {\n        var databaseName: String? = null\n        var tableName: String = \"\"\n\n        if (fullId.childCount == 2) {\n            databaseName = fullId.uid().get(0).text\n            tableName = (fullId.getChild(1) as TerminalNodeImpl).text.substring(1)\n        } else if (fullId.childCount == 3) {\n            databaseName = CommonUtils.cleanQuote(fullId.uid().get(0).text)\n            tableName = CommonUtils.cleanQuote((fullId.getChild(2) as MySqlParser.UidContext).text)\n        } else {\n            tableName = fullId.uid().get(0).text\n        }\n\n        if (databaseName != null) {\n            databaseName = CommonUtils.cleanQuote(databaseName)\n        }\n        tableName = CommonUtils.cleanQuote(tableName)\n\n        return TableId(databaseName, tableName)\n    }\n}\n"
  },
  {
    "path": "superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/MySqlHelper.kt",
    "content": "package com.github.melin.superior.sql.parser.mysql\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.mysql.AbstractSqlParser\nimport io.github.melin.superior.parser.mysql.MySqlAntlr4Visitor\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlLexer\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParser\nimport io.github.melin.superior.parser.mysql.antlr4.MySqlParserBaseVisitor\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/1/10. */\nobject MySqlHelper {\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until MySqlLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = MySqlLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement {\n        val statements = this.parseMultiStatement(command)\n        if (statements.size != 1) {\n            throw IllegalStateException(\"only parser one sql, sql count: \" + statements.size)\n        } else {\n            return statements.get(0)\n        }\n    }\n\n    @JvmStatic\n    fun parseMultiStatement(command: String): List<Statement> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = MySqlAntlr4Visitor(false)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSqlStatements()\n    }\n\n    @JvmStatic\n    fun splitSql(command: String): List<String> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = MySqlAntlr4Visitor(true)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSplitSqls()\n    }\n\n    @JvmStatic\n    fun checkSqlSyntax(command: String) {\n        val sqlVisitor = MySqlParserBaseVisitor<Statement>()\n        innerParseStatement(command, sqlVisitor)\n    }\n\n    private fun innerParseStatement(command: String, sqlVisitor: MySqlParserBaseVisitor<Statement>) {\n        val charStream = UpperCaseCharStream(CharStreams.fromString(command))\n        val lexer = MySqlLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = MySqlParser(tokenStream)\n        AbstractSqlParser.installCaches(parser)\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visitSqlStatements(parser.sqlStatements())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                sqlVisitor.visitSqlStatements(parser.sqlStatements())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(command)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/type/JsonType.kt",
    "content": "package io.github.melin.superior.parser.mysql.type\n\nimport io.github.melin.superior.common.type.AbsType\n\nclass JsonType : AbsType() {\n    override val name: String = \"json\"\n}\n"
  },
  {
    "path": "superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/type/datetime.kt",
    "content": "package io.github.melin.superior.parser.mysql.type\n\nimport io.github.melin.superior.common.type.AbsDataTimeType\n\nclass DateType : AbsDataTimeType() {\n    override val name: String = \"date\"\n}\n\ndata class TimeType(val precision: Int = 0) : AbsDataTimeType() {\n    override val name: String = \"time\"\n}\n\ndata class TimeStampType(val precision: Int = 0) : AbsDataTimeType() {\n    override val name: String = \"timestamp\"\n}\n\ndata class DateTimeType(val precision: Int = 0) : AbsDataTimeType() {\n    override val name: String = \"datetime\"\n}\n\nclass YearType : AbsDataTimeType() {\n    override val name: String = \"year\"\n}\n"
  },
  {
    "path": "superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/type/numeric.kt",
    "content": "package io.github.melin.superior.parser.mysql.type\n\nimport io.github.melin.superior.common.type.AbsNumericType\n\ndata class TinyintType(val length: Int, val unsigned: Boolean = false, val zerofill: Boolean = false) :\n    AbsNumericType() {\n    override val name: String = \"tinyint\"\n    override val alias: String = \"int1\"\n\n    companion object {\n        const val MIN_VALUE: Short = -128\n        const val MAX_VALUE: Short = 127\n    }\n}\n\ndata class SmallIntType(val length: Int, val unsigned: Boolean = false, val zerofill: Boolean = false) :\n    AbsNumericType() {\n    override val name: String = \"smallint\"\n    override val alias: String = \"int2\"\n\n    companion object {\n        const val MIN_VALUE: Int = -32768\n        const val MAX_VALUE: Int = 32767\n    }\n}\n\ndata class MediumIntType(val length: Int, val unsigned: Boolean = false, val zerofill: Boolean = false) :\n    AbsNumericType() {\n    override val name: String = \"mediumint\"\n    override val alias: String = \"int3\"\n\n    companion object {\n        const val MIN_VALUE: Int = -8388608\n        const val MAX_VALUE: Int = 8388607\n    }\n}\n\ndata class IntegerType(val length: Int) : AbsNumericType() {\n    override val name: String = \"integer\"\n    override val alias: String = \"int\"\n    override val alias2: String = \"int4\"\n\n    companion object {\n        const val MIN_VALUE: Long = -2147483648L\n        const val MAX_VALUE: Long = 2147483647L\n    }\n}\n\ndata class BigIntType(val length: Int, val unsigned: Boolean = false, val zerofill: Boolean = false) :\n    AbsNumericType() {\n    override val name: String = \"bigint\"\n    override val alias: String = \"int8\"\n}\n\ndata class DecimalType(val precision: Int = 10, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"decimal\"\n}\n\ndata class FloatType(val precision: Int, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"float\"\n}\n\ndata class DoubleType(val precision: Int, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"double\"\n    override val alias: String = \"float8\"\n}\n\ndata class RealType(val precision: Int, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"real\"\n    override val alias: String = \"float4\"\n}\n\ndata class BitType(val length: Int) : AbsNumericType() {\n    override val name: String = \"bit\"\n}\n"
  },
  {
    "path": "superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/type/string.kt",
    "content": "package io.github.melin.superior.parser.mysql.type\n\nimport io.github.melin.superior.common.type.AbsStringType\n\ndata class CharType(val length: Int) : AbsStringType() {\n    override val name: String = \"char\"\n\n    companion object {\n        const val MAX_LENGTH: Int = 255\n    }\n}\n\ndata class VarcharType(val length: Int) : AbsStringType() {\n    override val name: String = \"varchar\"\n\n    companion object {\n        const val MAX_LENGTH: Int = 65535\n    }\n}\n\ndata class BinaryType(val length: Int) : AbsStringType() {\n    override val name: String = \"binary\"\n\n    companion object {\n        const val MAX_LENGTH: Int = 255\n    }\n}\n\ndata class VarbinaryType(val length: Int) : AbsStringType() {\n    override val name: String = \"varbinary\"\n\n    companion object {\n        const val MAX_LENGTH: Int = 65535\n    }\n}\n\nclass TinyblobType : AbsStringType() {\n    override val name: String = \"tinyblob\"\n}\n\nclass BlobType : AbsStringType() {\n    override val name: String = \"blob\"\n}\n\nclass MediumblobType : AbsStringType() {\n    override val name: String = \"mediumblob\"\n}\n\nclass LongblobType : AbsStringType() {\n    override val name: String = \"longblob\"\n}\n\nclass TinytextType : AbsStringType() {\n    override val name: String = \"tinytext\"\n}\n\nclass TextType : AbsStringType() {\n    override val name: String = \"text\"\n}\n\nclass MediumtextType : AbsStringType() {\n    override val name: String = \"mediumtext\"\n}\n\nclass LongtextType : AbsStringType() {\n    override val name: String = \"longtext\"\n}\n\ndata class EnumType(val values: List<String>) : AbsStringType() {\n    override val name: String = \"enum\"\n}\n\ndata class SetType(val values: List<String>) : AbsStringType() {\n    override val name: String = \"set\"\n}\n"
  },
  {
    "path": "superior-mysql-parser/src/test/kotlin/io/github/melin/superior/parser/mysql/MySqlParserDdlTest.kt",
    "content": "package io.github.melin.superior.parser.mysql\n\nimport com.github.melin.superior.sql.parser.mysql.MySqlHelper\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.*\nimport io.github.melin.superior.common.relational.alter.*\nimport io.github.melin.superior.common.relational.common.UseDatabase\nimport io.github.melin.superior.common.relational.create.CreateDatabase\nimport io.github.melin.superior.common.relational.create.CreateTable\nimport io.github.melin.superior.common.relational.drop.DropDatabase\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport io.github.melin.superior.common.relational.table.TruncateTable\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2018/1/10. */\nclass MySqlParserDdlTest {\n\n    @Test\n    fun splitSqlTest() {\n        val sql =\n            \"\"\"\n            CREATE DATABASE IF NOT EXISTS bigdata1;    \n            drop DATABASE IF EXISTS bigdata2\n        \"\"\"\n                .trimIndent()\n\n        val statements = MySqlHelper.splitSql(sql)\n\n        Assert.assertEquals(2, statements.size)\n        Assert.assertEquals(\"CREATE DATABASE IF NOT EXISTS bigdata1\", statements.get(0))\n    }\n\n    @Test\n    fun createDatabaseTest() {\n        val sql =\n            \"\"\"\n            CREATE DATABASE IF NOT EXISTS \"bigdata1\";\n            drop DATABASE IF EXISTS bigdata2\n        \"\"\"\n                .trimIndent()\n\n        val statements = MySqlHelper.parseMultiStatement(sql)\n\n        val createDatabse = statements.get(0)\n        val dropDatabase = statements.get(1)\n        if (createDatabse is CreateDatabase) {\n            Assert.assertEquals(\"bigdata1\", createDatabse.databaseName)\n        }\n        if (dropDatabase is CreateDatabase) {\n            Assert.assertEquals(\"bigdata2\", dropDatabase.databaseName)\n        }\n    }\n\n    @Test\n    fun dropDatabaseTest() {\n        val sql = \"DROP DATABASE IF EXISTS bigdata\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n        if (statement is DropDatabase) {\n            val name = statement.databaseName\n            Assert.assertEquals(StatementType.DROP_DATABASE, statement.statementType)\n            Assert.assertEquals(\"bigdata\", name)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest() {\n        val sql =\n            \"CREATE TABLE bigdata.dc_config (\\n\" +\n                \"  `id` int(11) NOT NULL AUTO_INCREMENT comment 'id',\\n\" +\n                \"  `appname` varchar(64) NOT NULL,\\n\" +\n                \"  `profile` varchar(64) NOT NULL,\\n\" +\n                \"  `width` DECIMAL(5, 2) NOT NULL,\\n\" +\n                \"  `config_text` longtext,\\n\" +\n                \"  `content` json,\\n\" +\n                \"  `content1` text COLLATE utf8mb4_unicode_ci comment 'test',\\n\" +\n                \"  `creater` varchar(45) NOT NULL,\\n\" +\n                \"  `modifier` varchar(45) DEFAULT NULL,\\n\" +\n                \"  `gmt_created` datetime NOT NULL,\\n\" +\n                \"  `gmt_modified` datetime DEFAULT NULL,\\n\" +\n                \"  PRIMARY KEY (`id`),\\n\" +\n                \"  UNIQUE KEY `appname_UNIQUE` (`appname`,`profile`)\\n\" +\n                \") ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='系统参数配置';\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"bigdata\", statement.tableId.schemaName)\n            Assert.assertEquals(\"dc_config\", statement.tableId.tableName)\n            Assert.assertEquals(\"系统参数配置\", statement.comment)\n\n            statement.columnRels?.get(0)?.let { Assert.assertTrue(it.primaryKey) }\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest1() {\n        val sql =\n            \"CREATE TABLE `box_partner` (\\n\" +\n                \"    `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',\\n\" +\n                \"    `code` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户编码',\\n\" +\n                \"    `name` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '客户名称',\\n\" +\n                \"    `role` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户角色',\\n\" +\n                \"    `key` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户key',\\n\" +\n                \"    `logo` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户logo',\\n\" +\n                \"    `info` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户简介',\\n\" +\n                \"    `contacts` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '联系方式',\\n\" +\n                \"    `token` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户唯一标识',\\n\" +\n                \"    `callback_url` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户提供的回调地址',\\n\" +\n                \"    `attachment` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '扩展字段',\\n\" +\n                \"    `create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\\n\" +\n                \"    `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',\\n\" +\n                \"    `callback_url_status` int(11) DEFAULT NULL COMMENT '回调地址状态:成功0,失败1,通讯中断2',\\n\" +\n                \"    `callback_url_detail` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '回调事件',\\n\" +\n                \"    PRIMARY KEY (`id`),\\n\" +\n                \"    UNIQUE KEY `token` (`token`)\\n\" +\n                \"    ) ENGINE=InnoDB AUTO_INCREMENT=7564 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"box_partner\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest2() {\n        val sql =\n            \" CREATE TABLE `decision_flow_model` (\\n\" +\n                \"  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',\\n\" +\n                \"  `model_uuid` char(32) NOT NULL COMMENT '关联holmes_model表的uuid',\\n\" +\n                \"  `partner_code` varchar(128) NOT NULL COMMENT '合作方',\\n\" +\n                \"  `decision_flow_uuid` char(32) NOT NULL COMMENT '关联decision_flow表的uuid',\\n\" +\n                \"  `gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\\n\" +\n                \"  `gmt_modify` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',\\n\" +\n                \"  PRIMARY KEY (`id`)\\n\" +\n                \") ENGINE=InnoDB AUTO_INCREMENT=4475 DEFAULT CHARSET=utf8 COMMENT='决策流与模型关系表'\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"decision_flow_model\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest3() {\n        val sql =\n            \"CREATE TABLE `app_channel_daily_report` (\\n\" +\n                \"  `id` bigint(20) NOT NULL AUTO_INCREMENT,\\n\" +\n                \"  `normal_counting` bigint(20) NOT NULL DEFAULT '0' COMMENT '正常用户',\\n\" +\n                \"  `abnormal_counting` bigint(20) NOT NULL DEFAULT '0' COMMENT '异常用户',\\n\" +\n                \"  `emulator_counting` bigint(20) NOT NULL DEFAULT '0' COMMENT '模拟器用户',\\n\" +\n                \"  `gmt_create` datetime NOT NULL COMMENT '创建时间',\\n\" +\n                \"  `gmt_modified` datetime DEFAULT NULL COMMENT '更新时间',\\n\" +\n                \"  `create_by` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '创建者',\\n\" +\n                \"  `update_by` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '更新者',\\n\" +\n                \"  `event_type` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '事件类型',\\n\" +\n                \"  `partner_code` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '合作方编码',\\n\" +\n                \"  `app_channel` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '渠道',\\n\" +\n                \"  `app_name` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'app名称',\\n\" +\n                \"  `app_version` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'default',\\n\" +\n                \"  PRIMARY KEY (`id`,`gmt_create`),\\n\" +\n                \"  KEY `channel_report_index` (`gmt_create`,`partner_code`,`app_channel`,`app_name`,`app_version`,`event_type`)\\n\" +\n                \") ENGINE=InnoDB AUTO_INCREMENT=33703438 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='渠道反作弊日统计表'\\n\" +\n                \" PARTITION BY RANGE (month(gmt_create)-1)\\n\" +\n                \"(PARTITION part0 VALUES LESS THAN (1) COMMENT = '1月份' ENGINE = InnoDB,\\n\" +\n                \" PARTITION part1 VALUES LESS THAN (2) COMMENT = '2月份' ENGINE = InnoDB,\\n\" +\n                \" PARTITION part2 VALUES LESS THAN (3) COMMENT = '3月份' ENGINE = InnoDB,\\n\" +\n                \" PARTITION part3 VALUES LESS THAN (4) COMMENT = '4月份' ENGINE = InnoDB,\\n\" +\n                \" PARTITION part4 VALUES LESS THAN (5) COMMENT = '5月份' ENGINE = InnoDB,\\n\" +\n                \" PARTITION part5 VALUES LESS THAN (6) COMMENT = '6月份' ENGINE = InnoDB,\\n\" +\n                \" PARTITION part6 VALUES LESS THAN (7) COMMENT = '7月份' ENGINE = InnoDB,\\n\" +\n                \" PARTITION part7 VALUES LESS THAN (8) COMMENT = '8月份' ENGINE = InnoDB,\\n\" +\n                \" PARTITION part8 VALUES LESS THAN (9) COMMENT = '9月份' ENGINE = InnoDB,\\n\" +\n                \" PARTITION part9 VALUES LESS THAN (10) COMMENT = '10月份' ENGINE = InnoDB,\\n\" +\n                \" PARTITION part10 VALUES LESS THAN (11) COMMENT = '11月份' ENGINE = InnoDB,\\n\" +\n                \" PARTITION part11 VALUES LESS THAN (12) COMMENT = '12月份' ENGINE = InnoDB)\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"app_channel_daily_report\", statement.tableId.tableName)\n            Assert.assertEquals(PartitionType.RANGE, statement.partitionType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest4() {\n        val sql =\n            \"\"\"\n            CREATE TABLE IF NOT EXISTS `decision_flow_model` (\n    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',\n    `model_uuid` char(32) NOT NULL COMMENT '关联holmes_model表的uuid',\n    `partner_code` varchar(128) NOT NULL COMMENT '合作方',\n    `decision_flow_uuid` char(32) NOT NULL COMMENT '关联decision_flow表的uuid',\n    `gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n    `gmt_modify` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',\n    PRIMARY KEY (`id`)\n    ) ENGINE=InnoDB AUTO_INCREMENT=77 DEFAULT CHARSET=utf8\n            \"\"\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"decision_flow_model\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest5() {\n        val sql =\n            \"\"\"\n            CREATE TABLE `dw_job_analysis_detail` (\n  `id` int(11) NOT NULL AUTO_INCREMENT,\n  `user_id` varchar(255) DEFAULT NULL,\n  `job_id` int(11) DEFAULT NULL,\n  `job_type` varchar(255) DEFAULT NULL,\n  `job_status` int(255) DEFAULT NULL,\n  `create_time` timestamp(6) NULL DEFAULT NULL,\n  `creater` varchar(255) DEFAULT NULL,\n  `modifier` varchar(255) DEFAULT NULL,\n  `gmt_created` timestamp(6) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(6),\n  `gmt_modified` datetime(6) DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(6),\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB AUTO_INCREMENT=75306 DEFAULT CHARSET=utf8\n            \"\"\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"dw_job_analysis_detail\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropTableTest() {\n        val sql = \"DROP table IF EXISTS bigdata.users\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is DropTable) {\n            Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)\n            Assert.assertEquals(\"bigdata\", statement.tableId.schemaName)\n            Assert.assertEquals(\"users\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun renameTableTest() {\n        val sql = \"RENAME TABLE `datacompute`.`users_quan` TO  `datacompute`.`dc_users`\\n\"\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"datacompute\", statement.tableId.schemaName)\n            Assert.assertEquals(\"users_quan\", statement.tableId.tableName)\n            val action = statement.firstAction() as RenameAction\n            Assert.assertEquals(AlterActionType.RENAME, action.alterType)\n            Assert.assertEquals(\"dc_users\", action.newTableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun analyzeTableTest() {\n        val sql = \"analyze table bigdata.users\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is AnalyzeTable) {\n            val table = statement.tableIds.get(0)\n\n            Assert.assertEquals(StatementType.ANALYZE_TABLE, statement.statementType)\n            Assert.assertEquals(\"bigdata\", table.schemaName)\n            Assert.assertEquals(\"users\", table.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun truncateTableTest() {\n        val sql = \"TRUNCATE TABLE test.user\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is TruncateTable) {\n            Assert.assertEquals(StatementType.TRUNCATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"test\", statement.tableId.schemaName)\n            Assert.assertEquals(\"user\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun changeColumnTest() {\n        val sql =\n            \"ALTER TABLE `datacompute`.`log_collect_config` \\n\" +\n                \"CHANGE COLUMN `partition_type` `partition_type1` VARCHAR(45) NULL DEFAULT 'day' COMMENT '分区类型：day, hour, minute' ;\"\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"datacompute\", statement.tableId.schemaName)\n            Assert.assertEquals(\"log_collect_config\", statement.tableId.tableName)\n\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(\"partition_type\", action.columName)\n            Assert.assertEquals(\"partition_type1\", action.newColumName)\n            Assert.assertEquals(\"分区类型：day, hour, minute\", action.comment)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun modifyColumnTest() {\n        val sql = \"ALTER TABLE t1 MODIFY age BIGINT NOT NULL;\"\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"t1\", statement.tableId.tableName)\n\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(AlterActionType.ALTER_COLUMN, action.alterType)\n            Assert.assertEquals(\"age\", action.columName)\n            Assert.assertEquals(\"BIGINT\", action.dataType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun addColumnTest() {\n        val sql =\n            \"ALTER TABLE `datacompute`.`users_quan` ADD COLUMN `age` VARCHAR(45) NOT NULL DEFAULT 18 COMMENT '年龄' AFTER `username`\"\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"datacompute\", statement.tableId.schemaName)\n            Assert.assertEquals(\"users_quan\", statement.tableId.tableName)\n\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(AlterActionType.ADD_COLUMN, action.alterType)\n            Assert.assertEquals(\"age\", action.columName)\n            Assert.assertFalse(action.nullable)\n            Assert.assertEquals(\"18\", action.defaultExpression)\n            Assert.assertEquals(\"年龄\", action.comment)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun addColumnTest1() {\n        val sql =\n            \"\"\"\n            ALTER TABLE `mxy`.`cyj`\n            ADD COLUMN new_column1 VARCHAR(255) default null,\n            ADD COLUMN new_column2 INT not null default 0,\n            ADD COLUMN new_column3 TIMESTAMP DEFAULT CURRENT_TIMESTAMP;\n        \"\"\"\n                .trimIndent()\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"mxy\", statement.tableId.schemaName)\n            Assert.assertEquals(\"cyj\", statement.tableId.tableName)\n\n            Assert.assertEquals(3, statement.actions.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropColumnTest() {\n        val sql = \"ALTER TABLE `datacompute`.`users_quan` DROP COLUMN `age`;\"\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"datacompute\", statement.tableId.schemaName)\n            Assert.assertEquals(\"users_quan\", statement.tableId.tableName)\n\n            val action = statement.firstAction() as DropColumnAction\n            Assert.assertEquals(AlterActionType.DROP_COLUMN, action.alterType)\n            Assert.assertEquals(\"age\", action.columNames.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun addUNIQUETest() {\n        val sql =\n            \"ALTER TABLE `datacompute`.`dc_project_member`\\n\" +\n                \"    ADD UNIQUE INDEX `uk_prj_user` (`project_code` ASC, `user_id` ASC);\"\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n    }\n\n    @Test\n    fun addUNIQUETest1() {\n        val sql = \"ALTER TABLE amount_all ADD UNIQUE uk_type_time(etype, time)\"\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n    }\n\n    @Test\n    fun addIndexTest() {\n        val sql = \"ALTER TABLE sj_resource_charges add index index_test (name);\"\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        if (statement is AlterTable) {\n            val createIndex = statement.firstAction() as CreateIndex\n            Assert.assertEquals(\"index_test\", createIndex.indexName)\n        }\n    }\n\n    @Test\n    fun addIndexTest1() {\n        val sql = \"ALTER TABLE tablename ADD INDEX INDEX_NAME  (school_id, settlement_time)\"\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n    }\n\n    @Test\n    fun dropIndexTest1() {\n        val sql = \"ALTER TABLE table_name DROP INDEX index_name\"\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(\"ALTER TABLE table_name DROP INDEX index_name\", sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n    }\n\n    @Test\n    fun useTest() {\n        var sql = \"use bigdata\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.USE, statement.statementType)\n\n        if (statement is UseDatabase) {\n            Assert.assertEquals(\"bigdata\", statement.databaseName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createIndexTest() {\n        val sql = \"CREATE INDEX test_index ON demo.orders (column_name)\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(TableId(\"demo\", \"orders\"), statement.tableId)\n            val createIndex = statement.firstAction() as CreateIndex\n            Assert.assertEquals(\"test_index\", createIndex.indexName)\n        }\n    }\n\n    @Test\n    fun dropIndexTest() {\n        val sql = \"DROP INDEX test_index ON demo.orders\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(TableId(\"demo\", \"orders\"), statement.tableId)\n            val dropIndex = statement.firstAction() as DropIndex\n            Assert.assertEquals(AlterActionType.DROP_INDEX, dropIndex.alterType)\n            Assert.assertEquals(\"test_index\", dropIndex.indexName)\n        }\n    }\n\n    @Test\n    fun truncatePartitionTest() {\n        val sql = \"ALTER TABLE demo.orders TRUNCATE PARTITION p1998\\n\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(AlterActionType.TRUNCATE_PARTITION, statement.firstAction().alterType)\n            Assert.assertEquals(TableId(\"demo\", \"orders\"), statement.tableId)\n        }\n    }\n\n    @Test\n    fun dropPrimarykeyTest() {\n        val sql = \"alter table rd_orders drop primary key\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(AlterActionType.DROP_PRIMARY_KEY, statement.firstAction().alterType)\n            Assert.assertEquals(TableId(\"rd_orders\"), statement.tableId)\n        }\n    }\n\n    @Test\n    fun addPrimarykeyTest() {\n        val sql = \"alter table rd_orders add primary key (name)\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(AlterActionType.ADD_PRIMARY_KEY, statement.firstAction().alterType)\n            Assert.assertEquals(TableId(\"rd_orders\"), statement.tableId)\n        }\n    }\n}\n"
  },
  {
    "path": "superior-mysql-parser/src/test/kotlin/io/github/melin/superior/parser/mysql/MySqlParserDmlTest.kt",
    "content": "package io.github.melin.superior.parser.mysql\n\nimport com.github.melin.superior.sql.parser.mysql.MySqlHelper\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.create.CreateTableAsSelect\nimport io.github.melin.superior.common.relational.dml.DeleteTable\nimport io.github.melin.superior.common.relational.dml.InsertTable\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport io.github.melin.superior.common.relational.dml.UpdateTable\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2018/1/10. */\nclass MySqlParserDmlTest {\n\n    @Test\n    fun selectTest0() {\n        val sql = \"select * from users limit 5, 10\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(5, statement.offset)\n            Assert.assertEquals(10, statement.limit)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun selectTest1() {\n        val sql = \"select * from users a left outer join address b on a.address_id = b.id limit 10 offset 100\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(2, statement.inputTables.size)\n            Assert.assertEquals(10, statement.limit)\n            Assert.assertEquals(100, statement.offset)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest0() {\n        val sql =\n            \"\"\"\n            DELETE FROM films\n            WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest1() {\n        val sql =\n            \"\"\"\n            DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3\n            WHERE t1.id=t2.id AND t2.id=t3.id;\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"t1\", statement.tableId.tableName)\n            Assert.assertEquals(2, statement.outputTables.size)\n            Assert.assertEquals(3, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest2() {\n        val sql =\n            \"\"\"\n            DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3\n            WHERE t1.id=t2.id AND t2.id=t3.id;\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"t1\", statement.tableId.tableName)\n            Assert.assertEquals(2, statement.outputTables.size)\n            Assert.assertEquals(3, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest3() {\n        val sql =\n            \"\"\"\n            DELETE FROM users\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"users\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest0() {\n        val sql =\n            \"\"\"\n            UPDATE employees SET sales_count = sales_count + 1 WHERE id =\n            (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId?.tableName)\n            Assert.assertEquals(2, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest1() {\n        val sql =\n            \"\"\"\n            UPDATE product p LEFT JOIN product_price pp ON p.productid= pp.productid \n            SET p.isdelete = 1 WHERE pp.productid IS NULL;\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"product\", statement.tableId.tableName)\n            Assert.assertEquals(2, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest2() {\n        val sql =\n            \"\"\"\n            update resource_screen_node b join (\n              select \n                concat(region_name,'区域测点') name\n                ,sum(access_station_num) as snum\n                ,sum(access_point_num) as pnum \n              from ads_dmap_datasource_indicator \n              group by region_name\n            ) as a on a.name=b.name\n            set b.access_station=a.snum,b.access_point=pnum;\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"resource_screen_node\", statement.tableId.tableName)\n            Assert.assertEquals(2, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest3() {\n        val sql =\n            \"\"\"\n            UPDATE items,month SET items.price=month.price\n            WHERE items.id=month.id;\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"items\", statement.tableId.tableName)\n            Assert.assertEquals(2, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertValuesTest() {\n        val sql =\n            \"\"\"\n            insert into bigdata.\"user\" select * from users a left outer join address b on a.address_id = b.id\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"bigdata\", statement.tableId?.schemaName)\n            Assert.assertEquals(\"user\", statement.tableId?.tableName)\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun replaceValuesTest() {\n        // val sql = \"insert into user values('name')\"\n        val sql = \"REPLACE into bigdata.user select * from users a left outer join address b on a.address_id = b.id\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"bigdata\", statement.tableId?.schemaName)\n            Assert.assertEquals(\"user\", statement.tableId?.tableName)\n            Assert.assertTrue(statement.mysqlReplace)\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun countCondTest() {\n        val sql = \"select count(type='mac' or null) From test_table where a=2 limit 50\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.SELECT, statement.statementType)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(\"test_table\", statement.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun cteTest0() {\n        val sql =\n            \"\"\"\n            WITH\n              CTE1 AS (SELECT A, B FROM TABLE1),\n              CTE2 AS (SELECT C, D FROM TABLE2)\n            SELECT B, D FROM CTE1 JOIN CTE2\n            WHERE CTE1.A = CTE2.C;\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.SELECT, statement.statementType)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(\"TABLE1\", statement.inputTables.get(0).tableName)\n\n            Assert.assertEquals(2, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun cteTest1() {\n        val sql =\n            \"\"\"\n            INSERT INTO DATES (DATE)\n            SELECT DATE\n            FROM (\n                WITH RECURSIVE DATE_RANGE AS (\n                    SELECT DATE('2023-01-01') AS DATE\n                    UNION ALL\n                    SELECT DATE + INTERVAL 1 DAY\n                    FROM DATE_RANGE\n                    WHERE DATE < '2024-12-31'\n                ),\n                DATE_RANGE2 AS (\n                    SELECT DATE('2025-01-01') AS DATE\n                    UNION ALL\n                    SELECT DATE + INTERVAL 1 DAY\n                    FROM DATE_RANGE2\n                    WHERE DATE < '2025-12-31'\n                )\n                SELECT DATE\n                FROM DATE_RANGE\n                UNION ALL\n                SELECT DATE\n                FROM DATE_RANGE2\n            ) AS DERIVED_TABLE\n            ON DUPLICATE KEY UPDATE DATE = VALUES(DATE);\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.INSERT, statement.statementType)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(TableId(\"DATES\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun cteTest2() {\n        val sql =\n            \"\"\"\n            WITH cte1 AS (SELECT 1)\n            SELECT * FROM (WITH cte2 AS (SELECT 2) SELECT * FROM cte2 JOIN cte1) AS dt;\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.SELECT, statement.statementType)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(0, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun ctasTest0() {\n        val sql = \"create table demo1 as select * from demo\"\n\n        val statement = MySqlHelper.parseStatement(sql)\n        if (statement is CreateTableAsSelect) {\n            Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n            Assert.assertEquals(\"demo1\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-mysql-parser/src/test/kotlin/io/github/melin/superior/parser/mysql/MySqlProcedureParserTest.kt",
    "content": "package io.github.melin.superior.parser.mysql\n\nimport com.github.melin.superior.sql.parser.mysql.MySqlHelper\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.create.CreateProcedure\nimport org.junit.Assert\nimport org.junit.Test\n\nclass MySqlProcedureParserTest {\n\n    @Test\n    fun procedureTest0() {\n        val sql =\n            \"\"\"\n            CREATE PROCEDURE UpdateEmployeeSalary(IN employeeId INT, IN newSalary DECIMAL(10, 2))\n            BEGIN\n                -- Update the salary of an employee with the given ID\n                UPDATE employees\n                SET salary = newSalary\n                WHERE id = employeeId;\n                \n                select * from demos;\n            END;\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(\"UpdateEmployeeSalary\", statement.procedureId?.procedureName)\n            Assert.assertEquals(2, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun procedureTest1() {\n        val sql =\n            \"\"\"\n            create procedure my_procedure()\n            begin\n                declare my_id varchar(32);\n                declare my_name varchar(50);\n                DECLARE done INT DEFAULT FALSE;\n             \n                DECLARE My_Cursor CURSOR FOR ( SELECT id, name FROM t_people ); \n                DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; \n             \n                OPEN My_Cursor; \n                myLoop: LOOP \n                    FETCH My_Cursor into my_id, my_name;\n                    IF done THEN \n                        LEAVE myLoop; \n                    END IF;\n                    UPDATE t_user SET c_name = my_name WHERE id = my_id and rtrim(ltrim(c_name)) = '';\n             \n                    COMMIT;\n                END LOOP myLoop;\n                CLOSE My_Cursor;\n            END;\n        \"\"\"\n                .trimIndent()\n\n        val statement = MySqlHelper.parseStatement(sql)\n\n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(\"my_procedure\", statement.procedureId?.procedureName)\n            Assert.assertEquals(2, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-mysql-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-oracle-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-oracle-parser</artifactId>\n    <name>superior-oracle-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n\n</project>\n"
  },
  {
    "path": "superior-oracle-parser/src/main/antlr4/io/github/melin/superior/parser/oracle/antlr4/OracleLexer.g4",
    "content": "/**\n * Oracle(c) PL/SQL 11g Parser\n *\n * Copyright (c) 2009-2011 Alexandre Porcelli <alexandre.porcelli@gmail.com>\n * Copyright (c) 2015-2019 Ivan Kochurkin (KvanTTT, kvanttt@gmail.com, Positive Technologies).\n * Copyright (c) 2017 Mark Adams <madams51703@gmail.com>\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nlexer grammar OracleLexer;\n\noptions {\n    superClass=OracleLexerBase;\n}\nABORT                          : 'ABORT';\nABS                            : 'ABS';\nABSENT                         : 'ABSENT';\nACCESS                         : 'ACCESS';\nACCESSED                       : 'ACCESSED';\nACCESSIBLE                     : 'ACCESSIBLE';\nACCOUNT                        : 'ACCOUNT';\nACL                            : 'ACL';\nACOS                           : 'ACOS';\nACROSS                         : 'ACROSS';\nACTION                         : 'ACTION';\nACTIONS                        : 'ACTIONS';\nACTIVATE                       : 'ACTIVATE';\nACTIVE                         : 'ACTIVE';\nACTIVE_COMPONENT               : 'ACTIVE_COMPONENT';\nACTIVE_DATA                    : 'ACTIVE_DATA';\nACTIVE_FUNCTION                : 'ACTIVE_FUNCTION';\nACTIVE_TAG                     : 'ACTIVE_TAG';\nACTIVITY                       : 'ACTIVITY';\nADAPTIVE_PLAN                  : 'ADAPTIVE_PLAN';\nADD                            : 'ADD';\nADD_COLUMN                     : 'ADD_COLUMN';\nADD_GROUP                      : 'ADD_GROUP';\nADD_MONTHS                     : 'ADD_MONTHS';\nADJ_DATE                       : 'ADJ_DATE';\nADMIN                          : 'ADMIN';\nADMINISTER                     : 'ADMINISTER';\nADMINISTRATOR                  : 'ADMINISTRATOR';\nADVANCED                       : 'ADVANCED';\nADVISE                         : 'ADVISE';\nADVISOR                        : 'ADVISOR';\nAFD_DISKSTRING                 : 'AFD_DISKSTRING';\nAFTER                          : 'AFTER';\nAGENT                          : 'AGENT';\nAGGREGATE                      : 'AGGREGATE';\nA_LETTER                       : 'A';\nALIAS                          : 'ALIAS';\nALL                            : 'ALL';\nALLOCATE                       : 'ALLOCATE';\nALLOW                          : 'ALLOW';\nALL_ROWS                       : 'ALL_ROWS';\nALTER                          : 'ALTER';\nALTERNATE                      : 'ALTERNATE';\nALWAYS                         : 'ALWAYS';\nANALYTIC                       : 'ANALYTIC';\nANALYZE                        : 'ANALYZE';\nANCESTOR                       : 'ANCESTOR';\nANCILLARY                      : 'ANCILLARY';\nAND                            : 'AND';\nAND_EQUAL                      : 'AND_EQUAL';\nANNOTATIONS                    : 'ANNOTATIONS';\nANOMALY                        : 'ANOMALY';\nANSI_REARCH                    : 'ANSI_REARCH';\nANTIJOIN                       : 'ANTIJOIN';\nANY                            : 'ANY';\nANYSCHEMA                      : 'ANYSCHEMA';\nAPPEND                         : 'APPEND';\nAPPENDCHILDXML                 : 'APPENDCHILDXML';\nAPPEND_VALUES                  : 'APPEND_VALUES';\nAPPLICATION                    : 'APPLICATION';\nAPPLY                          : 'APPLY';\nAPPROX_COUNT_DISTINCT          : 'APPROX_COUNT_DISTINCT';\nARCHIVAL                       : 'ARCHIVAL';\nARCHIVE                        : 'ARCHIVE';\nARCHIVED                       : 'ARCHIVED';\nARCHIVELOG                     : 'ARCHIVELOG';\nARE                            : 'ARE';\nARRAY                          : 'ARRAY';\nAS                             : 'AS';\nASC                            : 'ASC';\nASCII                          : 'ASCII';\nASCIISTR                       : 'ASCIISTR';\nASIN                           : 'ASIN';\nASIS                           : 'ASIS';\nASSEMBLY                       : 'ASSEMBLY';\nASSIGN                         : 'ASSIGN';\nASSOCIATE                      : 'ASSOCIATE';\nASYNC                          : 'ASYNC';\nASYNCHRONOUS                   : 'ASYNCHRONOUS';\nATAN2                          : 'ATAN2';\nATAN                           : 'ATAN';\nAT                             : 'AT';\nATTRIBUTE                      : 'ATTRIBUTE';\nATTRIBUTES                     : 'ATTRIBUTES';\nAUDIT                          : 'AUDIT';\nAUTHENTICATED                  : 'AUTHENTICATED';\nAUTHENTICATION                 : 'AUTHENTICATION';\nAUTHID                         : 'AUTHID';\nAUTHORIZATION                  : 'AUTHORIZATION';\nAUTOALLOCATE                   : 'AUTOALLOCATE';\nAUTO                           : 'AUTO';\nAUTOBACKUP                     : 'AUTOBACKUP';\nAUTOEXTEND                     : 'AUTOEXTEND';\nAUTO_LOGIN                     : 'AUTO_LOGIN';\nAUTOMATIC                      : 'AUTOMATIC';\nAUTONOMOUS_TRANSACTION         : 'AUTONOMOUS_TRANSACTION';\nAUTO_REOPTIMIZE                : 'AUTO_REOPTIMIZE';\nAVAILABILITY                   : 'AVAILABILITY';\nAVRO                           : 'AVRO';\nBACKGROUND                     : 'BACKGROUND';\nBACKINGFILE                    : 'BACKINGFILE';\nBACKUP                         : 'BACKUP';\nBACKUPS                        : 'BACKUPS';\nBACKUPSET                      : 'BACKUPSET';\nBADFILE                        : 'BADFILE';\nBASIC                          : 'BASIC';\nBASICFILE                      : 'BASICFILE';\nBATCH                          : 'BATCH';\nBATCHSIZE                      : 'BATCHSIZE';\nBATCH_TABLE_ACCESS_BY_ROWID    : 'BATCH_TABLE_ACCESS_BY_ROWID';\nBECOME                         : 'BECOME';\nBEFORE                         : 'BEFORE';\nBEGIN                          : 'BEGIN';\nBEGINNING                      : 'BEGINNING';\nBEGIN_OUTLINE_DATA             : 'BEGIN_OUTLINE_DATA';\nBEHALF                         : 'BEHALF';\nBEQUEATH                       : 'BEQUEATH';\nBETWEEN                        : 'BETWEEN';\nBFILE                          : 'BFILE';\nBFILENAME                      : 'BFILENAME';\nBIG                            : 'BIG';\nBIGFILE                        : 'BIGFILE';\nBIGINT                         : 'BIGINT';\nBINARY                         : 'BINARY';\nBINARY_DOUBLE                  : 'BINARY_DOUBLE';\nBINARY_DOUBLE_INFINITY         : 'BINARY_DOUBLE_INFINITY';\nBINARY_DOUBLE_NAN              : 'BINARY_DOUBLE_NAN';\nBINARY_FLOAT                   : 'BINARY_FLOAT';\nBINARY_FLOAT_INFINITY          : 'BINARY_FLOAT_INFINITY';\nBINARY_FLOAT_NAN               : 'BINARY_FLOAT_NAN';\nBINARY_INTEGER                 : 'BINARY_INTEGER';\nBIND_AWARE                     : 'BIND_AWARE';\nBINDING                        : 'BINDING';\nBIN_TO_NUM                     : 'BIN_TO_NUM';\nBITAND                         : 'BITAND';\nBITMAP_AND                     : 'BITMAP_AND';\nBITMAP                         : 'BITMAP';\nBITMAPS                        : 'BITMAPS';\nBITMAP_TREE                    : 'BITMAP_TREE';\nBITS                           : 'BITS';\nBLANKS                         : 'BLANKS';\nBLOB                           : 'BLOB';\nBLOCK                          : 'BLOCK';\nBLOCK_RANGE                    : 'BLOCK_RANGE';\nBLOCKS                         : 'BLOCKS';\nBLOCKSIZE                      : 'BLOCKSIZE';\nBODY                           : 'BODY';\nBOOLEAN                        : 'BOOLEAN';\nBOTH                           : 'BOTH';\nBOUND                          : 'BOUND';\nBRANCH                         : 'BRANCH';\nBREADTH                        : 'BREADTH';\nBROADCAST                      : 'BROADCAST';\nBSON                           : 'BSON';\nBUFFER                         : 'BUFFER';\nBUFFER_CACHE                   : 'BUFFER_CACHE';\nBUFFER_POOL                    : 'BUFFER_POOL';\nBUILD                          : 'BUILD';\nBULK                           : 'BULK';\nBY                             : 'BY';\nBYPASS_RECURSIVE_CHECK         : 'BYPASS_RECURSIVE_CHECK';\nBYPASS_UJVC                    : 'BYPASS_UJVC';\nBYTE                           : 'BYTE';\nBYTES                          : 'BYTES';\nBYTEORDERMARK                  : 'BYTEORDERMARK';\nCACHE                          : 'CACHE';\nCACHE_CB                       : 'CACHE_CB';\nCACHE_INSTANCES                : 'CACHE_INSTANCES';\nCACHE_TEMP_TABLE               : 'CACHE_TEMP_TABLE';\nCACHING                        : 'CACHING';\nCALCULATED                     : 'CALCULATED';\nCALLBACK                       : 'CALLBACK';\nCALL                           : 'CALL';\nCANCEL                         : 'CANCEL';\nCANONICAL                      : 'CANONICAL';\nCAPACITY                       : 'CAPACITY';\nCAPTION                        : 'CAPTION';\nCARDINALITY                    : 'CARDINALITY';\nCASCADE                        : 'CASCADE';\nCASE                           : 'CASE';\nCAST                           : 'CAST';\nCASESENSITIVE                  : 'CASE-SENSITIVE';\nCATEGORY                       : 'CATEGORY';\nCDBDEFAULT                     : 'CDB$DEFAULT';\nCEIL                           : 'CEIL';\nCELL_FLASH_CACHE               : 'CELL_FLASH_CACHE';\nCERTIFICATE                    : 'CERTIFICATE';\nCFILE                          : 'CFILE';\nCHAINED                        : 'CHAINED';\nCHANGE                         : 'CHANGE';\nCHANGETRACKING                 : 'CHANGETRACKING';\nCHANGE_DUPKEY_ERROR_INDEX      : 'CHANGE_DUPKEY_ERROR_INDEX';\nCHARACTER                      : 'CHARACTER';\nCHARACTERS                     : 'CHARACTERS';\nCHARACTERSET                   : 'CHARACTERSET';\nCHAR                           : 'CHAR';\nCHAR_CS                        : 'CHAR_CS';\nCHARTOROWID                    : 'CHARTOROWID';\nCHECK_ACL_REWRITE              : 'CHECK_ACL_REWRITE';\nCHECK                          : 'CHECK';\nCHECKPOINT                     : 'CHECKPOINT';\nCHILD                          : 'CHILD';\nCHOOSE                         : 'CHOOSE';\nCHR                            : 'CHR';\nCHUNK                          : 'CHUNK';\nCLASS                          : 'CLASS';\nCLASSIFICATION                 : 'CLASSIFICATION';\nCLASSIFIER                     : 'CLASSIFIER';\nCLAUSE                         : 'CLAUSE';\nCLEAN                          : 'CLEAN';\nCLEANUP                        : 'CLEANUP';\nCLEAR                          : 'CLEAR';\nC_LETTER                       : 'C';\nCLIENT                         : 'CLIENT';\nCLOB                           : 'CLOB';\nCLONE                          : 'CLONE';\nCLOSE_CACHED_OPEN_CURSORS      : 'CLOSE_CACHED_OPEN_CURSORS';\nCLOSE                          : 'CLOSE';\nCLUSTER_BY_ROWID               : 'CLUSTER_BY_ROWID';\nCLUSTER                        : 'CLUSTER';\nCLUSTER_DETAILS                : 'CLUSTER_DETAILS';\nCLUSTER_DISTANCE               : 'CLUSTER_DISTANCE';\nCLUSTER_ID                     : 'CLUSTER_ID';\nCLUSTERING                     : 'CLUSTERING';\nCLUSTERING_FACTOR              : 'CLUSTERING_FACTOR';\nCLUSTER_PROBABILITY            : 'CLUSTER_PROBABILITY';\nCLUSTER_SET                    : 'CLUSTER_SET';\nCOALESCE                       : 'COALESCE';\nCOALESCE_SQ                    : 'COALESCE_SQ';\nCOARSE                         : 'COARSE';\nCO_AUTH_IND                    : 'CO_AUTH_IND';\nCOLD                           : 'COLD';\nCOLLECT                        : 'COLLECT';\nCOLLECTION                     : 'COLLECTION';\nCOLUMNAR                       : 'COLUMNAR';\nCOLUMN_AUTH_INDICATOR          : 'COLUMN_AUTH_INDICATOR';\nCOLUMN                         : 'COLUMN';\nCOLUMNS                        : 'COLUMNS';\nCOLUMN_STATS                   : 'COLUMN_STATS';\nCOLUMN_VALUE                   : 'COLUMN_VALUE';\nCOMMENT                        : 'COMMENT';\nCOMMIT                         : 'COMMIT';\nCOMMITTED                      : 'COMMITTED';\nCOMMON                         : 'COMMON';\nCOMMON_DATA                    : 'COMMON_DATA';\nCOMPACT                        : 'COMPACT';\nCOMPATIBLE                     : 'COMPATIBLE';\nCOMPATIBILITY                  : 'COMPATIBILITY';\nCOMPILE                        : 'COMPILE';\nCOMPLETE                       : 'COMPLETE';\nCOMPLIANCE                     : 'COMPLIANCE';\nCOMPONENT                      : 'COMPONENT';\nCOMPONENTS                     : 'COMPONENTS';\nCOMPOSE                        : 'COMPOSE';\nCOMPOSITE                      : 'COMPOSITE';\nCOMPOSITE_LIMIT                : 'COMPOSITE_LIMIT';\nCOMPOUND                       : 'COMPOUND';\nCOMPRESS                       : 'COMPRESS';\nCOMPRESSION                    : 'COMPRESSION';\nCOMPUTE                        : 'COMPUTE';\nCONCAT                         : 'CONCAT';\nCON_DBID_TO_ID                 : 'CON_DBID_TO_ID';\nCONDITIONAL                    : 'CONDITIONAL';\nCONDITION                      : 'CONDITION';\nCONFIRM                        : 'CONFIRM';\nCONFORMING                     : 'CONFORMING';\nCON_GUID_TO_ID                 : 'CON_GUID_TO_ID';\nCON_ID                         : 'CON_ID';\nCON_NAME_TO_ID                 : 'CON_NAME_TO_ID';\nCONNECT_BY_CB_WHR_ONLY         : 'CONNECT_BY_CB_WHR_ONLY';\nCONNECT_BY_COMBINE_SW          : 'CONNECT_BY_COMBINE_SW';\nCONNECT_BY_COST_BASED          : 'CONNECT_BY_COST_BASED';\nCONNECT_BY_ELIM_DUPS           : 'CONNECT_BY_ELIM_DUPS';\nCONNECT_BY_FILTERING           : 'CONNECT_BY_FILTERING';\nCONNECT_BY_ISCYCLE             : 'CONNECT_BY_ISCYCLE';\nCONNECT_BY_ISLEAF              : 'CONNECT_BY_ISLEAF';\nCONNECT_BY_ROOT                : 'CONNECT_BY_ROOT';\nCONNECT                        : 'CONNECT';\nCONNECT_TIME                   : 'CONNECT_TIME';\nCONSIDER                       : 'CONSIDER';\nCONSISTENT                     : 'CONSISTENT';\nCONSTANT                       : 'CONSTANT';\nCONST                          : 'CONST';\nCONSTRAINT                     : 'CONSTRAINT';\nCONSTRAINTS                    : 'CONSTRAINTS';\nCONSTRUCTOR                    : 'CONSTRUCTOR';\nCONTAINER                      : 'CONTAINER';\nCONTAINERS                     : 'CONTAINERS';\nCONTAINERS_DEFAULT             : 'CONTAINERS_DEFAULT';\nCONTAINER_DATA                 : 'CONTAINER_DATA';\nCONTAINER_MAP                  : 'CONTAINER_MAP';\nCONTENT                        : 'CONTENT';\nCONTENTS                       : 'CONTENTS';\nCONTEXT                        : 'CONTEXT';\nCONTINUE                       : 'CONTINUE';\nCONTROLFILE                    : 'CONTROLFILE';\nCON_UID_TO_ID                  : 'CON_UID_TO_ID';\nCONVERT                        : 'CONVERT';\nCONVERSION                     : 'CONVERSION';\nCOOKIE                         : 'COOKIE';\nCOPY                           : 'COPY';\nCORR_K                         : 'CORR_K';\nCORR_S                         : 'CORR_S';\nCORRUPTION                     : 'CORRUPTION';\nCORRUPT_XID_ALL                : 'CORRUPT_XID_ALL';\nCORRUPT_XID                    : 'CORRUPT_XID';\nCOS                            : 'COS';\nCOSH                           : 'COSH';\nCOST                           : 'COST';\nCOST_XML_QUERY_REWRITE         : 'COST_XML_QUERY_REWRITE';\nCOUNT                          : 'COUNT';\nCOUNTED                        : 'COUNTED';\nCOVAR_POP                      : 'COVAR_POP';\nCOVAR_SAMP                     : 'COVAR_SAMP';\nCPU_COSTING                    : 'CPU_COSTING';\nCPU_PER_CALL                   : 'CPU_PER_CALL';\nCPU_PER_SESSION                : 'CPU_PER_SESSION';\nCRASH                          : 'CRASH';\nCREATE                         : 'CREATE';\nCREATE_FILE_DEST               : 'CREATE_FILE_DEST';\nCREATE_STORED_OUTLINES         : 'CREATE_STORED_OUTLINES';\nCREATION                       : 'CREATION';\nCREDENTIAL                     : 'CREDENTIAL';\nCRITICAL                       : 'CRITICAL';\nCROSS                          : 'CROSS';\nCROSSEDITION                   : 'CROSSEDITION';\nCSCONVERT                      : 'CSCONVERT';\nCSV                            : 'CSV';\nCUBE_AJ                        : 'CUBE_AJ';\nCUBE                           : 'CUBE';\nCUBE_GB                        : 'CUBE_GB';\nCUBE_SJ                        : 'CUBE_SJ';\nCUME_DISTM                     : 'CUME_DISTM';\nCURRENT                        : 'CURRENT';\nCURRENT_DATE                   : 'CURRENT_DATE';\nCURRENT_SCHEMA                 : 'CURRENT_SCHEMA';\nCURRENT_TIME                   : 'CURRENT_TIME';\nCURRENT_TIMESTAMP              : 'CURRENT_TIMESTAMP';\nCURRENT_USER                   : 'CURRENT_USER';\nCURRENTV                       : 'CURRENTV';\nCURSOR                         : 'CURSOR';\nCURSOR_SHARING_EXACT           : 'CURSOR_SHARING_EXACT';\nCURSOR_SPECIFIC_SEGMENT        : 'CURSOR_SPECIFIC_SEGMENT';\nCUSTOMDATUM                    : 'CUSTOMDATUM';\nCV                             : 'CV';\nCYCLE                          : 'CYCLE';\nDANGLING                       : 'DANGLING';\nDATABASE                       : 'DATABASE';\nDATA                           : 'DATA';\nDATAFILE                       : 'DATAFILE';\nDATAFILES                      : 'DATAFILES';\nDATAGUARDCONFIG                : 'DATAGUARDCONFIG';\nDATAMOVEMENT                   : 'DATAMOVEMENT';\nDATAOBJNO                      : 'DATAOBJNO';\nDATAOBJ_TO_MAT_PARTITION       : 'DATAOBJ_TO_MAT_PARTITION';\nDATAOBJ_TO_PARTITION           : 'DATAOBJ_TO_PARTITION';\nDATAPUMP                       : 'DATAPUMP';\nDATA_SECURITY_REWRITE_LIMIT    : 'DATA_SECURITY_REWRITE_LIMIT';\nDATE                           : 'DATE';\nDATE_CACHE                     : 'DATE_CACHE';\nDATE_FORMAT                    : 'DATE_FORMAT';\nDATE_MODE                      : 'DATE_MODE';\nDAY                            : 'DAY';\nDAYS                           : 'DAYS';\nDAY_TO_SECOND                  : 'DAY_TO_SECOND';\nDBA                            : 'DBA';\nDBA_RECYCLEBIN                 : 'DBA_RECYCLEBIN';\nDBLINK                         : 'DBLINK';\nDBMS_STATS                     : 'DBMS_STATS';\nDB_ROLE_CHANGE                 : 'DB_ROLE_CHANGE';\nDBTIMEZONE                     : 'DBTIMEZONE';\nDB_UNIQUE_NAME                 : 'DB_UNIQUE_NAME';\nDB_VERSION                     : 'DB_VERSION';\nDDL                            : 'DDL';\nDEALLOCATE                     : 'DEALLOCATE';\nDEBUG                          : 'DEBUG';\nDEBUGGER                       : 'DEBUGGER';\nDEC                            : 'DEC';\nDECIMAL                        : 'DECIMAL';\nDECLARE                        : 'DECLARE';\nDECOMPOSE                      : 'DECOMPOSE';\nDECORRELATE                    : 'DECORRELATE';\nDECR                           : 'DECR';\nDECREMENT                      : 'DECREMENT';\nDECRYPT                        : 'DECRYPT';\nDEDUPLICATE                    : 'DEDUPLICATE';\nDEFAULT                        : 'DEFAULT';\nDEFAULTIF                      : 'DEFAULTIF';\nDEFAULTS                       : 'DEFAULTS';\nDEFAULT_COLLATION              : 'DEFAULT_COLLATION';\nDEFAULT_CREDENTIAL             : 'DEFAULT_CREDENTIAL';\nDEFERRABLE                     : 'DEFERRABLE';\nDEFERRED                       : 'DEFERRED';\nDEFINED                        : 'DEFINED';\nDEFINE                         : 'DEFINE';\nDEFINER                        : 'DEFINER';\nDEGREE                         : 'DEGREE';\nDELAY                          : 'DELAY';\nDELEGATE                       : 'DELEGATE';\nDELETE_ALL                     : 'DELETE_ALL';\nDELETE                         : 'DELETE';\nDELETEXML                      : 'DELETEXML';\nDELIMITED                      : 'DELIMITED';\nDEMAND                         : 'DEMAND';\nDENSE_RANKM                    : 'DENSE_RANKM';\nDEPENDENT                      : 'DEPENDENT';\nDEPRECATE                      : 'DEPRECATE';\nDEPTH                          : 'DEPTH';\nDEQUEUE                        : 'DEQUEUE';\nDEREF                          : 'DEREF';\nDEREF_NO_REWRITE               : 'DEREF_NO_REWRITE';\nDESC                           : 'DESC';\nDESCRIPTION                    : 'DESCRIPTION';\nDESTROY                        : 'DESTROY';\nDETACHED                       : 'DETACHED';\nDETECTED                       : 'DETECTED';\nDETERMINES                     : 'DETERMINES';\nDETERMINISTIC                  : 'DETERMINISTIC';\nDICTIONARY                     : 'DICTIONARY';\nDIMENSION                      : 'DIMENSION';\nDIMENSIONS                     : 'DIMENSIONS';\nDIRECTIO                       : 'DIRECTIO';\nDIRECT_LOAD                    : 'DIRECT_LOAD';\nDIRECTORY                      : 'DIRECTORY';\nDIRECT_PATH                    : 'DIRECT_PATH';\nDISABLE_ALL                    : 'DISABLE_ALL';\nDISABLE                        : 'DISABLE';\nDISABLED                       : 'DISABLED';\nDISABLE_DIRECTORY_LINK_CHECK   : 'DISABLE_DIRECTORY_LINK_CHECK';\nDISABLE_PARALLEL_DML           : 'DISABLE_PARALLEL_DML';\nDISABLE_PRESET                 : 'DISABLE_PRESET';\nDISABLE_RPKE                   : 'DISABLE_RPKE';\nDISALLOW                       : 'DISALLOW';\nDISASSOCIATE                   : 'DISASSOCIATE';\nDISCARD                        : 'DISCARD';\nDISCARDFILE                    : 'DISCARDFILE';\nDISCONNECT                     : 'DISCONNECT';\nDISK                           : 'DISK';\nDISKGROUP                      : 'DISKGROUP';\nDISKGROUP_PLUS                 : '\\'+ DISKGROUP';\nDISKS                          : 'DISKS';\nDISMOUNT                       : 'DISMOUNT';\nDISTINCT                       : 'DISTINCT';\nDISTINGUISHED                  : 'DISTINGUISHED';\nDISTRIBUTED                    : 'DISTRIBUTED';\nDISTRIBUTE                     : 'DISTRIBUTE';\nDML                            : 'DML';\nDML_UPDATE                     : 'DML_UPDATE';\nDNFS_DISABLE                   : 'DNFS_DISABLE';\nDNFS_ENABLE                    : 'DNFS_ENABLE';\nDNFS_READBUFFERS               : 'DNFS_READBUFFERS';\nDOCFIDELITY                    : 'DOCFIDELITY';\nDOCUMENT                       : 'DOCUMENT';\nDOLLAR_ELSE                    : '$ELSE';\nDOLLAR_ELSIF                   : '$ELSIF';\nDOLLAR_END                     : '$END';\nDOLLAR_ERROR                   : '$ERROR';\nDOLLAR_IF                      : '$IF';\nDOLLAR_THEN                    : '$THEN';\nDOMAIN_INDEX_FILTER            : 'DOMAIN_INDEX_FILTER';\nDOMAIN_INDEX_NO_SORT           : 'DOMAIN_INDEX_NO_SORT';\nDOMAIN_INDEX_SORT              : 'DOMAIN_INDEX_SORT';\nDOUBLE                         : 'DOUBLE';\nDOWNGRADE                      : 'DOWNGRADE';\nDRIVING_SITE                   : 'DRIVING_SITE';\nDROP_COLUMN                    : 'DROP_COLUMN';\nDROP                           : 'DROP';\nDROP_GROUP                     : 'DROP_GROUP';\nDSINTERVAL_UNCONSTRAINED       : 'DSINTERVAL_UNCONSTRAINED';\nDST_UPGRADE_INSERT_CONV        : 'DST_UPGRADE_INSERT_CONV';\nDUMP                           : 'DUMP';\nDUMPSET                        : 'DUMPSET';\nDUPLICATE                      : 'DUPLICATE';\nDV                             : 'DV';\nDYNAMIC                        : 'DYNAMIC';\nDYNAMIC_SAMPLING               : 'DYNAMIC_SAMPLING';\nDYNAMIC_SAMPLING_EST_CDN       : 'DYNAMIC_SAMPLING_EST_CDN';\nE_LETTER                       : 'E';\nEACH                           : 'EACH';\nEDITIONABLE                    : 'EDITIONABLE';\nEDITION                        : 'EDITION';\nEDITIONING                     : 'EDITIONING';\nEDITIONS                       : 'EDITIONS';\nELEMENT                        : 'ELEMENT';\nELIM_GROUPBY                   : 'ELIM_GROUPBY';\nELIMINATE_JOIN                 : 'ELIMINATE_JOIN';\nELIMINATE_OBY                  : 'ELIMINATE_OBY';\nELIMINATE_OUTER_JOIN           : 'ELIMINATE_OUTER_JOIN';\nELSE                           : 'ELSE';\nELSIF                          : 'ELSIF';\nEM                             : 'EM';\nEMBEDDED                       : 'EMBEDDED';\nEMPTY_BLOB                     : 'EMPTY_BLOB';\nEMPTY_CLOB                     : 'EMPTY_CLOB';\nEMPTY_                         : 'EMPTY';\nENABLE_ALL                     : 'ENABLE_ALL';\nENABLE                         : 'ENABLE';\nENABLED                        : 'ENABLED';\nENABLE_PARALLEL_DML            : 'ENABLE_PARALLEL_DML';\nENABLE_PRESET                  : 'ENABLE_PRESET';\nENCLOSED                       : 'ENCLOSED';\nENCODING                       : 'ENCODING';\nENCRYPT                        : 'ENCRYPT';\nENCRYPTION                     : 'ENCRYPTION';\nENCRYPTPASSWORDISNULL          : 'ENCRYPTPASSWORDISNULL';\nEND                            : 'END';\nEND_OUTLINE_DATA               : 'END_OUTLINE_DATA';\nENDIAN                         : 'ENDIAN';\nENFORCED                       : 'ENFORCED';\nENFORCE                        : 'ENFORCE';\nENQUEUE                        : 'ENQUEUE';\nENTERPRISE                     : 'ENTERPRISE';\nENTITYESCAPING                 : 'ENTITYESCAPING';\nENTRY                          : 'ENTRY';\nEQUIPART                       : 'EQUIPART';\nERR                            : 'ERR';\nERROR_ARGUMENT                 : 'ERROR_ARGUMENT';\nERROR                          : 'ERROR';\nERROR_ON_OVERLAP_TIME          : 'ERROR_ON_OVERLAP_TIME';\nERRORS                         : 'ERRORS';\nERROR_INDEX                    : 'ERROR_INDEX';\nERROR_CODE                     : 'ERROR_CODE';\nESCAPE                         : 'ESCAPE';\nESCAPED                        : 'ESCAPED';\nESTIMATE                       : 'ESTIMATE';\nEVAL                           : 'EVAL';\nEVALNAME                       : 'EVALNAME';\nEVALUATE                       : 'EVALUATE';\nEVALUATION                     : 'EVALUATION';\nEVENTS                         : 'EVENTS';\nEVERY                          : 'EVERY';\nEXCEPT                         : 'EXCEPT';\nEXCEPTION                      : 'EXCEPTION';\nEXCEPTION_INIT                 : 'EXCEPTION_INIT';\nEXCEPTIONS                     : 'EXCEPTIONS';\nEXCHANGE                       : 'EXCHANGE';\nEXCLUDE                        : 'EXCLUDE';\nEXCLUDING                      : 'EXCLUDING';\nEXCLUSIVE                      : 'EXCLUSIVE';\nEXECUTE                        : 'EXECUTE';\nEXEMPT                         : 'EXEMPT';\nEXISTING                       : 'EXISTING';\nEXISTS                         : 'EXISTS';\nEXISTSNODE                     : 'EXISTSNODE';\nEXIT                           : 'EXIT';\nEXPAND_GSET_TO_UNION           : 'EXPAND_GSET_TO_UNION';\nEXPAND_TABLE                   : 'EXPAND_TABLE';\nEXP                            : 'EXP';\nEXPIRE                         : 'EXPIRE';\nEXPLAIN                        : 'EXPLAIN';\nEXPLOSION                      : 'EXPLOSION';\nEXPORT                         : 'EXPORT';\nEXPR_CORR_CHECK                : 'EXPR_CORR_CHECK';\nEXPRESS                        : 'EXPRESS';\nEXTENDS                        : 'EXTENDS';\nEXTENT                         : 'EXTENT';\nEXTENTS                        : 'EXTENTS';\nEXTERNAL                       : 'EXTERNAL';\nEXTERNALLY                     : 'EXTERNALLY';\nEXTRACTCLOBXML                 : 'EXTRACTCLOBXML';\nEXTRACT                        : 'EXTRACT';\nEXTRACTVALUE                   : 'EXTRACTVALUE';\nEXTRA                          : 'EXTRA';\nFACILITY                       : 'FACILITY';\nFACT                           : 'FACT';\nFACTOR                         : 'FACTOR';\nFACTORIZE_JOIN                 : 'FACTORIZE_JOIN';\nFAILED                         : 'FAILED';\nFAILED_LOGIN_ATTEMPTS          : 'FAILED_LOGIN_ATTEMPTS';\nFAILGROUP                      : 'FAILGROUP';\nFAILOVER                       : 'FAILOVER';\nFAILURE                        : 'FAILURE';\nFALSE                          : 'FALSE';\nFAMILY                         : 'FAMILY';\nFAR                            : 'FAR';\nFAST                           : 'FAST';\nFASTSTART                      : 'FASTSTART';\nFBTSCAN                        : 'FBTSCAN';\nFEATURE                        : 'FEATURE';\nFEATURE_DETAILS                : 'FEATURE_DETAILS';\nFEATURE_ID                     : 'FEATURE_ID';\nFEATURE_SET                    : 'FEATURE_SET';\nFEATURE_VALUE                  : 'FEATURE_VALUE';\nFETCH                          : 'FETCH';\nFIELD                          : 'FIELD';\nFIELDS                         : 'FIELDS';\nFILE                           : 'FILE';\nFILE_NAME_CONVERT              : 'FILE_NAME_CONVERT';\nFILEGROUP                      : 'FILEGROUP';\nFILESTORE                      : 'FILESTORE';\nFILESYSTEM_LIKE_LOGGING        : 'FILESYSTEM_LIKE_LOGGING';\nFILTER                         : 'FILTER';\nFINAL                          : 'FINAL';\nFINE                           : 'FINE';\nFINISH                         : 'FINISH';\nFIRST                          : 'FIRST';\nFIRSTM                         : 'FIRSTM';\nFIRST_ROWS                     : 'FIRST_ROWS';\nFIRST_VALUE                    : 'FIRST_VALUE';\nFIXED                          : 'FIXED';\nFIXED_VIEW_DATA                : 'FIXED_VIEW_DATA';\nFLAGGER                        : 'FLAGGER';\nFLASHBACK                      : 'FLASHBACK';\nFLASH_CACHE                    : 'FLASH_CACHE';\nFLOAT                          : 'FLOAT';\nFLOB                           : 'FLOB';\nFLEX                           : 'FLEX';\nFLOOR                          : 'FLOOR';\nFLUSH                          : 'FLUSH';\nFOLDER                         : 'FOLDER';\nFOLLOWING                      : 'FOLLOWING';\nFOLLOWS                        : 'FOLLOWS';\nFORALL                         : 'FORALL';\nFORCE                          : 'FORCE';\nFORCE_XML_QUERY_REWRITE        : 'FORCE_XML_QUERY_REWRITE';\nFOREIGN                        : 'FOREIGN';\nFOREVER                        : 'FOREVER';\nFOR                            : 'FOR';\nFORMAT                         : 'FORMAT';\nFORWARD                        : 'FORWARD';\nFRAGMENT_NUMBER                : 'FRAGMENT_NUMBER';\nFREELIST                       : 'FREELIST';\nFREELISTS                      : 'FREELISTS';\nFREEPOOLS                      : 'FREEPOOLS';\nFRESH                          : 'FRESH';\nFROM                           : 'FROM';\nFROM_TZ                        : 'FROM_TZ';\nFULL                           : 'FULL';\nFULL_OUTER_JOIN_TO_OUTER       : 'FULL_OUTER_JOIN_TO_OUTER';\nFUNCTION                       : 'FUNCTION';\nFUNCTIONS                      : 'FUNCTIONS';\nFTP                            : 'FTP';\nG_LETTER                       : 'G';\nGATHER_OPTIMIZER_STATISTICS    : 'GATHER_OPTIMIZER_STATISTICS';\nGATHER_PLAN_STATISTICS         : 'GATHER_PLAN_STATISTICS';\nGBY_CONC_ROLLUP                : 'GBY_CONC_ROLLUP';\nGBY_PUSHDOWN                   : 'GBY_PUSHDOWN';\nGENERATED                      : 'GENERATED';\nGET                            : 'GET';\nGLOBAL                         : 'GLOBAL';\nGLOBALLY                       : 'GLOBALLY';\nGLOBAL_NAME                    : 'GLOBAL_NAME';\nGLOBAL_TOPIC_ENABLED           : 'GLOBAL_TOPIC_ENABLED';\nGOTO                           : 'GOTO';\nGRANT                          : 'GRANT';\nGROUP_BY                       : 'GROUP_BY';\nGROUP                          : 'GROUP';\nGROUP_ID                       : 'GROUP_ID';\nGROUPING                       : 'GROUPING';\nGROUPING_ID                    : 'GROUPING_ID';\nGROUPS                         : 'GROUPS';\nGUARANTEED                     : 'GUARANTEED';\nGUARANTEE                      : 'GUARANTEE';\nGUARD                          : 'GUARD';\nHADOOP_TRAILERS                : 'HADOOP_TRAILERS';\nHALF_YEARS                     : 'HALF_YEARS';\nHASH_AJ                        : 'HASH_AJ';\nHASH                           : 'HASH';\nHASHKEYS                       : 'HASHKEYS';\nHASH_SJ                        : 'HASH_SJ';\nHAVING                         : 'HAVING';\nHEADER                         : 'HEADER';\nHEAP                           : 'HEAP';\nHELP                           : 'HELP';\nHEXTORAW                       : 'HEXTORAW';\nHEXTOREF                       : 'HEXTOREF';\nHIDDEN_KEYWORD                 : 'HIDDEN';\nHIDE                           : 'HIDE';\nHIER_ORDER                     : 'HIER_ORDER';\nHIERARCHICAL                   : 'HIERARCHICAL';\nHIERARCHIES                    : 'HIERARCHIES';\nHIERARCHY                      : 'HIERARCHY';\nHIGH                           : 'HIGH';\nHINTSET_BEGIN                  : 'HINTSET_BEGIN';\nHINTSET_END                    : 'HINTSET_END';\nHOT                            : 'HOT';\nHOUR                           : 'HOUR';\nHOURS                          : 'HOURS';\nHTTP                           : 'HTTP';\nHWM_BROKERED                   : 'HWM_BROKERED';\nHYBRID                         : 'HYBRID';\nH_LETTER                       : 'H';\nIDENTIFIED                     : 'IDENTIFIED';\nIDENTIFIER                     : 'IDENTIFIER';\nIDENTITY                       : 'IDENTITY';\nIDGENERATORS                   : 'IDGENERATORS';\nID                             : 'ID';\nIDLE_TIME                      : 'IDLE_TIME';\nIF                             : 'IF';\nIGNORE                         : 'IGNORE';\nIGNORE_CHARS_AFTER_EOR         : 'IGNORE_CHARS_AFTER_EOR';\nIGNORE_OPTIM_EMBEDDED_HINTS    : 'IGNORE_OPTIM_EMBEDDED_HINTS';\nIGNORE_ROW_ON_DUPKEY_INDEX     : 'IGNORE_ROW_ON_DUPKEY_INDEX';\nIGNORE_WHERE_CLAUSE            : 'IGNORE_WHERE_CLAUSE';\nILM                            : 'ILM';\nIMMEDIATE                      : 'IMMEDIATE';\nIMPACT                         : 'IMPACT';\nIMPORT                         : 'IMPORT';\nINACTIVE                       : 'INACTIVE';\nINACTIVE_ACCOUNT_TIME          : 'INACTIVE_ACCOUNT_TIME';\nINCLUDE                        : 'INCLUDE';\nINCLUDE_VERSION                : 'INCLUDE_VERSION';\nINCLUDING                      : 'INCLUDING';\nINCREMENTAL                    : 'INCREMENTAL';\nINCREMENT                      : 'INCREMENT';\nINCR                           : 'INCR';\nINDENT                         : 'INDENT';\nINDEX_ASC                      : 'INDEX_ASC';\nINDEX_COMBINE                  : 'INDEX_COMBINE';\nINDEX_DESC                     : 'INDEX_DESC';\nINDEXED                        : 'INDEXED';\nINDEXES                        : 'INDEXES';\nINDEX_FFS                      : 'INDEX_FFS';\nINDEX_FILTER                   : 'INDEX_FILTER';\nINDEX                          : 'INDEX';\nINDEXING                       : 'INDEXING';\nINDEX_JOIN                     : 'INDEX_JOIN';\nINDEX_ROWS                     : 'INDEX_ROWS';\nINDEX_RRS                      : 'INDEX_RRS';\nINDEX_RS_ASC                   : 'INDEX_RS_ASC';\nINDEX_RS_DESC                  : 'INDEX_RS_DESC';\nINDEX_RS                       : 'INDEX_RS';\nINDEX_SCAN                     : 'INDEX_SCAN';\nINDEX_SKIP_SCAN                : 'INDEX_SKIP_SCAN';\nINDEX_SS_ASC                   : 'INDEX_SS_ASC';\nINDEX_SS_DESC                  : 'INDEX_SS_DESC';\nINDEX_SS                       : 'INDEX_SS';\nINDEX_STATS                    : 'INDEX_STATS';\nINDEXTYPE                      : 'INDEXTYPE';\nINDEXTYPES                     : 'INDEXTYPES';\nINDICATOR                      : 'INDICATOR';\nINDICES                        : 'INDICES';\nINFINITE                       : 'INFINITE';\nINFORMATIONAL                  : 'INFORMATIONAL';\nINHERIT                        : 'INHERIT';\nIN                             : 'IN';\nINITCAP                        : 'INITCAP';\nINITIAL                        : 'INITIAL';\nINITIALIZED                    : 'INITIALIZED';\nINITIALLY                      : 'INITIALLY';\nINITRANS                       : 'INITRANS';\nINLINE                         : 'INLINE';\nINLINE_XMLTYPE_NT              : 'INLINE_XMLTYPE_NT';\nINMEMORY                       : 'INMEMORY';\nIN_MEMORY_METADATA             : 'IN_MEMORY_METADATA';\nINMEMORY_PRUNING               : 'INMEMORY_PRUNING';\nINNER                          : 'INNER';\nINOUT                          : 'INOUT';\nINPLACE                        : 'INPLACE';\nINPUTFORMAT                    : 'INPUTFORMAT';\nINSERTCHILDXMLAFTER            : 'INSERTCHILDXMLAFTER';\nINSERTCHILDXMLBEFORE           : 'INSERTCHILDXMLBEFORE';\nINSERTCHILDXML                 : 'INSERTCHILDXML';\nINSERT                         : 'INSERT';\nINSERTXMLAFTER                 : 'INSERTXMLAFTER';\nINSERTXMLBEFORE                : 'INSERTXMLBEFORE';\nINSTANCE                       : 'INSTANCE';\nINSTANCES                      : 'INSTANCES';\nINSTANTIABLE                   : 'INSTANTIABLE';\nINSTANTLY                      : 'INSTANTLY';\nINSTEAD                        : 'INSTEAD';\nINSTR2                         : 'INSTR2';\nINSTR4                         : 'INSTR4';\nINSTRB                         : 'INSTRB';\nINSTRC                         : 'INSTRC';\nINSTR                          : 'INSTR';\nINTEGER                        : 'INTEGER';\nINTERLEAVED                    : 'INTERLEAVED';\nINTERMEDIATE                   : 'INTERMEDIATE';\nINTERNAL_CONVERT               : 'INTERNAL_CONVERT';\nINTERNAL_USE                   : 'INTERNAL_USE';\nINTERPRETED                    : 'INTERPRETED';\nINTERSECT                      : 'INTERSECT';\nINTERVAL                       : 'INTERVAL';\nINT                            : 'INT';\nINTERNAL                       : 'INTERNAL';\nINTO                           : 'INTO';\nINVALIDATE                     : 'INVALIDATE';\nINVALIDATION                   : 'INVALIDATION';\nINVISIBLE                      : 'INVISIBLE';\nIN_XQUERY                      : 'IN_XQUERY';\nIO_OPTIONS                     : 'IO_OPTIONS';\nIS                             : 'IS';\nIS_LEAF                        : 'IS_LEAF';\nISOLATION                      : 'ISOLATION';\nISOLATION_LEVEL                : 'ISOLATION_LEVEL';\nITEMS                          : 'ITEMS';\nITERATE                        : 'ITERATE';\nITERATION_NUMBER               : 'ITERATION_NUMBER';\nJAVA                           : 'JAVA';\nJOB                            : 'JOB';\nJOIN                           : 'JOIN';\nJSON_ARRAYAGG                  : 'JSON_ARRAYAGG';\nJSON_ARRAY                     : 'JSON_ARRAY';\nJSON_EQUAL                     : 'JSON_EQUAL';\nJSON_EXISTS2                   : 'JSON_EXISTS2';\nJSON_EXISTS                    : 'JSON_EXISTS';\nJSONGET                        : 'JSONGET';\nJSON                           : 'JSON';\nJSON_OBJECTAGG                 : 'JSON_OBJECTAGG';\nJSON_OBJECT                    : 'JSON_OBJECT';\nJSONPARSE                      : 'JSONPARSE';\nJSON_QUERY                     : 'JSON_QUERY';\nJSON_SERIALIZE                 : 'JSON_SERIALIZE';\nJSON_TABLE                     : 'JSON_TABLE';\nJSON_TEXTCONTAINS2             : 'JSON_TEXTCONTAINS2';\nJSON_TEXTCONTAINS              : 'JSON_TEXTCONTAINS';\nJSON_TRANSFORM                 : 'JSON_TRANSFORM';\nJSON_VALUE                     : 'JSON_VALUE';\nK_LETTER                       : 'K';\nKEEP_DUPLICATES                : 'KEEP_DUPLICATES';\nKEEP                           : 'KEEP';\nKERBEROS                       : 'KERBEROS';\nKEY                            : 'KEY';\nKEY_LENGTH                     : 'KEY_LENGTH';\nKEYSIZE                        : 'KEYSIZE';\nKEYS                           : 'KEYS';\nKEYSTORE                       : 'KEYSTORE';\nKILL                           : 'KILL';\nLABEL                          : 'LABEL';\nLANGUAGE                       : 'LANGUAGE';\nLAST_DAY                       : 'LAST_DAY';\nLAST                           : 'LAST';\nLAST_VALUE                     : 'LAST_VALUE';\nLATERAL                        : 'LATERAL';\nLATEST                         : 'LATEST';\nLAX                            : 'LAX';\nLAYER                          : 'LAYER';\nLDAP_REGISTRATION_ENABLED      : 'LDAP_REGISTRATION_ENABLED';\nLDAP_REGISTRATION              : 'LDAP_REGISTRATION';\nLDAP_REG_SYNC_INTERVAL         : 'LDAP_REG_SYNC_INTERVAL';\nLDRTRIM                        : 'LDRTRIM';\nLEAF                           : 'LEAF';\nLEAD_CDB                       : 'LEAD_CDB';\nLEAD_CDB_URI                   : 'LEAD_CDB_URI';\nLEADING                        : 'LEADING';\nLEFT                           : 'LEFT';\nLENGTH2                        : 'LENGTH2';\nLENGTH4                        : 'LENGTH4';\nLENGTHB                        : 'LENGTHB';\nLENGTHC                        : 'LENGTHC';\nLENGTH                         : 'LENGTH';\nLESS                           : 'LESS';\nLEVEL                          : 'LEVEL';\nLEVEL_NAME                     : 'LEVEL_NAME';\nLEVELS                         : 'LEVELS';\nLIBRARY                        : 'LIBRARY';\nLIFECYCLE                      : 'LIFECYCLE';\nLIFE                           : 'LIFE';\nLIFETIME                       : 'LIFETIME';\nLIKE2                          : 'LIKE2';\nLIKE4                          : 'LIKE4';\nLIKEC                          : 'LIKEC';\nLIKE_EXPAND                    : 'LIKE_EXPAND';\nLIKE                           : 'LIKE';\nLIMIT                          : 'LIMIT';\nLINEAR                         : 'LINEAR';\nLINES                          : 'LINES';\nLINK                           : 'LINK';\nLIST                           : 'LIST';\nLITTLE                         : 'LITTLE';\nLLS                            : 'LLS';\nLN                             : 'LN';\nLNNVL                          : 'LNNVL';\nLOAD                           : 'LOAD';\nLOB                            : 'LOB';\nLOBFILE                        : 'LOBFILE';\nLOBNVL                         : 'LOBNVL';\nLOBS                           : 'LOBS';\nLOCAL_INDEXES                  : 'LOCAL_INDEXES';\nLOCAL                          : 'LOCAL';\nLOCALTIME                      : 'LOCALTIME';\nLOCALTIMESTAMP                 : 'LOCALTIMESTAMP';\nLOCATION                       : 'LOCATION';\nLOCATOR                        : 'LOCATOR';\nLOCKDOWN                       : 'LOCKDOWN';\nLOCKED                         : 'LOCKED';\nLOCKING                        : 'LOCKING';\nLOCK                           : 'LOCK';\nLOGFILE                        : 'LOGFILE';\nLOGFILES                       : 'LOGFILES';\nLOGGING                        : 'LOGGING';\nLOGICAL                        : 'LOGICAL';\nLOGICAL_READS_PER_CALL         : 'LOGICAL_READS_PER_CALL';\nLOGICAL_READS_PER_SESSION      : 'LOGICAL_READS_PER_SESSION';\nLOG                            : 'LOG';\nLOGMINING                      : 'LOGMINING';\nLOGOFF                         : 'LOGOFF';\nLOGON                          : 'LOGON';\nLOG_READ_ONLY_VIOLATIONS       : 'LOG_READ_ONLY_VIOLATIONS';\nLONG                           : 'LONG';\nLOOP                           : 'LOOP';\nLOST                           : 'LOST';\nLOWER                          : 'LOWER';\nLOW                            : 'LOW';\nLPAD                           : 'LPAD';\nLRTRIM                         : 'LRTRIM';\nLTRIM                          : 'LTRIM';\nM_LETTER                       : 'M';\nMAIN                           : 'MAIN';\nMAKE_REF                       : 'MAKE_REF';\nMANAGED                        : 'MANAGED';\nMANAGE                         : 'MANAGE';\nMANAGEMENT                     : 'MANAGEMENT';\nMANAGER                        : 'MANAGER';\nMANDATORY                      : 'MANDATORY';\nMANUAL                         : 'MANUAL';\nMAP                            : 'MAP';\nMAPPING                        : 'MAPPING';\nMASK                           : 'MASK';\nMASTER                         : 'MASTER';\nMATCHED                        : 'MATCHED';\nMATCHES                        : 'MATCHES';\nMATCH                          : 'MATCH';\nMATCH_NUMBER                   : 'MATCH_NUMBER';\nMATCH_RECOGNIZE                : 'MATCH_RECOGNIZE';\nMATERIALIZED                   : 'MATERIALIZED';\nMATERIALIZE                    : 'MATERIALIZE';\nMAXARCHLOGS                    : 'MAXARCHLOGS';\nMAXDATAFILES                   : 'MAXDATAFILES';\nMAXEXTENTS                     : 'MAXEXTENTS';\nMAXIMIZE                       : 'MAXIMIZE';\nMAXINSTANCES                   : 'MAXINSTANCES';\nMAXLOGFILES                    : 'MAXLOGFILES';\nMAXLOGHISTORY                  : 'MAXLOGHISTORY';\nMAXLOGMEMBERS                  : 'MAXLOGMEMBERS';\nMAX_SHARED_TEMP_SIZE           : 'MAX_SHARED_TEMP_SIZE';\nMAXSIZE                        : 'MAXSIZE';\nMAXTRANS                       : 'MAXTRANS';\nMAXVALUE                       : 'MAXVALUE';\nMEASURE                        : 'MEASURE';\nMEASURES                       : 'MEASURES';\nMEDIUM                         : 'MEDIUM';\nMEMBER                         : 'MEMBER';\nMEMBER_CAPTION                 : 'MEMBER_CAPTION';\nMEMBER_DESCRIPTION             : 'MEMBER_DESCRIPTION';\nMEMBER_NAME                    : 'MEMBER_NAME';\nMEMBER_UNIQUE_NAME             : 'MEMBER_UNIQUE_NAME';\nMEMCOMPRESS                    : 'MEMCOMPRESS';\nMEMORY                         : 'MEMORY';\nMERGEACTIONS                   : 'MERGE$ACTIONS';\nMERGE_AJ                       : 'MERGE_AJ';\nMERGE_CONST_ON                 : 'MERGE_CONST_ON';\nMERGE                          : 'MERGE';\nMERGE_SJ                       : 'MERGE_SJ';\nMETADATA                       : 'METADATA';\nMETHOD                         : 'METHOD';\nMIGRATE                        : 'MIGRATE';\nMIGRATION                      : 'MIGRATION';\nMINEXTENTS                     : 'MINEXTENTS';\nMINIMIZE                       : 'MINIMIZE';\nMINIMUM                        : 'MINIMUM';\nMINING                         : 'MINING';\nMINUS                          : 'MINUS';\nMINUS_NULL                     : 'MINUS_NULL';\nMINUTE                         : 'MINUTE';\nMINUTES                        : 'MINUTES';\nMINVALUE                       : 'MINVALUE';\nMIRRORCOLD                     : 'MIRRORCOLD';\nMIRRORHOT                      : 'MIRRORHOT';\nMIRROR                         : 'MIRROR';\nMISSING                        : 'MISSING';\nMISMATCH                       : 'MISMATCH';\nMLSLABEL                       : 'MLSLABEL';\nMODEL_COMPILE_SUBQUERY         : 'MODEL_COMPILE_SUBQUERY';\nMODEL_DONTVERIFY_UNIQUENESS    : 'MODEL_DONTVERIFY_UNIQUENESS';\nMODEL_DYNAMIC_SUBQUERY         : 'MODEL_DYNAMIC_SUBQUERY';\nMODEL_MIN_ANALYSIS             : 'MODEL_MIN_ANALYSIS';\nMODEL                          : 'MODEL';\nMODEL_NB                       : 'MODEL_NB';\nMODEL_NO_ANALYSIS              : 'MODEL_NO_ANALYSIS';\nMODEL_PBY                      : 'MODEL_PBY';\nMODEL_PUSH_REF                 : 'MODEL_PUSH_REF';\nMODEL_SV                       : 'MODEL_SV';\nMODE                           : 'MODE';\nMODIFICATION                   : 'MODIFICATION';\nMODIFY_COLUMN_TYPE             : 'MODIFY_COLUMN_TYPE';\nMODIFY                         : 'MODIFY';\nMOD                            : 'MOD';\nMODULE                         : 'MODULE';\nMONITORING                     : 'MONITORING';\nMONITOR                        : 'MONITOR';\nMONTH                          : 'MONTH';\nMONTHS_BETWEEN                 : 'MONTHS_BETWEEN';\nMONTHS                         : 'MONTHS';\nMOUNT                          : 'MOUNT';\nMOUNTPATH                      : 'MOUNTPATH';\nMOUNTPOINT                     : 'MOUNTPOINT';\nMOVEMENT                       : 'MOVEMENT';\nMOVE                           : 'MOVE';\nMULTIDIMENSIONAL               : 'MULTIDIMENSIONAL';\nMULTISET                       : 'MULTISET';\nMV_MERGE                       : 'MV_MERGE';\nNAMED                          : 'NAMED';\nNAME                           : 'NAME';\nNAMESPACE                      : 'NAMESPACE';\nNAN_                            : 'NAN';\nNANVL                          : 'NANVL';\nNATIONAL                       : 'NATIONAL';\nNATIVE_FULL_OUTER_JOIN         : 'NATIVE_FULL_OUTER_JOIN';\nNATIVE                         : 'NATIVE';\nNATURAL                        : 'NATURAL';\nNATURALN                       : 'NATURALN';\nNAV                            : 'NAV';\nNCHAR_CS                       : 'NCHAR_CS';\nNCHAR                          : 'NCHAR';\nNCHR                           : 'NCHR';\nNCLOB                          : 'NCLOB';\nNEEDED                         : 'NEEDED';\nNEG                            : 'NEG';\nNESTED                         : 'NESTED';\nNESTED_TABLE_FAST_INSERT       : 'NESTED_TABLE_FAST_INSERT';\nNESTED_TABLE_GET_REFS          : 'NESTED_TABLE_GET_REFS';\nNESTED_TABLE_ID                : 'NESTED_TABLE_ID';\nNESTED_TABLE_SET_REFS          : 'NESTED_TABLE_SET_REFS';\nNESTED_TABLE_SET_SETID         : 'NESTED_TABLE_SET_SETID';\nNETWORK                        : 'NETWORK';\nNEVER                          : 'NEVER';\nNEW                            : 'NEW';\nNEWLINE_                       : 'NEWLINE';\nNEW_TIME                       : 'NEW_TIME';\nNEXT_DAY                       : 'NEXT_DAY';\nNEXT                           : 'NEXT';\nNL_AJ                          : 'NL_AJ';\nNLJ_BATCHING                   : 'NLJ_BATCHING';\nNLJ_INDEX_FILTER               : 'NLJ_INDEX_FILTER';\nNLJ_INDEX_SCAN                 : 'NLJ_INDEX_SCAN';\nNLJ_PREFETCH                   : 'NLJ_PREFETCH';\nNLS_CALENDAR                   : 'NLS_CALENDAR';\nNLS_CHARACTERSET               : 'NLS_CHARACTERSET';\nNLS_CHARSET_DECL_LEN           : 'NLS_CHARSET_DECL_LEN';\nNLS_CHARSET_ID                 : 'NLS_CHARSET_ID';\nNLS_CHARSET_NAME               : 'NLS_CHARSET_NAME';\nNLS_COMP                       : 'NLS_COMP';\nNLS_CURRENCY                   : 'NLS_CURRENCY';\nNLS_DATE_FORMAT                : 'NLS_DATE_FORMAT';\nNLS_DATE_LANGUAGE              : 'NLS_DATE_LANGUAGE';\nNLS_INITCAP                    : 'NLS_INITCAP';\nNLS_ISO_CURRENCY               : 'NLS_ISO_CURRENCY';\nNL_SJ                          : 'NL_SJ';\nNLS_LANG                       : 'NLS_LANG';\nNLS_LANGUAGE                   : 'NLS_LANGUAGE';\nNLS_LENGTH_SEMANTICS           : 'NLS_LENGTH_SEMANTICS';\nNLS_LOWER                      : 'NLS_LOWER';\nNLS_NCHAR_CONV_EXCP            : 'NLS_NCHAR_CONV_EXCP';\nNLS_NUMERIC_CHARACTERS         : 'NLS_NUMERIC_CHARACTERS';\nNLS_SORT                       : 'NLS_SORT';\nNLSSORT                        : 'NLSSORT';\nNLS_SPECIAL_CHARS              : 'NLS_SPECIAL_CHARS';\nNLS_TERRITORY                  : 'NLS_TERRITORY';\nNLS_UPPER                      : 'NLS_UPPER';\nNO_ACCESS                      : 'NO_ACCESS';\nNO_ADAPTIVE_PLAN               : 'NO_ADAPTIVE_PLAN';\nNO_ANSI_REARCH                 : 'NO_ANSI_REARCH';\nNOAPPEND                       : 'NOAPPEND';\nNOARCHIVELOG                   : 'NOARCHIVELOG';\nNOAUDIT                        : 'NOAUDIT';\nNOBADFILE                      : 'NOBADFILE';\nNO_AUTO_REOPTIMIZE             : 'NO_AUTO_REOPTIMIZE';\nNO_BASETABLE_MULTIMV_REWRITE   : 'NO_BASETABLE_MULTIMV_REWRITE';\nNO_BATCH_TABLE_ACCESS_BY_ROWID : 'NO_BATCH_TABLE_ACCESS_BY_ROWID';\nNO_BIND_AWARE                  : 'NO_BIND_AWARE';\nNO_BUFFER                      : 'NO_BUFFER';\nNOCACHE                        : 'NOCACHE';\nNOCHECK                        : 'NOCHECK';\nNO_CARTESIAN                   : 'NO_CARTESIAN';\nNO_CHECK_ACL_REWRITE           : 'NO_CHECK_ACL_REWRITE';\nNO_CLUSTER_BY_ROWID            : 'NO_CLUSTER_BY_ROWID';\nNO_CLUSTERING                  : 'NO_CLUSTERING';\nNO_COALESCE_SQ                 : 'NO_COALESCE_SQ';\nNO_COMMON_DATA                 : 'NO_COMMON_DATA';\nNOCOMPRESS                     : 'NOCOMPRESS';\nNO_CONNECT_BY_CB_WHR_ONLY      : 'NO_CONNECT_BY_CB_WHR_ONLY';\nNO_CONNECT_BY_COMBINE_SW       : 'NO_CONNECT_BY_COMBINE_SW';\nNO_CONNECT_BY_COST_BASED       : 'NO_CONNECT_BY_COST_BASED';\nNO_CONNECT_BY_ELIM_DUPS        : 'NO_CONNECT_BY_ELIM_DUPS';\nNO_CONNECT_BY_FILTERING        : 'NO_CONNECT_BY_FILTERING';\nNOCOPY                         : 'NOCOPY';\nNO_COST_XML_QUERY_REWRITE      : 'NO_COST_XML_QUERY_REWRITE';\nNO_CPU_COSTING                 : 'NO_CPU_COSTING';\nNOCPU_COSTING                  : 'NOCPU_COSTING';\nNOCYCLE                        : 'NOCYCLE';\nNO_DATA_SECURITY_REWRITE       : 'NO_DATA_SECURITY_REWRITE';\nNO_DECORRELATE                 : 'NO_DECORRELATE';\nNODELAY                        : 'NODELAY';\nNODIRECTIO                     : 'NODIRECTIO';\nNODISCARDFILE                  : 'NODISCARDFILE';\nNO_DOMAIN_INDEX_FILTER         : 'NO_DOMAIN_INDEX_FILTER';\nNO_DST_UPGRADE_INSERT_CONV     : 'NO_DST_UPGRADE_INSERT_CONV';\nNO_ELIM_GROUPBY                : 'NO_ELIM_GROUPBY';\nNO_ELIMINATE_JOIN              : 'NO_ELIMINATE_JOIN';\nNO_ELIMINATE_OBY               : 'NO_ELIMINATE_OBY';\nNO_ELIMINATE_OUTER_JOIN        : 'NO_ELIMINATE_OUTER_JOIN';\nNOENTITYESCAPING               : 'NOENTITYESCAPING';\nNO_EXPAND_GSET_TO_UNION        : 'NO_EXPAND_GSET_TO_UNION';\nNO_EXPAND                      : 'NO_EXPAND';\nNO_EXPAND_TABLE                : 'NO_EXPAND_TABLE';\nNOEXTEND                       : 'NOEXTEND';\nNO_FACT                        : 'NO_FACT';\nNO_FACTORIZE_JOIN              : 'NO_FACTORIZE_JOIN';\nNO_FILTERING                   : 'NO_FILTERING';\nNOFORCE                        : 'NOFORCE';\nNO_FULL_OUTER_JOIN_TO_OUTER    : 'NO_FULL_OUTER_JOIN_TO_OUTER';\nNO_GATHER_OPTIMIZER_STATISTICS : 'NO_GATHER_OPTIMIZER_STATISTICS';\nNO_GBY_PUSHDOWN                : 'NO_GBY_PUSHDOWN';\nNOGUARANTEE                    : 'NOGUARANTEE';\nNO_INDEX_FFS                   : 'NO_INDEX_FFS';\nNO_INDEX                       : 'NO_INDEX';\nNO_INDEX_SS                    : 'NO_INDEX_SS';\nNO_INMEMORY                    : 'NO_INMEMORY';\nNO_INMEMORY_PRUNING            : 'NO_INMEMORY_PRUNING';\nNOKEEP                         : 'NOKEEP';\nNO_LOAD                        : 'NO_LOAD';\nNOLOCAL                        : 'NOLOCAL';\nNOLOG                          : 'NOLOG';\nNOLOGFILE                      : 'NOLOGFILE';\nNOLOGGING                      : 'NOLOGGING';\nNOMAPPING                      : 'NOMAPPING';\nNOMAXVALUE                     : 'NOMAXVALUE';\nNO_MERGE                       : 'NO_MERGE';\nNOMINIMIZE                     : 'NOMINIMIZE';\nNOMINVALUE                     : 'NOMINVALUE';\nNO_MODEL_PUSH_REF              : 'NO_MODEL_PUSH_REF';\nNO_MONITORING                  : 'NO_MONITORING';\nNOMONITORING                   : 'NOMONITORING';\nNO_MONITOR                     : 'NO_MONITOR';\nNO_MULTIMV_REWRITE             : 'NO_MULTIMV_REWRITE';\nNO_NATIVE_FULL_OUTER_JOIN      : 'NO_NATIVE_FULL_OUTER_JOIN';\nNONBLOCKING                    : 'NONBLOCKING';\nNONEDITIONABLE                 : 'NONEDITIONABLE';\nNONE                           : 'NONE';\nNONULLIF                       : 'NONULLIF';\nNO_NLJ_BATCHING                : 'NO_NLJ_BATCHING';\nNO_NLJ_PREFETCH                : 'NO_NLJ_PREFETCH';\nNO                             : 'NO';\nNONSCHEMA                      : 'NONSCHEMA';\nNO_OBJECT_LINK                 : 'NO_OBJECT_LINK';\nNOORDER                        : 'NOORDER';\nNO_ORDER_ROLLUPS               : 'NO_ORDER_ROLLUPS';\nNO_OUTER_JOIN_TO_ANTI          : 'NO_OUTER_JOIN_TO_ANTI';\nNO_OUTER_JOIN_TO_INNER         : 'NO_OUTER_JOIN_TO_INNER';\nNOOVERRIDE                     : 'NOOVERRIDE';\nNO_PARALLEL_INDEX              : 'NO_PARALLEL_INDEX';\nNOPARALLEL_INDEX               : 'NOPARALLEL_INDEX';\nNO_PARALLEL                    : 'NO_PARALLEL';\nNOPARALLEL                     : 'NOPARALLEL';\nNO_PARTIAL_COMMIT              : 'NO_PARTIAL_COMMIT';\nNO_PARTIAL_JOIN                : 'NO_PARTIAL_JOIN';\nNO_PARTIAL_ROLLUP_PUSHDOWN     : 'NO_PARTIAL_ROLLUP_PUSHDOWN';\nNOPARTITION                    : 'NOPARTITION';\nNO_PLACE_DISTINCT              : 'NO_PLACE_DISTINCT';\nNO_PLACE_GROUP_BY              : 'NO_PLACE_GROUP_BY';\nNO_PQ_CONCURRENT_UNION         : 'NO_PQ_CONCURRENT_UNION';\nNO_PQ_MAP                      : 'NO_PQ_MAP';\nNOPROMPT                       : 'NOPROMPT';\nNO_PQ_REPLICATE                : 'NO_PQ_REPLICATE';\nNO_PQ_SKEW                     : 'NO_PQ_SKEW';\nNO_PRUNE_GSETS                 : 'NO_PRUNE_GSETS';\nNO_PULL_PRED                   : 'NO_PULL_PRED';\nNO_PUSH_PRED                   : 'NO_PUSH_PRED';\nNO_PUSH_SUBQ                   : 'NO_PUSH_SUBQ';\nNO_PX_FAULT_TOLERANCE          : 'NO_PX_FAULT_TOLERANCE';\nNO_PX_JOIN_FILTER              : 'NO_PX_JOIN_FILTER';\nNO_QKN_BUFF                    : 'NO_QKN_BUFF';\nNO_QUERY_TRANSFORMATION        : 'NO_QUERY_TRANSFORMATION';\nNO_REF_CASCADE                 : 'NO_REF_CASCADE';\nNORELOCATE                     : 'NORELOCATE';\nNORELY                         : 'NORELY';\nNOREPAIR                       : 'NOREPAIR';\nNOREPLAY                       : 'NOREPLAY';\nNORESETLOGS                    : 'NORESETLOGS';\nNO_RESULT_CACHE                : 'NO_RESULT_CACHE';\nNOREVERSE                      : 'NOREVERSE';\nNO_REWRITE                     : 'NO_REWRITE';\nNOREWRITE                      : 'NOREWRITE';\nNORMAL                         : 'NORMAL';\nNO_ROOT_SW_FOR_LOCAL           : 'NO_ROOT_SW_FOR_LOCAL';\nNOROWDEPENDENCIES              : 'NOROWDEPENDENCIES';\nNOSCALE                        : 'NOSCALE';\nNOSCHEMACHECK                  : 'NOSCHEMACHECK';\nNOSEGMENT                      : 'NOSEGMENT';\nNO_SEMIJOIN                    : 'NO_SEMIJOIN';\nNO_SEMI_TO_INNER               : 'NO_SEMI_TO_INNER';\nNO_SET_TO_JOIN                 : 'NO_SET_TO_JOIN';\nNOSHARD                        : 'NOSHARD';\nNOSORT                         : 'NOSORT';\nNO_SQL_TRANSLATION             : 'NO_SQL_TRANSLATION';\nNO_SQL_TUNE                    : 'NO_SQL_TUNE';\nNO_STAR_TRANSFORMATION         : 'NO_STAR_TRANSFORMATION';\nNO_STATEMENT_QUEUING           : 'NO_STATEMENT_QUEUING';\nNO_STATS_GSETS                 : 'NO_STATS_GSETS';\nNOSTRICT                       : 'NOSTRICT';\nNO_SUBQUERY_PRUNING            : 'NO_SUBQUERY_PRUNING';\nNO_SUBSTRB_PAD                 : 'NO_SUBSTRB_PAD';\nNO_SWAP_JOIN_INPUTS            : 'NO_SWAP_JOIN_INPUTS';\nNOSWITCH                       : 'NOSWITCH';\nNO_TABLE_LOOKUP_BY_NL          : 'NO_TABLE_LOOKUP_BY_NL';\nNO_TEMP_TABLE                  : 'NO_TEMP_TABLE';\nNOTHING                        : 'NOTHING';\nNOTIFICATION                   : 'NOTIFICATION';\nNOTRIM                         : 'NOTRIM';\nNOT                            : 'NOT';\nNO_TRANSFORM_DISTINCT_AGG      : 'NO_TRANSFORM_DISTINCT_AGG';\nNO_UNNEST                      : 'NO_UNNEST';\nNO_USE_CUBE                    : 'NO_USE_CUBE';\nNO_USE_HASH_AGGREGATION        : 'NO_USE_HASH_AGGREGATION';\nNO_USE_HASH_GBY_FOR_PUSHDOWN   : 'NO_USE_HASH_GBY_FOR_PUSHDOWN';\nNO_USE_HASH                    : 'NO_USE_HASH';\nNO_USE_INVISIBLE_INDEXES       : 'NO_USE_INVISIBLE_INDEXES';\nNO_USE_MERGE                   : 'NO_USE_MERGE';\nNO_USE_NL                      : 'NO_USE_NL';\nNO_USE_VECTOR_AGGREGATION      : 'NO_USE_VECTOR_AGGREGATION';\nNOVALIDATE                     : 'NOVALIDATE';\nNO_VECTOR_TRANSFORM_DIMS       : 'NO_VECTOR_TRANSFORM_DIMS';\nNO_VECTOR_TRANSFORM_FACT       : 'NO_VECTOR_TRANSFORM_FACT';\nNO_VECTOR_TRANSFORM            : 'NO_VECTOR_TRANSFORM';\nNOWAIT                         : 'NOWAIT';\nNO_XDB_FASTPATH_INSERT         : 'NO_XDB_FASTPATH_INSERT';\nNO_XML_DML_REWRITE             : 'NO_XML_DML_REWRITE';\nNO_XMLINDEX_REWRITE_IN_SELECT  : 'NO_XMLINDEX_REWRITE_IN_SELECT';\nNO_XMLINDEX_REWRITE            : 'NO_XMLINDEX_REWRITE';\nNO_XML_QUERY_REWRITE           : 'NO_XML_QUERY_REWRITE';\nNO_ZONEMAP                     : 'NO_ZONEMAP';\nNTH_VALUE                      : 'NTH_VALUE';\nNULLIF                         : 'NULLIF';\nNULL_                          : 'NULL';\nNULLS                          : 'NULLS';\nNUMBER                         : 'NUMBER';\nNUMERIC                        : 'NUMERIC';\nNUM_INDEX_KEYS                 : 'NUM_INDEX_KEYS';\nNUMTODSINTERVAL                : 'NUMTODSINTERVAL';\nNUMTOYMINTERVAL                : 'NUMTOYMINTERVAL';\nNVARCHAR2                      : 'NVARCHAR2';\nNVL2                           : 'NVL2';\nOBJECT2XML                     : 'OBJECT2XML';\nOBJECT                         : 'OBJECT';\nOBJ_ID                         : 'OBJ_ID';\nOBJNO                          : 'OBJNO';\nOBJNO_REUSE                    : 'OBJNO_REUSE';\nOCCURENCES                     : 'OCCURENCES';\nOFFLINE                        : 'OFFLINE';\nOFF                            : 'OFF';\nOFFSET                         : 'OFFSET';\nOF                             : 'OF';\nOIDINDEX                       : 'OIDINDEX';\nOID                            : 'OID';\nOLAP                           : 'OLAP';\nOLD                            : 'OLD';\nOLD_PUSH_PRED                  : 'OLD_PUSH_PRED';\nOLS                            : 'OLS';\nOLTP                           : 'OLTP';\nOMIT                           : 'OMIT';\nONE                            : 'ONE';\nONLINE                         : 'ONLINE';\nONLINELOG                      : 'ONLINELOG';\nONLY                           : 'ONLY';\nON                             : 'ON';\nOPAQUE                         : 'OPAQUE';\nOPAQUE_TRANSFORM               : 'OPAQUE_TRANSFORM';\nOPAQUE_XCANONICAL              : 'OPAQUE_XCANONICAL';\nOPCODE                         : 'OPCODE';\nOPEN                           : 'OPEN';\nOPERATIONS                     : 'OPERATIONS';\nOPERATOR                       : 'OPERATOR';\nOPT_ESTIMATE                   : 'OPT_ESTIMATE';\nOPTIMAL                        : 'OPTIMAL';\nOPTIMIZE                       : 'OPTIMIZE';\nOPTIMIZER_FEATURES_ENABLE      : 'OPTIMIZER_FEATURES_ENABLE';\nOPTIMIZER_GOAL                 : 'OPTIMIZER_GOAL';\nOPTION                         : 'OPTION';\nOPTIONALLY                     : 'OPTIONALLY';\nOPT_PARAM                      : 'OPT_PARAM';\nORA_BRANCH                     : 'ORA_BRANCH';\nORA_CHECK_ACL                  : 'ORA_CHECK_ACL';\nORA_CHECK_PRIVILEGE            : 'ORA_CHECK_PRIVILEGE';\nORA_CLUSTERING                 : 'ORA_CLUSTERING';\nORADATA                        : 'ORADATA';\nORC                            : 'ORC';\nORACLE_DATE                    : 'ORACLE_DATE';\nORACLE_NUMBER                  : 'ORACLE_NUMBER';\nORADEBUG                       : 'ORADEBUG';\nORA_DST_AFFECTED               : 'ORA_DST_AFFECTED';\nORA_DST_CONVERT                : 'ORA_DST_CONVERT';\nORA_DST_ERROR                  : 'ORA_DST_ERROR';\nORA_GET_ACLIDS                 : 'ORA_GET_ACLIDS';\nORA_GET_PRIVILEGES             : 'ORA_GET_PRIVILEGES';\nORA_HASH                       : 'ORA_HASH';\nORA_INVOKING_USERID            : 'ORA_INVOKING_USERID';\nORA_INVOKING_USER              : 'ORA_INVOKING_USER';\nORA_INVOKING_XS_USER_GUID      : 'ORA_INVOKING_XS_USER_GUID';\nORA_INVOKING_XS_USER           : 'ORA_INVOKING_XS_USER';\nORA_RAWCOMPARE                 : 'ORA_RAWCOMPARE';\nORA_RAWCONCAT                  : 'ORA_RAWCONCAT';\nORA_ROWSCN                     : 'ORA_ROWSCN';\nORA_ROWSCN_RAW                 : 'ORA_ROWSCN_RAW';\nORA_ROWVERSION                 : 'ORA_ROWVERSION';\nORA_TABVERSION                 : 'ORA_TABVERSION';\nORA_WRITE_TIME                 : 'ORA_WRITE_TIME';\nORDERED                        : 'ORDERED';\nORDERED_PREDICATES             : 'ORDERED_PREDICATES';\nORDER                          : 'ORDER';\nORDINALITY                     : 'ORDINALITY';\nOR_EXPAND                      : 'OR_EXPAND';\nORGANIZATION                   : 'ORGANIZATION';\nOR                             : 'OR';\nOR_PREDICATES                  : 'OR_PREDICATES';\nOSERROR                        : 'OSERROR';\nOTHER                          : 'OTHER';\nOUTER_JOIN_TO_ANTI             : 'OUTER_JOIN_TO_ANTI';\nOUTER_JOIN_TO_INNER            : 'OUTER_JOIN_TO_INNER';\nOUTER                          : 'OUTER';\nOUTLINE_LEAF                   : 'OUTLINE_LEAF';\nOUTLINE                        : 'OUTLINE';\nOUTPUTFORMAT                   : 'OUTPUTFORMAT';\nOUT_OF_LINE                    : 'OUT_OF_LINE';\nOUT                            : 'OUT';\nOVERFLOW_NOMOVE                : 'OVERFLOW_NOMOVE';\nOVERFLOW_                      : 'OVERFLOW';\nOVERLAPS                       : 'OVERLAPS';\nOVER                           : 'OVER';\nOVERRIDE                       : 'OVERRIDE';\nOVERRIDING                     : 'OVERRIDING';\nOWNER                          : 'OWNER';\nOWNERSHIP                      : 'OWNERSHIP';\nOWN                            : 'OWN';\nP_LETTER                       : 'P';\nPACKAGE                        : 'PACKAGE';\nPACKAGES                       : 'PACKAGES';\nPARALLEL_ENABLE                : 'PARALLEL_ENABLE';\nPARALLEL_INDEX                 : 'PARALLEL_INDEX';\nPARALLEL                       : 'PARALLEL';\nPARAMETERFILE                  : 'PARAMETERFILE';\nPARAMETERS                     : 'PARAMETERS';\nPARAM                          : 'PARAM';\nPARENT                         : 'PARENT';\nPARENT_LEVEL_NAME              : 'PARENT_LEVEL_NAME';\nPARENT_UNIQUE_NAME             : 'PARENT_UNIQUE_NAME';\nPARITY                         : 'PARITY';\nPARQUET                        : 'PARQUET';\nPARTIAL_JOIN                   : 'PARTIAL_JOIN';\nPARTIALLY                      : 'PARTIALLY';\nPARTIAL                        : 'PARTIAL';\nPARTIAL_ROLLUP_PUSHDOWN        : 'PARTIAL_ROLLUP_PUSHDOWN';\nPARTITION_HASH                 : 'PARTITION_HASH';\nPARTITION_LIST                 : 'PARTITION_LIST';\nPARTITION                      : 'PARTITION';\nPARTITION_RANGE                : 'PARTITION_RANGE';\nPARTITIONS                     : 'PARTITIONS';\nPARTNUMINST                    : 'PART$NUM$INST';\nPASSING                        : 'PASSING';\nPASSWORD_GRACE_TIME            : 'PASSWORD_GRACE_TIME';\nPASSWORD_LIFE_TIME             : 'PASSWORD_LIFE_TIME';\nPASSWORD_LOCK_TIME             : 'PASSWORD_LOCK_TIME';\nPASSWORD                       : 'PASSWORD';\nPASSWORD_REUSE_MAX             : 'PASSWORD_REUSE_MAX';\nPASSWORD_REUSE_TIME            : 'PASSWORD_REUSE_TIME';\nPASSWORD_ROLLOVER_TIME         : 'PASSWORD_ROLLOVER_TIME';\nPASSWORD_VERIFY_FUNCTION       : 'PASSWORD_VERIFY_FUNCTION';\nPAST                           : 'PAST';\nPATCH                          : 'PATCH';\nPATH                           : 'PATH';\nPATH_PREFIX                    : 'PATH_PREFIX';\nPATHS                          : 'PATHS';\nPATTERN                        : 'PATTERN';\nPBL_HS_BEGIN                   : 'PBL_HS_BEGIN';\nPBL_HS_END                     : 'PBL_HS_END';\nPCTFREE                        : 'PCTFREE';\nPCTINCREASE                    : 'PCTINCREASE';\nPCTTHRESHOLD                   : 'PCTTHRESHOLD';\nPCTUSED                        : 'PCTUSED';\nPCTVERSION                     : 'PCTVERSION';\nPENDING                        : 'PENDING';\nPERCENT_FOUND                  : '%' SPACE* 'FOUND';\nPERCENT_ISOPEN                 : '%' SPACE* 'ISOPEN';\nPERCENT_NOTFOUND               : '%' SPACE* 'NOTFOUND';\nPERCENT_KEYWORD                : 'PERCENT';\nPERCENT_RANKM                  : 'PERCENT_RANKM';\nPERCENT_ROWCOUNT               : '%' SPACE* 'ROWCOUNT';\nPERCENT_ROWTYPE                : '%' SPACE* 'ROWTYPE';\nPERCENT_TYPE                   : '%' SPACE* 'TYPE';\nPERCENT_BULK_EXCEPTIONS        : '%' SPACE* 'BULK_EXCEPTIONS';\nPERCENT_BULK_ROWCOUNT          : '%' SPACE* 'BULK_ROWCOUNT';\nPERFORMANCE                    : 'PERFORMANCE';\nPERIOD_KEYWORD                 : 'PERIOD';\nPERMANENT                      : 'PERMANENT';\nPERMISSION                     : 'PERMISSION';\nPERMUTE                        : 'PERMUTE';\nPER                            : 'PER';\nPFILE                          : 'PFILE';\nPHYSICAL                       : 'PHYSICAL';\nPIKEY                          : 'PIKEY';\nPIPELINED                      : 'PIPELINED';\nPIPE                           : 'PIPE';\nPIV_GB                         : 'PIV_GB';\nPIVOT                          : 'PIVOT';\nPIV_SSF                        : 'PIV_SSF';\nPLACE_DISTINCT                 : 'PLACE_DISTINCT';\nPLACE_GROUP_BY                 : 'PLACE_GROUP_BY';\nPLAN                           : 'PLAN';\nPLSCOPE_SETTINGS               : 'PLSCOPE_SETTINGS';\nPLS_INTEGER                    : 'PLS_INTEGER';\nPLSQL_CCFLAGS                  : 'PLSQL_CCFLAGS';\nPLSQL_CODE_TYPE                : 'PLSQL_CODE_TYPE';\nPLSQL_DEBUG                    : 'PLSQL_DEBUG';\nPLSQL_OPTIMIZE_LEVEL           : 'PLSQL_OPTIMIZE_LEVEL';\nPLSQL_WARNINGS                 : 'PLSQL_WARNINGS';\nPLUGGABLE                      : 'PLUGGABLE';\nPMEM                           : 'PMEM';\nPOINT                          : 'POINT';\nPOLICY                         : 'POLICY';\nPOOL_16K                       : 'POOL_16K';\nPOOL_2K                        : 'POOL_2K';\nPOOL_32K                       : 'POOL_32K';\nPOOL_4K                        : 'POOL_4K';\nPOOL_8K                        : 'POOL_8K';\nPOSITION                       : 'POSITION';\nPOSITIVEN                      : 'POSITIVEN';\nPOSITIVE                       : 'POSITIVE';\nPOST_TRANSACTION               : 'POST_TRANSACTION';\nPOWERMULTISET_BY_CARDINALITY   : 'POWERMULTISET_BY_CARDINALITY';\nPOWERMULTISET                  : 'POWERMULTISET';\nPOWER                          : 'POWER';\nPQ_CONCURRENT_UNION            : 'PQ_CONCURRENT_UNION';\nPQ_DISTRIBUTE                  : 'PQ_DISTRIBUTE';\nPQ_DISTRIBUTE_WINDOW           : 'PQ_DISTRIBUTE_WINDOW';\nPQ_FILTER                      : 'PQ_FILTER';\nPQ_MAP                         : 'PQ_MAP';\nPQ_NOMAP                       : 'PQ_NOMAP';\nPQ_REPLICATE                   : 'PQ_REPLICATE';\nPQ_SKEW                        : 'PQ_SKEW';\nPRAGMA                         : 'PRAGMA';\nPREBUILT                       : 'PREBUILT';\nPRECEDES                       : 'PRECEDES';\nPRECEDING                      : 'PRECEDING';\nPRECISION                      : 'PRECISION';\nPRECOMPUTE_SUBQUERY            : 'PRECOMPUTE_SUBQUERY';\nPREDICATE_REORDERS             : 'PREDICATE_REORDERS';\nPRELOAD                        : 'PRELOAD';\nPREPARE                        : 'PREPARE';\nPREPROCESSOR                   : 'PREPROCESSOR';\nPRESENTNNV                     : 'PRESENTNNV';\nPRESENT                        : 'PRESENT';\nPRESENTV                       : 'PRESENTV';\nPRESERVE_OID                   : 'PRESERVE_OID';\nPRESERVE                       : 'PRESERVE';\nPRETTY                         : 'PRETTY';\nPREVIOUS                       : 'PREVIOUS';\nPREV                           : 'PREV';\nPRIMARY                        : 'PRIMARY';\nPRINTBLOBTOCLOB                : 'PRINTBLOBTOCLOB';\nPRIORITY                       : 'PRIORITY';\nPRIOR                          : 'PRIOR';\nPRIVATE                        : 'PRIVATE';\nPRIVATE_SGA                    : 'PRIVATE_SGA';\nPRIVILEGED                     : 'PRIVILEGED';\nPRIVILEGE                      : 'PRIVILEGE';\nPRIVILEGES                     : 'PRIVILEGES';\nPROCEDURAL                     : 'PROCEDURAL';\nPROCEDURE                      : 'PROCEDURE';\nPROCESS                        : 'PROCESS';\nPROFILE                        : 'PROFILE';\nPROGRAM                        : 'PROGRAM';\nPROJECT                        : 'PROJECT';\nPROPAGATE                      : 'PROPAGATE';\nPROPERTY                       : 'PROPERTY';\nPROTECTED                      : 'PROTECTED';\nPROTECTION                     : 'PROTECTION';\nPROTOCOL                       : 'PROTOCOL';\nPROXY                          : 'PROXY';\nPRUNING                        : 'PRUNING';\nPUBLIC                         : 'PUBLIC';\nPULL_PRED                      : 'PULL_PRED';\nPURGE                          : 'PURGE';\nPUSH_PRED                      : 'PUSH_PRED';\nPUSH_SUBQ                      : 'PUSH_SUBQ';\nPX_FAULT_TOLERANCE             : 'PX_FAULT_TOLERANCE';\nPX_GRANULE                     : 'PX_GRANULE';\nPX_JOIN_FILTER                 : 'PX_JOIN_FILTER';\nQB_NAME                        : 'QB_NAME';\nQUARTERS                       : 'QUARTERS';\nQUERY_BLOCK                    : 'QUERY_BLOCK';\nQUERY                          : 'QUERY';\nQUEUE_CURR                     : 'QUEUE_CURR';\nQUEUE                          : 'QUEUE';\nQUEUE_ROWP                     : 'QUEUE_ROWP';\nQUIESCE                        : 'QUIESCE';\nQUORUM                         : 'QUORUM';\nQUOTA                          : 'QUOTA';\nQUOTAGROUP                     : 'QUOTAGROUP';\nRAISE                          : 'RAISE';\nRANDOM_LOCAL                   : 'RANDOM_LOCAL';\nRANDOM                         : 'RANDOM';\nRANGE                          : 'RANGE';\nRANKM                          : 'RANKM';\nRAPIDLY                        : 'RAPIDLY';\nRAW                            : 'RAW';\nRAWTOHEX                       : 'RAWTOHEX';\nRAWTONHEX                      : 'RAWTONHEX';\nRBA                            : 'RBA';\nRBO_OUTLINE                    : 'RBO_OUTLINE';\nRCFILE                         : 'RCFILE';\nRDBA                           : 'RDBA';\nREAD                           : 'READ';\nREADS                          : 'READS';\nREADSIZE                       : 'READSIZE';\nREALM                          : 'REALM';\nREAL                           : 'REAL';\nREBALANCE                      : 'REBALANCE';\nREBUILD                        : 'REBUILD';\nRECORD                         : 'RECORD';\nRECORDS                        : 'RECORDS';\nRECORDS_PER_BLOCK              : 'RECORDS_PER_BLOCK';\nRECOVERABLE                    : 'RECOVERABLE';\nRECOVER                        : 'RECOVER';\nRECOVERY                       : 'RECOVERY';\nRECYCLEBIN                     : 'RECYCLEBIN';\nRECYCLE                        : 'RECYCLE';\nREDACTION                      : 'REDACTION';\nREDEFINE                       : 'REDEFINE';\nREDO                           : 'REDO';\nREDUCED                        : 'REDUCED';\nREDUNDANCY                     : 'REDUNDANCY';\nREF_CASCADE_CURSOR             : 'REF_CASCADE_CURSOR';\nREFERENCED                     : 'REFERENCED';\nREFERENCE                      : 'REFERENCE';\nREFERENCES                     : 'REFERENCES';\nREFERENCING                    : 'REFERENCING';\nREF                            : 'REF';\nREFRESH                        : 'REFRESH';\nREFTOHEX                       : 'REFTOHEX';\nREGEXP_COUNT                   : 'REGEXP_COUNT';\nREGEXP_INSTR                   : 'REGEXP_INSTR';\nREGEXP_LIKE                    : 'REGEXP_LIKE';\nREGEXP_REPLACE                 : 'REGEXP_REPLACE';\nREGEXP_SUBSTR                  : 'REGEXP_SUBSTR';\nREGISTER                       : 'REGISTER';\nREGR_AVGX                      : 'REGR_AVGX';\nREGR_AVGY                      : 'REGR_AVGY';\nREGR_COUNT                     : 'REGR_COUNT';\nREGR_INTERCEPT                 : 'REGR_INTERCEPT';\nREGR_R2                        : 'REGR_R2';\nREGR_SLOPE                     : 'REGR_SLOPE';\nREGR_SXX                       : 'REGR_SXX';\nREGR_SXY                       : 'REGR_SXY';\nREGR_SYY                       : 'REGR_SYY';\nREGULAR                        : 'REGULAR';\nREJECT                         : 'REJECT';\nREKEY                          : 'REKEY';\nRELATIONAL                     : 'RELATIONAL';\nRELIES_ON                      : 'RELIES_ON';\nRELOCATE                       : 'RELOCATE';\nRELY                           : 'RELY';\nREMAINDER                      : 'REMAINDER';\nREMOTE                         : 'REMOTE';\nREMOTE_MAPPED                  : 'REMOTE_MAPPED';\nREMOVE                         : 'REMOVE';\nRENAME                         : 'RENAME';\nREPAIR                         : 'REPAIR';\nREPEAT                         : 'REPEAT';\nREPLACE                        : 'REPLACE';\nREPLICATION                    : 'REPLICATION';\nREQUIRED                       : 'REQUIRED';\nRESETLOGS                      : 'RESETLOGS';\nRESET                          : 'RESET';\nRESIZE                         : 'RESIZE';\nRESOLVE                        : 'RESOLVE';\nRESOLVER                       : 'RESOLVER';\nRESOURCE                       : 'RESOURCE';\nRESPECT                        : 'RESPECT';\nRESTART                        : 'RESTART';\nRESTORE_AS_INTERVALS           : 'RESTORE_AS_INTERVALS';\nRESTORE                        : 'RESTORE';\nRESTRICT_ALL_REF_CONS          : 'RESTRICT_ALL_REF_CONS';\nRESTRICTED                     : 'RESTRICTED';\nRESTRICT_REFERENCES            : 'RESTRICT_REFERENCES';\nRESTRICT                       : 'RESTRICT';\nRESULT_CACHE                   : 'RESULT_CACHE';\nRESULT                         : 'RESULT';\nRESUMABLE                      : 'RESUMABLE';\nRESUME                         : 'RESUME';\nRETENTION                      : 'RETENTION';\nRETRY_ON_ROW_CHANGE            : 'RETRY_ON_ROW_CHANGE';\nRETURNING                      : 'RETURNING';\nRETURN                         : 'RETURN';\nREUSE                          : 'REUSE';\nREVERSE                        : 'REVERSE';\nREVOKE                         : 'REVOKE';\nREWRITE_OR_ERROR               : 'REWRITE_OR_ERROR';\nREWRITE                        : 'REWRITE';\nRIGHT                          : 'RIGHT';\nROLE                           : 'ROLE';\nROLESET                        : 'ROLESET';\nROLES                          : 'ROLES';\nROLLBACK                       : 'ROLLBACK';\nROLLING                        : 'ROLLING';\nROLLUP                         : 'ROLLUP';\nROWDEPENDENCIES                : 'ROWDEPENDENCIES';\nROWID_MAPPING_TABLE            : 'ROWID_MAPPING_TABLE';\nROWID                          : 'ROWID';\nROWIDTOCHAR                    : 'ROWIDTOCHAR';\nROWIDTONCHAR                   : 'ROWIDTONCHAR';\nROW_LENGTH                     : 'ROW_LENGTH';\nROWNUM                         : 'ROWNUM';\nROW                            : 'ROW';\nROWS                           : 'ROWS';\nRPAD                           : 'RPAD';\nRTRIM                          : 'RTRIM';\nRULE                           : 'RULE';\nRULES                          : 'RULES';\nRUNNING                        : 'RUNNING';\nSALT                           : 'SALT';\nSAMPLE                         : 'SAMPLE';\nSAVE_AS_INTERVALS              : 'SAVE_AS_INTERVALS';\nSAVEPOINT                      : 'SAVEPOINT';\nSAVE                           : 'SAVE';\nSB4                            : 'SB4';\nSCALE_ROWS                     : 'SCALE_ROWS';\nSCALE                          : 'SCALE';\nSCAN_INSTANCES                 : 'SCAN_INSTANCES';\nSCAN                           : 'SCAN';\nSCHEDULER                      : 'SCHEDULER';\nSCHEMACHECK                    : 'SCHEMACHECK';\nSCHEMA                         : 'SCHEMA';\nSCN_ASCENDING                  : 'SCN_ASCENDING';\nSCN                            : 'SCN';\nSCOPE                          : 'SCOPE';\nSCRUB                          : 'SCRUB';\nSD_ALL                         : 'SD_ALL';\nSD_INHIBIT                     : 'SD_INHIBIT';\nSDO_GEOM_MBR                   : 'SDO_GEOM_MBR';\nSDO_GEOMETRY                   : 'SDO_GEOMETRY';\nSD_SHOW                        : 'SD_SHOW';\nSEARCH                         : 'SEARCH';\nSECOND                         : 'SECOND';\nSECONDS                        : 'SECONDS';\nSECRET                         : 'SECRET';\nSECUREFILE_DBA                 : 'SECUREFILE_DBA';\nSECUREFILE                     : 'SECUREFILE';\nSECURITY                       : 'SECURITY';\nSEED                           : 'SEED';\nSEG_BLOCK                      : 'SEG_BLOCK';\nSEG_FILE                       : 'SEG_FILE';\nSEGMENT                        : 'SEGMENT';\nSELECTIVITY                    : 'SELECTIVITY';\nSELECT                         : 'SELECT';\nSELF                           : 'SELF';\nSEMIJOIN_DRIVER                : 'SEMIJOIN_DRIVER';\nSEMIJOIN                       : 'SEMIJOIN';\nSEMI_TO_INNER                  : 'SEMI_TO_INNER';\nSEQUENCED                      : 'SEQUENCED';\nSEQUENCE                       : 'SEQUENCE';\nSEQUENCEFILE                   : 'SEQUENCEFILE';\nSEQUENTIAL                     : 'SEQUENTIAL';\nSEQ                            : 'SEQ';\nSERDE                          : 'SERDE';\nSERDEPROPERTIES                : 'SERDEPROPERTIES';\nSERIALIZABLE                   : 'SERIALIZABLE';\nSERIALLY_REUSABLE              : 'SERIALLY_REUSABLE';\nSERIAL                         : 'SERIAL';\nSERVERERROR                    : 'SERVERERROR';\nSERVICE_NAME_CONVERT           : 'SERVICE_NAME_CONVERT';\nSERVICE                        : 'SERVICE';\nSERVICES                       : 'SERVICES';\nSESSION_CACHED_CURSORS         : 'SESSION_CACHED_CURSORS';\nSESSION                        : 'SESSION';\nSESSIONS_PER_USER              : 'SESSIONS_PER_USER';\nSESSIONTIMEZONE                : 'SESSIONTIMEZONE';\nSESSIONTZNAME                  : 'SESSIONTZNAME';\nSET                            : 'SET';\nSETS                           : 'SETS';\nSETTINGS                       : 'SETTINGS';\nSET_TO_JOIN                    : 'SET_TO_JOIN';\nSEVERE                         : 'SEVERE';\nSHARD                          : 'SHARD';\nSHARDSPACE                     : 'SHARDSPACE';\nSHARED_POOL                    : 'SHARED_POOL';\nSHARED                         : 'SHARED';\nSHARE                          : 'SHARE';\nSHARING                        : 'SHARING';\nSHELFLIFE                      : 'SHELFLIFE';\nSHOW                           : 'SHOW';\nSHRINK                         : 'SHRINK';\nSHUTDOWN                       : 'SHUTDOWN';\nSIBLINGS                       : 'SIBLINGS';\nSID                            : 'SID';\nSITE                           : 'SITE';\nSIGNAL_COMPONENT               : 'SIGNAL_COMPONENT';\nSIGNAL_FUNCTION                : 'SIGNAL_FUNCTION';\nSIGN                           : 'SIGN';\nSIGNTYPE                       : 'SIGNTYPE';\nSIMPLE_INTEGER                 : 'SIMPLE_INTEGER';\nSIMPLE                         : 'SIMPLE';\nSINGLE                         : 'SINGLE';\nSINGLETASK                     : 'SINGLETASK';\nSINH                           : 'SINH';\nSIN                            : 'SIN';\nSIZE                           : 'SIZE';\nSIZES                          : 'SIZES';\nSKIP_EXT_OPTIMIZER             : 'SKIP_EXT_OPTIMIZER';\nSKIP_                          : 'SKIP';\nSKIP_UNQ_UNUSABLE_IDX          : 'SKIP_UNQ_UNUSABLE_IDX';\nSKIP_UNUSABLE_INDEXES          : 'SKIP_UNUSABLE_INDEXES';\nSMALLFILE                      : 'SMALLFILE';\nSMALLINT                       : 'SMALLINT';\nSNAPSHOT                       : 'SNAPSHOT';\nSOME                           : 'SOME';\nSORT                           : 'SORT';\nSOUNDEX                        : 'SOUNDEX';\nSOURCE_FILE_DIRECTORY          : 'SOURCE_FILE_DIRECTORY';\nSOURCE_FILE_NAME_CONVERT       : 'SOURCE_FILE_NAME_CONVERT';\nSOURCE                         : 'SOURCE';\nSPACE_KEYWORD                  : 'SPACE';\nSPECIFICATION                  : 'SPECIFICATION';\nSPFILE                         : 'SPFILE';\nSPLIT                          : 'SPLIT';\nSPREADSHEET                    : 'SPREADSHEET';\nSQLDATA                        : 'SQLDATA';\nSQLERROR                       : 'SQLERROR';\nSQLLDR                         : 'SQLLDR';\nSQL                            : 'SQL';\nFILE_EXT                       : 'PKB' | 'PKS';\nSQL_MACRO                      : 'SQL_MACRO';\nSQL_TRACE                      : 'SQL_TRACE';\nSQL_TRANSLATION_PROFILE        : 'SQL_TRANSLATION_PROFILE';\nSQRT                           : 'SQRT';\nSTALE                          : 'STALE';\nSTANDALONE                     : 'STANDALONE';\nSTANDARD                       : 'STANDARD';\nSTANDARD_HASH                  : 'STANDARD_HASH';\nSTANDBY_MAX_DATA_DELAY         : 'STANDBY_MAX_DATA_DELAY';\nSTANDBYS                       : 'STANDBYS';\nSTANDBY                        : 'STANDBY';\nSTAR                           : 'STAR';\nSTAR_TRANSFORMATION            : 'STAR_TRANSFORMATION';\nSTART                          : 'START';\nSTARTOF                        : 'STARTOF';\nSTARTUP                        : 'STARTUP';\nSTATEMENT_ID                   : 'STATEMENT_ID';\nSTATEMENT_QUEUING              : 'STATEMENT_QUEUING';\nSTATEMENTS                     : 'STATEMENTS';\nSTATEMENT                      : 'STATEMENT';\nSTATE                          : 'STATE';\nSTATIC                         : 'STATIC';\nSTATISTICS                     : 'STATISTICS';\nSTATS_BINOMIAL_TEST            : 'STATS_BINOMIAL_TEST';\nSTATS_CROSSTAB                 : 'STATS_CROSSTAB';\nSTATS_F_TEST                   : 'STATS_F_TEST';\nSTATS_KS_TEST                  : 'STATS_KS_TEST';\nSTATS_MODE                     : 'STATS_MODE';\nSTATS_MW_TEST                  : 'STATS_MW_TEST';\nSTATS_ONE_WAY_ANOVA            : 'STATS_ONE_WAY_ANOVA';\nSTATS_T_TEST_INDEP             : 'STATS_T_TEST_INDEP';\nSTATS_T_TEST_INDEPU            : 'STATS_T_TEST_INDEPU';\nSTATS_T_TEST_ONE               : 'STATS_T_TEST_ONE';\nSTATS_T_TEST_PAIRED            : 'STATS_T_TEST_PAIRED';\nSTATS_WSR_TEST                 : 'STATS_WSR_TEST';\nSTDDEV_POP                     : 'STDDEV_POP';\nSTDDEV_SAMP                    : 'STDDEV_SAMP';\nSTOP                           : 'STOP';\nSTORAGE                        : 'STORAGE';\nSTORE                          : 'STORE';\nSTREAMS                        : 'STREAMS';\nSTREAM                         : 'STREAM';\nSTRICT                         : 'STRICT';\nSTRING                         : 'STRING';\nSTRIPE_COLUMNS                 : 'STRIPE_COLUMNS';\nSTRIPE_WIDTH                   : 'STRIPE_WIDTH';\nSTRIP                          : 'STRIP';\nSTRUCTURE                      : 'STRUCTURE';\nSUBMULTISET                    : 'SUBMULTISET';\nSUBPARTITION_REL               : 'SUBPARTITION_REL';\nSUBPARTITIONS                  : 'SUBPARTITIONS';\nSUBPARTITION                   : 'SUBPARTITION';\nSUBQUERIES                     : 'SUBQUERIES';\nSUBQUERY_PRUNING               : 'SUBQUERY_PRUNING';\nSUBSCRIBE                      : 'SUBSCRIBE';\nSUBSET                         : 'SUBSET';\nSUBSTITUTABLE                  : 'SUBSTITUTABLE';\nSUBSTR2                        : 'SUBSTR2';\nSUBSTR4                        : 'SUBSTR4';\nSUBSTRB                        : 'SUBSTRB';\nSUBSTRC                        : 'SUBSTRC';\nSUBTYPE                        : 'SUBTYPE';\nSUCCESSFUL                     : 'SUCCESSFUL';\nSUCCESS                        : 'SUCCESS';\nSUMMARY                        : 'SUMMARY';\nSUPPLEMENTAL                   : 'SUPPLEMENTAL';\nSUSPEND                        : 'SUSPEND';\nSWAP_JOIN_INPUTS               : 'SWAP_JOIN_INPUTS';\nSWITCHOVER                     : 'SWITCHOVER';\nSWITCH                         : 'SWITCH';\nSYNCHRONOUS                    : 'SYNCHRONOUS';\nSYNC                           : 'SYNC';\nSYNONYM                        : 'SYNONYM';\nSYS                            : 'SYS';\nSYSASM                         : 'SYSASM';\nSYS_AUDIT                      : 'SYS_AUDIT';\nSYSAUX                         : 'SYSAUX';\nSYSBACKUP                      : 'SYSBACKUP';\nSYS_CHECKACL                   : 'SYS_CHECKACL';\nSYS_CHECK_PRIVILEGE            : 'SYS_CHECK_PRIVILEGE';\nSYS_CONNECT_BY_PATH            : 'SYS_CONNECT_BY_PATH';\nSYS_CONTEXT                    : 'SYS_CONTEXT';\nSYSDATE                        : 'SYSDATE';\nSYSDBA                         : 'SYSDBA';\nSYS_DBURIGEN                   : 'SYS_DBURIGEN';\nSYSDG                          : 'SYSDG';\nSYS_DL_CURSOR                  : 'SYS_DL_CURSOR';\nSYS_DM_RXFORM_CHR              : 'SYS_DM_RXFORM_CHR';\nSYS_DM_RXFORM_NUM              : 'SYS_DM_RXFORM_NUM';\nSYS_DOM_COMPARE                : 'SYS_DOM_COMPARE';\nSYS_DST_PRIM2SEC               : 'SYS_DST_PRIM2SEC';\nSYS_DST_SEC2PRIM               : 'SYS_DST_SEC2PRIM';\nSYS_ET_BFILE_TO_RAW            : 'SYS_ET_BFILE_TO_RAW';\nSYS_ET_BLOB_TO_IMAGE           : 'SYS_ET_BLOB_TO_IMAGE';\nSYS_ET_IMAGE_TO_BLOB           : 'SYS_ET_IMAGE_TO_BLOB';\nSYS_ET_RAW_TO_BFILE            : 'SYS_ET_RAW_TO_BFILE';\nSYS_EXTPDTXT                   : 'SYS_EXTPDTXT';\nSYS_EXTRACT_UTC                : 'SYS_EXTRACT_UTC';\nSYS_FBT_INSDEL                 : 'SYS_FBT_INSDEL';\nSYS_FILTER_ACLS                : 'SYS_FILTER_ACLS';\nSYS_FNMATCHES                  : 'SYS_FNMATCHES';\nSYS_FNREPLACE                  : 'SYS_FNREPLACE';\nSYS_GET_ACLIDS                 : 'SYS_GET_ACLIDS';\nSYS_GET_COL_ACLIDS             : 'SYS_GET_COL_ACLIDS';\nSYS_GET_PRIVILEGES             : 'SYS_GET_PRIVILEGES';\nSYS_GETTOKENID                 : 'SYS_GETTOKENID';\nSYS_GETXTIVAL                  : 'SYS_GETXTIVAL';\nSYS_GUID                       : 'SYS_GUID';\nSYSGUID                        : 'SYSGUID';\nSYSKM                          : 'SYSKM';\nSYS_MAKE_XMLNODEID             : 'SYS_MAKE_XMLNODEID';\nSYS_MAKEXML                    : 'SYS_MAKEXML';\nSYS_MKXMLATTR                  : 'SYS_MKXMLATTR';\nSYS_MKXTI                      : 'SYS_MKXTI';\nSYSOBJ                         : 'SYSOBJ';\nSYS_OP_ADT2BIN                 : 'SYS_OP_ADT2BIN';\nSYS_OP_ADTCONS                 : 'SYS_OP_ADTCONS';\nSYS_OP_ALSCRVAL                : 'SYS_OP_ALSCRVAL';\nSYS_OP_ATG                     : 'SYS_OP_ATG';\nSYS_OP_BIN2ADT                 : 'SYS_OP_BIN2ADT';\nSYS_OP_BITVEC                  : 'SYS_OP_BITVEC';\nSYS_OP_BL2R                    : 'SYS_OP_BL2R';\nSYS_OP_BLOOM_FILTER_LIST       : 'SYS_OP_BLOOM_FILTER_LIST';\nSYS_OP_BLOOM_FILTER            : 'SYS_OP_BLOOM_FILTER';\nSYS_OP_C2C                     : 'SYS_OP_C2C';\nSYS_OP_CAST                    : 'SYS_OP_CAST';\nSYS_OP_CEG                     : 'SYS_OP_CEG';\nSYS_OP_CL2C                    : 'SYS_OP_CL2C';\nSYS_OP_COMBINED_HASH           : 'SYS_OP_COMBINED_HASH';\nSYS_OP_COMP                    : 'SYS_OP_COMP';\nSYS_OP_CONVERT                 : 'SYS_OP_CONVERT';\nSYS_OP_COUNTCHG                : 'SYS_OP_COUNTCHG';\nSYS_OP_CSCONV                  : 'SYS_OP_CSCONV';\nSYS_OP_CSCONVTEST              : 'SYS_OP_CSCONVTEST';\nSYS_OP_CSR                     : 'SYS_OP_CSR';\nSYS_OP_CSX_PATCH               : 'SYS_OP_CSX_PATCH';\nSYS_OP_CYCLED_SEQ              : 'SYS_OP_CYCLED_SEQ';\nSYS_OP_DECOMP                  : 'SYS_OP_DECOMP';\nSYS_OP_DESCEND                 : 'SYS_OP_DESCEND';\nSYS_OP_DISTINCT                : 'SYS_OP_DISTINCT';\nSYS_OP_DRA                     : 'SYS_OP_DRA';\nSYS_OP_DUMP                    : 'SYS_OP_DUMP';\nSYS_OP_DV_CHECK                : 'SYS_OP_DV_CHECK';\nSYS_OP_ENFORCE_NOT_NULL        : 'SYS_OP_ENFORCE_NOT_NULL$';\nSYSOPER                        : 'SYSOPER';\nSYS_OP_EXTRACT                 : 'SYS_OP_EXTRACT';\nSYS_OP_GROUPING                : 'SYS_OP_GROUPING';\nSYS_OP_GUID                    : 'SYS_OP_GUID';\nSYS_OP_HASH                    : 'SYS_OP_HASH';\nSYS_OP_IIX                     : 'SYS_OP_IIX';\nSYS_OP_ITR                     : 'SYS_OP_ITR';\nSYS_OP_KEY_VECTOR_CREATE       : 'SYS_OP_KEY_VECTOR_CREATE';\nSYS_OP_KEY_VECTOR_FILTER_LIST  : 'SYS_OP_KEY_VECTOR_FILTER_LIST';\nSYS_OP_KEY_VECTOR_FILTER       : 'SYS_OP_KEY_VECTOR_FILTER';\nSYS_OP_KEY_VECTOR_SUCCEEDED    : 'SYS_OP_KEY_VECTOR_SUCCEEDED';\nSYS_OP_KEY_VECTOR_USE          : 'SYS_OP_KEY_VECTOR_USE';\nSYS_OP_LBID                    : 'SYS_OP_LBID';\nSYS_OP_LOBLOC2BLOB             : 'SYS_OP_LOBLOC2BLOB';\nSYS_OP_LOBLOC2CLOB             : 'SYS_OP_LOBLOC2CLOB';\nSYS_OP_LOBLOC2ID               : 'SYS_OP_LOBLOC2ID';\nSYS_OP_LOBLOC2NCLOB            : 'SYS_OP_LOBLOC2NCLOB';\nSYS_OP_LOBLOC2TYP              : 'SYS_OP_LOBLOC2TYP';\nSYS_OP_LSVI                    : 'SYS_OP_LSVI';\nSYS_OP_LVL                     : 'SYS_OP_LVL';\nSYS_OP_MAKEOID                 : 'SYS_OP_MAKEOID';\nSYS_OP_MAP_NONNULL             : 'SYS_OP_MAP_NONNULL';\nSYS_OP_MSR                     : 'SYS_OP_MSR';\nSYS_OP_NICOMBINE               : 'SYS_OP_NICOMBINE';\nSYS_OP_NIEXTRACT               : 'SYS_OP_NIEXTRACT';\nSYS_OP_NII                     : 'SYS_OP_NII';\nSYS_OP_NIX                     : 'SYS_OP_NIX';\nSYS_OP_NOEXPAND                : 'SYS_OP_NOEXPAND';\nSYS_OP_NTCIMG                  : 'SYS_OP_NTCIMG$';\nSYS_OP_NUMTORAW                : 'SYS_OP_NUMTORAW';\nSYS_OP_OIDVALUE                : 'SYS_OP_OIDVALUE';\nSYS_OP_OPNSIZE                 : 'SYS_OP_OPNSIZE';\nSYS_OP_PAR_1                   : 'SYS_OP_PAR_1';\nSYS_OP_PARGID_1                : 'SYS_OP_PARGID_1';\nSYS_OP_PARGID                  : 'SYS_OP_PARGID';\nSYS_OP_PAR                     : 'SYS_OP_PAR';\nSYS_OP_PART_ID                 : 'SYS_OP_PART_ID';\nSYS_OP_PIVOT                   : 'SYS_OP_PIVOT';\nSYS_OP_R2O                     : 'SYS_OP_R2O';\nSYS_OP_RAWTONUM                : 'SYS_OP_RAWTONUM';\nSYS_OP_RDTM                    : 'SYS_OP_RDTM';\nSYS_OP_REF                     : 'SYS_OP_REF';\nSYS_OP_RMTD                    : 'SYS_OP_RMTD';\nSYS_OP_ROWIDTOOBJ              : 'SYS_OP_ROWIDTOOBJ';\nSYS_OP_RPB                     : 'SYS_OP_RPB';\nSYS_OPTLOBPRBSC                : 'SYS_OPTLOBPRBSC';\nSYS_OP_TOSETID                 : 'SYS_OP_TOSETID';\nSYS_OP_TPR                     : 'SYS_OP_TPR';\nSYS_OP_TRTB                    : 'SYS_OP_TRTB';\nSYS_OPTXICMP                   : 'SYS_OPTXICMP';\nSYS_OPTXQCASTASNQ              : 'SYS_OPTXQCASTASNQ';\nSYS_OP_UNDESCEND               : 'SYS_OP_UNDESCEND';\nSYS_OP_VECAND                  : 'SYS_OP_VECAND';\nSYS_OP_VECBIT                  : 'SYS_OP_VECBIT';\nSYS_OP_VECOR                   : 'SYS_OP_VECOR';\nSYS_OP_VECXOR                  : 'SYS_OP_VECXOR';\nSYS_OP_VERSION                 : 'SYS_OP_VERSION';\nSYS_OP_VREF                    : 'SYS_OP_VREF';\nSYS_OP_VVD                     : 'SYS_OP_VVD';\nSYS_OP_XMLCONS_FOR_CSX         : 'SYS_OP_XMLCONS_FOR_CSX';\nSYS_OP_XPTHATG                 : 'SYS_OP_XPTHATG';\nSYS_OP_XPTHIDX                 : 'SYS_OP_XPTHIDX';\nSYS_OP_XPTHOP                  : 'SYS_OP_XPTHOP';\nSYS_OP_XTXT2SQLT               : 'SYS_OP_XTXT2SQLT';\nSYS_OP_ZONE_ID                 : 'SYS_OP_ZONE_ID';\nSYS_ORDERKEY_DEPTH             : 'SYS_ORDERKEY_DEPTH';\nSYS_ORDERKEY_MAXCHILD          : 'SYS_ORDERKEY_MAXCHILD';\nSYS_ORDERKEY_PARENT            : 'SYS_ORDERKEY_PARENT';\nSYS_PARALLEL_TXN               : 'SYS_PARALLEL_TXN';\nSYS_PATHID_IS_ATTR             : 'SYS_PATHID_IS_ATTR';\nSYS_PATHID_IS_NMSPC            : 'SYS_PATHID_IS_NMSPC';\nSYS_PATHID_LASTNAME            : 'SYS_PATHID_LASTNAME';\nSYS_PATHID_LASTNMSPC           : 'SYS_PATHID_LASTNMSPC';\nSYS_PATH_REVERSE               : 'SYS_PATH_REVERSE';\nSYS_PXQEXTRACT                 : 'SYS_PXQEXTRACT';\nSYS_RAW_TO_XSID                : 'SYS_RAW_TO_XSID';\nSYS_RID_ORDER                  : 'SYS_RID_ORDER';\nSYS_ROW_DELTA                  : 'SYS_ROW_DELTA';\nSYS_SC_2_XMLT                  : 'SYS_SC_2_XMLT';\nSYS_SYNRCIREDO                 : 'SYS_SYNRCIREDO';\nSYSTEM_DEFINED                 : 'SYSTEM_DEFINED';\nSYSTEM                         : 'SYSTEM';\nSYSTIMESTAMP                   : 'SYSTIMESTAMP';\nSYS_TYPEID                     : 'SYS_TYPEID';\nSYS_UMAKEXML                   : 'SYS_UMAKEXML';\nSYS_XMLANALYZE                 : 'SYS_XMLANALYZE';\nSYS_XMLCONTAINS                : 'SYS_XMLCONTAINS';\nSYS_XMLCONV                    : 'SYS_XMLCONV';\nSYS_XMLEXNSURI                 : 'SYS_XMLEXNSURI';\nSYS_XMLGEN                     : 'SYS_XMLGEN';\nSYS_XMLI_LOC_ISNODE            : 'SYS_XMLI_LOC_ISNODE';\nSYS_XMLI_LOC_ISTEXT            : 'SYS_XMLI_LOC_ISTEXT';\nSYS_XMLINSTR                   : 'SYS_XMLINSTR';\nSYS_XMLLOCATOR_GETSVAL         : 'SYS_XMLLOCATOR_GETSVAL';\nSYS_XMLNODEID_GETCID           : 'SYS_XMLNODEID_GETCID';\nSYS_XMLNODEID_GETLOCATOR       : 'SYS_XMLNODEID_GETLOCATOR';\nSYS_XMLNODEID_GETOKEY          : 'SYS_XMLNODEID_GETOKEY';\nSYS_XMLNODEID_GETPATHID        : 'SYS_XMLNODEID_GETPATHID';\nSYS_XMLNODEID_GETPTRID         : 'SYS_XMLNODEID_GETPTRID';\nSYS_XMLNODEID_GETRID           : 'SYS_XMLNODEID_GETRID';\nSYS_XMLNODEID_GETSVAL          : 'SYS_XMLNODEID_GETSVAL';\nSYS_XMLNODEID_GETTID           : 'SYS_XMLNODEID_GETTID';\nSYS_XMLNODEID                  : 'SYS_XMLNODEID';\nSYS_XMLT_2_SC                  : 'SYS_XMLT_2_SC';\nSYS_XMLTRANSLATE               : 'SYS_XMLTRANSLATE';\nSYS_XMLTYPE2SQL                : 'SYS_XMLTYPE2SQL';\nSYS_XQ_ASQLCNV                 : 'SYS_XQ_ASQLCNV';\nSYS_XQ_ATOMCNVCHK              : 'SYS_XQ_ATOMCNVCHK';\nSYS_XQBASEURI                  : 'SYS_XQBASEURI';\nSYS_XQCASTABLEERRH             : 'SYS_XQCASTABLEERRH';\nSYS_XQCODEP2STR                : 'SYS_XQCODEP2STR';\nSYS_XQCODEPEQ                  : 'SYS_XQCODEPEQ';\nSYS_XQCON2SEQ                  : 'SYS_XQCON2SEQ';\nSYS_XQCONCAT                   : 'SYS_XQCONCAT';\nSYS_XQDELETE                   : 'SYS_XQDELETE';\nSYS_XQDFLTCOLATION             : 'SYS_XQDFLTCOLATION';\nSYS_XQDOC                      : 'SYS_XQDOC';\nSYS_XQDOCURI                   : 'SYS_XQDOCURI';\nSYS_XQDURDIV                   : 'SYS_XQDURDIV';\nSYS_XQED4URI                   : 'SYS_XQED4URI';\nSYS_XQENDSWITH                 : 'SYS_XQENDSWITH';\nSYS_XQERRH                     : 'SYS_XQERRH';\nSYS_XQERR                      : 'SYS_XQERR';\nSYS_XQESHTMLURI                : 'SYS_XQESHTMLURI';\nSYS_XQEXLOBVAL                 : 'SYS_XQEXLOBVAL';\nSYS_XQEXSTWRP                  : 'SYS_XQEXSTWRP';\nSYS_XQEXTRACT                  : 'SYS_XQEXTRACT';\nSYS_XQEXTRREF                  : 'SYS_XQEXTRREF';\nSYS_XQEXVAL                    : 'SYS_XQEXVAL';\nSYS_XQFB2STR                   : 'SYS_XQFB2STR';\nSYS_XQFNBOOL                   : 'SYS_XQFNBOOL';\nSYS_XQFNCMP                    : 'SYS_XQFNCMP';\nSYS_XQFNDATIM                  : 'SYS_XQFNDATIM';\nSYS_XQFNLNAME                  : 'SYS_XQFNLNAME';\nSYS_XQFNNM                     : 'SYS_XQFNNM';\nSYS_XQFNNSURI                  : 'SYS_XQFNNSURI';\nSYS_XQFNPREDTRUTH              : 'SYS_XQFNPREDTRUTH';\nSYS_XQFNQNM                    : 'SYS_XQFNQNM';\nSYS_XQFNROOT                   : 'SYS_XQFNROOT';\nSYS_XQFORMATNUM                : 'SYS_XQFORMATNUM';\nSYS_XQFTCONTAIN                : 'SYS_XQFTCONTAIN';\nSYS_XQFUNCR                    : 'SYS_XQFUNCR';\nSYS_XQGETCONTENT               : 'SYS_XQGETCONTENT';\nSYS_XQINDXOF                   : 'SYS_XQINDXOF';\nSYS_XQINSERT                   : 'SYS_XQINSERT';\nSYS_XQINSPFX                   : 'SYS_XQINSPFX';\nSYS_XQIRI2URI                  : 'SYS_XQIRI2URI';\nSYS_XQLANG                     : 'SYS_XQLANG';\nSYS_XQLLNMFRMQNM               : 'SYS_XQLLNMFRMQNM';\nSYS_XQMKNODEREF                : 'SYS_XQMKNODEREF';\nSYS_XQNILLED                   : 'SYS_XQNILLED';\nSYS_XQNODENAME                 : 'SYS_XQNODENAME';\nSYS_XQNORMSPACE                : 'SYS_XQNORMSPACE';\nSYS_XQNORMUCODE                : 'SYS_XQNORMUCODE';\nSYS_XQ_NRNG                    : 'SYS_XQ_NRNG';\nSYS_XQNSP4PFX                  : 'SYS_XQNSP4PFX';\nSYS_XQNSPFRMQNM                : 'SYS_XQNSPFRMQNM';\nSYS_XQPFXFRMQNM                : 'SYS_XQPFXFRMQNM';\nSYS_XQ_PKSQL2XML               : 'SYS_XQ_PKSQL2XML';\nSYS_XQPOLYABS                  : 'SYS_XQPOLYABS';\nSYS_XQPOLYADD                  : 'SYS_XQPOLYADD';\nSYS_XQPOLYCEL                  : 'SYS_XQPOLYCEL';\nSYS_XQPOLYCSTBL                : 'SYS_XQPOLYCSTBL';\nSYS_XQPOLYCST                  : 'SYS_XQPOLYCST';\nSYS_XQPOLYDIV                  : 'SYS_XQPOLYDIV';\nSYS_XQPOLYFLR                  : 'SYS_XQPOLYFLR';\nSYS_XQPOLYMOD                  : 'SYS_XQPOLYMOD';\nSYS_XQPOLYMUL                  : 'SYS_XQPOLYMUL';\nSYS_XQPOLYRND                  : 'SYS_XQPOLYRND';\nSYS_XQPOLYSQRT                 : 'SYS_XQPOLYSQRT';\nSYS_XQPOLYSUB                  : 'SYS_XQPOLYSUB';\nSYS_XQPOLYUMUS                 : 'SYS_XQPOLYUMUS';\nSYS_XQPOLYUPLS                 : 'SYS_XQPOLYUPLS';\nSYS_XQPOLYVEQ                  : 'SYS_XQPOLYVEQ';\nSYS_XQPOLYVGE                  : 'SYS_XQPOLYVGE';\nSYS_XQPOLYVGT                  : 'SYS_XQPOLYVGT';\nSYS_XQPOLYVLE                  : 'SYS_XQPOLYVLE';\nSYS_XQPOLYVLT                  : 'SYS_XQPOLYVLT';\nSYS_XQPOLYVNE                  : 'SYS_XQPOLYVNE';\nSYS_XQREF2VAL                  : 'SYS_XQREF2VAL';\nSYS_XQRENAME                   : 'SYS_XQRENAME';\nSYS_XQREPLACE                  : 'SYS_XQREPLACE';\nSYS_XQRESVURI                  : 'SYS_XQRESVURI';\nSYS_XQRNDHALF2EVN              : 'SYS_XQRNDHALF2EVN';\nSYS_XQRSLVQNM                  : 'SYS_XQRSLVQNM';\nSYS_XQRYENVPGET                : 'SYS_XQRYENVPGET';\nSYS_XQRYVARGET                 : 'SYS_XQRYVARGET';\nSYS_XQRYWRP                    : 'SYS_XQRYWRP';\nSYS_XQSEQ2CON4XC               : 'SYS_XQSEQ2CON4XC';\nSYS_XQSEQ2CON                  : 'SYS_XQSEQ2CON';\nSYS_XQSEQDEEPEQ                : 'SYS_XQSEQDEEPEQ';\nSYS_XQSEQINSB                  : 'SYS_XQSEQINSB';\nSYS_XQSEQRM                    : 'SYS_XQSEQRM';\nSYS_XQSEQRVS                   : 'SYS_XQSEQRVS';\nSYS_XQSEQSUB                   : 'SYS_XQSEQSUB';\nSYS_XQSEQTYPMATCH              : 'SYS_XQSEQTYPMATCH';\nSYS_XQSTARTSWITH               : 'SYS_XQSTARTSWITH';\nSYS_XQSTATBURI                 : 'SYS_XQSTATBURI';\nSYS_XQSTR2CODEP                : 'SYS_XQSTR2CODEP';\nSYS_XQSTRJOIN                  : 'SYS_XQSTRJOIN';\nSYS_XQSUBSTRAFT                : 'SYS_XQSUBSTRAFT';\nSYS_XQSUBSTRBEF                : 'SYS_XQSUBSTRBEF';\nSYS_XQTOKENIZE                 : 'SYS_XQTOKENIZE';\nSYS_XQTREATAS                  : 'SYS_XQTREATAS';\nSYS_XQ_UPKXML2SQL              : 'SYS_XQ_UPKXML2SQL';\nSYS_XQXFORM                    : 'SYS_XQXFORM';\nSYS_XSID_TO_RAW                : 'SYS_XSID_TO_RAW';\nSYS_ZMAP_FILTER                : 'SYS_ZMAP_FILTER';\nSYS_ZMAP_REFRESH               : 'SYS_ZMAP_REFRESH';\nT_LETTER                       : 'T';\nTABLE_LOOKUP_BY_NL             : 'TABLE_LOOKUP_BY_NL';\nTABLESPACE_NO                  : 'TABLESPACE_NO';\nTABLESPACE                     : 'TABLESPACE';\nTABLES                         : 'TABLES';\nTABLE_STATS                    : 'TABLE_STATS';\nTABLE                          : 'TABLE';\nTABNO                          : 'TABNO';\nTAG                            : 'TAG';\nTANH                           : 'TANH';\nTAN                            : 'TAN';\nTBLORIDXPARTNUM                : 'TBL$OR$IDX$PART$NUM';\nTEMPFILE                       : 'TEMPFILE';\nTEMPLATE                       : 'TEMPLATE';\nTEMPLATE_TABLE                 : 'TEMPLATE_TABLE';\nTEMPORARY                      : 'TEMPORARY';\nTEMP_TABLE                     : 'TEMP_TABLE';\nTERMINATED                     : 'TERMINATED';\nTEST                           : 'TEST';\nTEXT                           : 'TEXT';\nTEXTFILE                       : 'TEXTFILE';\nTHAN                           : 'THAN';\nTHEN                           : 'THEN';\nTHE                            : 'THE';\nTHESE                          : 'THESE';\nTHREAD                         : 'THREAD';\nTHROUGH                        : 'THROUGH';\nTIER                           : 'TIER';\nTIES                           : 'TIES';\nTIMEOUT                        : 'TIMEOUT';\nTIMESTAMP_LTZ_UNCONSTRAINED    : 'TIMESTAMP_LTZ_UNCONSTRAINED';\nTIMESTAMP                      : 'TIMESTAMP';\nTIMESTAMP_TZ_UNCONSTRAINED     : 'TIMESTAMP_TZ_UNCONSTRAINED';\nTIMESTAMP_UNCONSTRAINED        : 'TIMESTAMP_UNCONSTRAINED';\nTIMES                          : 'TIMES';\nTIME                           : 'TIME';\nTIMEZONE                       : 'TIMEZONE';\nTIMEZONE_ABBR                  : 'TIMEZONE_ABBR';\nTIMEZONE_HOUR                  : 'TIMEZONE_HOUR';\nTIMEZONE_MINUTE                : 'TIMEZONE_MINUTE';\nTIMEZONE_OFFSET                : 'TIMEZONE_OFFSET';\nTIMEZONE_REGION                : 'TIMEZONE_REGION';\nTIME_ZONE                      : 'TIME_ZONE';\nTIMING                         : 'TIMING';\nTINYINT                        : 'TINYINT';\nTIV_GB                         : 'TIV_GB';\nTIV_SSF                        : 'TIV_SSF';\nTO_ACLID                       : 'TO_ACLID';\nTO_BINARY_DOUBLE               : 'TO_BINARY_DOUBLE';\nTO_BINARY_FLOAT                : 'TO_BINARY_FLOAT';\nTO_BLOB                        : 'TO_BLOB';\nTO_CLOB                        : 'TO_CLOB';\nTO_DSINTERVAL                  : 'TO_DSINTERVAL';\nTO_LOB                         : 'TO_LOB';\nTO_MULTI_BYTE                  : 'TO_MULTI_BYTE';\nTO_NCHAR                       : 'TO_NCHAR';\nTO_NCLOB                       : 'TO_NCLOB';\nTO_NUMBER                      : 'TO_NUMBER';\nTOPLEVEL                       : 'TOPLEVEL';\nTO_SINGLE_BYTE                 : 'TO_SINGLE_BYTE';\nTO_TIMESTAMP                   : 'TO_TIMESTAMP';\nTO_TIMESTAMP_TZ                : 'TO_TIMESTAMP_TZ';\nTO_TIME                        : 'TO_TIME';\nTO_TIME_TZ                     : 'TO_TIME_TZ';\nTO                             : 'TO';\nTO_YMINTERVAL                  : 'TO_YMINTERVAL';\nTRACE                          : 'TRACE';\nTRACING                        : 'TRACING';\nTRACKING                       : 'TRACKING';\nTRAILING                       : 'TRAILING';\nTRANSACTION                    : 'TRANSACTION';\nTRANSFORM                      : 'TRANSFORM';\nTRANSFORMS                     : 'TRANSFORMS';\nTRANSFORM_DISTINCT_AGG         : 'TRANSFORM_DISTINCT_AGG';\nTRANSITIONAL                   : 'TRANSITIONAL';\nTRANSITION                     : 'TRANSITION';\nTRANSLATE                      : 'TRANSLATE';\nTRANSLATION                    : 'TRANSLATION';\nTREAT                          : 'TREAT';\nTRIGGERS                       : 'TRIGGERS';\nTRIGGER                        : 'TRIGGER';\nTRUE                           : 'TRUE';\nTRUNCATE                       : 'TRUNCATE';\nTRUNC                          : 'TRUNC';\nTRUSTED                        : 'TRUSTED';\nTRUST                          : 'TRUST';\nTUNING                         : 'TUNING';\nTX                             : 'TX';\nTYPES                          : 'TYPES';\nTYPE                           : 'TYPE';\nTZ_OFFSET                      : 'TZ_OFFSET';\nUB2                            : 'UB2';\nUBA                            : 'UBA';\nUCS2                           : 'UCS2';\nUDF                            : 'UDF';\nUID                            : 'UID';\nUNARCHIVED                     : 'UNARCHIVED';\nUNBOUNDED                      : 'UNBOUNDED';\nUNBOUND                        : 'UNBOUND';\nUNCONDITIONAL                  : 'UNCONDITIONAL';\nUNDER                          : 'UNDER';\nUNDO                           : 'UNDO';\nUNDROP                         : 'UNDROP';\nUNIFORM                        : 'UNIFORM';\nUNION                          : 'UNION';\nUNIONTYPE                      : 'UNIONTYPE';\nUNIQUE                         : 'UNIQUE';\nUNISTR                         : 'UNISTR';\nUNLIMITED                      : 'UNLIMITED';\nUNLOAD                         : 'UNLOAD';\nUNLOCK                         : 'UNLOCK';\nUNMATCHED                      : 'UNMATCHED';\nUNNEST_INNERJ_DISTINCT_VIEW    : 'UNNEST_INNERJ_DISTINCT_VIEW';\nUNNEST_NOSEMIJ_NODISTINCTVIEW  : 'UNNEST_NOSEMIJ_NODISTINCTVIEW';\nUNNEST_SEMIJ_VIEW              : 'UNNEST_SEMIJ_VIEW';\nUNNEST                         : 'UNNEST';\nUNPACKED                       : 'UNPACKED';\nUNPIVOT                        : 'UNPIVOT';\nUNPLUG                         : 'UNPLUG';\nUNPROTECTED                    : 'UNPROTECTED';\nUNQUIESCE                      : 'UNQUIESCE';\nUNRECOVERABLE                  : 'UNRECOVERABLE';\nUNRESTRICTED                   : 'UNRESTRICTED';\nUNSIGNED                       : 'UNSIGNED';\nUNSUBSCRIBE                    : 'UNSUBSCRIBE';\nUNTIL                          : 'UNTIL';\nUNUSABLE                       : 'UNUSABLE';\nUNUSED                         : 'UNUSED';\nUPDATABLE                      : 'UPDATABLE';\nUPDATED                        : 'UPDATED';\nUPDATE                         : 'UPDATE';\nUPDATEXML                      : 'UPDATEXML';\nUPD_INDEXES                    : 'UPD_INDEXES';\nUPD_JOININDEX                  : 'UPD_JOININDEX';\nUPGRADE                        : 'UPGRADE';\nUPPER                          : 'UPPER';\nUPSERT                         : 'UPSERT';\nUROWID                         : 'UROWID';\nUSABLE                         : 'USABLE';\nUSAGE                          : 'USAGE';\nUSE_ANTI                       : 'USE_ANTI';\nUSE_CONCAT                     : 'USE_CONCAT';\nUSE_CUBE                       : 'USE_CUBE';\nUSE_HASH_AGGREGATION           : 'USE_HASH_AGGREGATION';\nUSE_HASH_GBY_FOR_PUSHDOWN      : 'USE_HASH_GBY_FOR_PUSHDOWN';\nUSE_HASH                       : 'USE_HASH';\nUSE_HIDDEN_PARTITIONS          : 'USE_HIDDEN_PARTITIONS';\nUSE_INVISIBLE_INDEXES          : 'USE_INVISIBLE_INDEXES';\nUSE_MERGE_CARTESIAN            : 'USE_MERGE_CARTESIAN';\nUSE_MERGE                      : 'USE_MERGE';\nUSE_NL                         : 'USE_NL';\nUSE_NL_WITH_INDEX              : 'USE_NL_WITH_INDEX';\nUSE_PRIVATE_OUTLINES           : 'USE_PRIVATE_OUTLINES';\nUSER_DATA                      : 'USER_DATA';\nUSER_DEFINED                   : 'USER_DEFINED';\nUSERENV                        : 'USERENV';\nUSERGROUP                      : 'USERGROUP';\nUSER_RECYCLEBIN                : 'USER_RECYCLEBIN';\nUSERS                          : 'USERS';\nUSER_TABLESPACES               : 'USER_TABLESPACES';\nUSER                           : 'USER';\nUSE_SEMI                       : 'USE_SEMI';\nUSE_STORED_OUTLINES            : 'USE_STORED_OUTLINES';\nUSE_TTT_FOR_GSETS              : 'USE_TTT_FOR_GSETS';\nUSE                            : 'USE';\nUSE_VECTOR_AGGREGATION         : 'USE_VECTOR_AGGREGATION';\nUSE_WEAK_NAME_RESL             : 'USE_WEAK_NAME_RESL';\nUSING_NO_EXPAND                : 'USING_NO_EXPAND';\nUSING_NLS_COMP                 : 'USING_NLS_COMP';\nUSING                          : 'USING';\nUTF16BE                        : 'UTF16BE';\nUTF16LE                        : 'UTF16LE';\nUTF32                          : 'UTF32';\nUTF8                           : 'UTF8';\nV1                             : 'V1';\nV2                             : 'V2';\nVALIDATE                       : 'VALIDATE';\nVALIDATE_CONVERSION            : 'VALIDATE_CONVERSION';\nVALIDATION                     : 'VALIDATION';\nVALID_TIME_END                 : 'VALID_TIME_END';\nVALUES                         : 'VALUES';\nVALUE                          : 'VALUE';\nVARCHAR2                       : 'VARCHAR2';\nVARCHAR                        : 'VARCHAR';\nVARCHARC                       : 'VARCHARC';\nVARIABLE                       : 'VARIABLE';\nVARRAW                         : 'VARRAW';\nVARRAWC                        : 'VARRAWC';\nVAR_POP                        : 'VAR_POP';\nVARRAYS                        : 'VARRAYS';\nVARRAY                         : 'VARRAY';\nVAR_SAMP                       : 'VAR_SAMP';\nVARYING                        : 'VARYING';\nVECTOR_READ_TRACE              : 'VECTOR_READ_TRACE';\nVECTOR_READ                    : 'VECTOR_READ';\nVECTOR_TRANSFORM_DIMS          : 'VECTOR_TRANSFORM_DIMS';\nVECTOR_TRANSFORM_FACT          : 'VECTOR_TRANSFORM_FACT';\nVECTOR_TRANSFORM               : 'VECTOR_TRANSFORM';\nVERIFIER                       : 'VERIFIER';\nVERIFY                         : 'VERIFY';\nVERSIONING                     : 'VERSIONING';\nVERSIONS_ENDSCN                : 'VERSIONS_ENDSCN';\nVERSIONS_ENDTIME               : 'VERSIONS_ENDTIME';\nVERSIONS_OPERATION             : 'VERSIONS_OPERATION';\nVERSIONS_STARTSCN              : 'VERSIONS_STARTSCN';\nVERSIONS_STARTTIME             : 'VERSIONS_STARTTIME';\nVERSIONS                       : 'VERSIONS';\nVERSIONS_XID                   : 'VERSIONS_XID';\nVERSION                        : 'VERSION';\nVIEW                           : 'VIEW';\nVIOLATION                      : 'VIOLATION';\nVIRTUAL                        : 'VIRTUAL';\nVISIBILITY                     : 'VISIBILITY';\nVISIBLE                        : 'VISIBLE';\nVOLUME                         : 'VOLUME';\nVSIZE                          : 'VSIZE';\nWAIT                           : 'WAIT';\nWALLET                         : 'WALLET';\nWARNING                        : 'WARNING';\nWEEKS                          : 'WEEKS';\nWEEK                           : 'WEEK';\nWELLFORMED                     : 'WELLFORMED';\nWHENEVER                       : 'WHENEVER';\nWHEN                           : 'WHEN';\nWHERE                          : 'WHERE';\nWHILE                          : 'WHILE';\nWHITESPACE                     : 'WHITESPACE';\nWIDTH_BUCKET                   : 'WIDTH_BUCKET';\nWITHIN                         : 'WITHIN';\nWITHOUT                        : 'WITHOUT';\nWITH_PLSQL                     : 'WITH_PLSQL';\nWITH                           : 'WITH';\nWORK                           : 'WORK';\nWORKERID                       : 'WORKERID';\nWRAPPED                        : 'WRAPPED';\nWRAPPER                        : 'WRAPPER';\nWRITE                          : 'WRITE';\nXDB_FASTPATH_INSERT            : 'XDB_FASTPATH_INSERT';\nXDB                            : 'XDB';\nX_DYN_PRUNE                    : 'X_DYN_PRUNE';\nXID                            : 'XID';\nXML2OBJECT                     : 'XML2OBJECT';\nXMLAGG                         : 'XMLAGG';\nXMLATTRIBUTES                  : 'XMLATTRIBUTES';\nXMLCAST                        : 'XMLCAST';\nXMLCDATA                       : 'XMLCDATA';\nXMLCOLATTVAL                   : 'XMLCOLATTVAL';\nXMLCOMMENT                     : 'XMLCOMMENT';\nXMLCONCAT                      : 'XMLCONCAT';\nXMLDIFF                        : 'XMLDIFF';\nXML_DML_RWT_STMT               : 'XML_DML_RWT_STMT';\nXMLELEMENT                     : 'XMLELEMENT';\nXMLEXISTS2                     : 'XMLEXISTS2';\nXMLEXISTS                      : 'XMLEXISTS';\nXMLFOREST                      : 'XMLFOREST';\nXMLINDEX                       : 'XMLINDEX';\nXMLINDEX_REWRITE_IN_SELECT     : 'XMLINDEX_REWRITE_IN_SELECT';\nXMLINDEX_REWRITE               : 'XMLINDEX_REWRITE';\nXMLINDEX_SEL_IDX_TBL           : 'XMLINDEX_SEL_IDX_TBL';\nXMLISNODE                      : 'XMLISNODE';\nXMLISVALID                     : 'XMLISVALID';\nXMLNAMESPACES                  : 'XMLNAMESPACES';\nXMLPARSE                       : 'XMLPARSE';\nXMLPATCH                       : 'XMLPATCH';\nXMLPI                          : 'XMLPI';\nXMLQUERYVAL                    : 'XMLQUERYVAL';\nXMLQUERY                       : 'XMLQUERY';\nXMLROOT                        : 'XMLROOT';\nXMLSCHEMA                      : 'XMLSCHEMA';\nXMLSERIALIZE                   : 'XMLSERIALIZE';\nXMLTABLE                       : 'XMLTABLE';\nXMLTAG                         : 'XMLTAG';\nXMLTRANSFORMBLOB               : 'XMLTRANSFORMBLOB';\nXMLTRANSFORM                   : 'XMLTRANSFORM';\nXMLTYPE                        : 'XMLTYPE';\nXML                            : 'XML';\nXPATHTABLE                     : 'XPATHTABLE';\nXS_SYS_CONTEXT                 : 'XS_SYS_CONTEXT';\nXS                             : 'XS';\nXTRANSPORT                     : 'XTRANSPORT';\nYEARS                          : 'YEARS';\nYEAR                           : 'YEAR';\nYEAR_TO_MONTH                  : 'YEAR_TO_MONTH';\nYES                            : 'YES';\nYMINTERVAL_UNCONSTRAINED       : 'YMINTERVAL_UNCONSTRAINED';\nZONEMAP                        : 'ZONEMAP';\nZONE                           : 'ZONE';\nZONED                          : 'ZONED';\nPREDICTION                     : 'PREDICTION';\nPREDICTION_BOUNDS              : 'PREDICTION_BOUNDS';\nPREDICTION_COST                : 'PREDICTION_COST';\nPREDICTION_DETAILS             : 'PREDICTION_DETAILS';\nPREDICTION_PROBABILITY         : 'PREDICTION_PROBABILITY';\nPREDICTION_SET                 : 'PREDICTION_SET';\n\nBLOCKCHAIN      : 'BLOCKCHAIN';\nCOLLATE         : 'COLLATE';\nCOLLATION       : 'COLLATION';\nDEFINITION      : 'DEFINITION';\nDUPLICATED      : 'DUPLICATED';\nEXTENDED        : 'EXTENDED';\nHASHING         : 'HASHING';\nIDLE            : 'IDLE';\nIMMUTABLE       : 'IMMUTABLE';\nORACLE_DATAPUMP : 'ORACLE_DATAPUMP';\nORACLE_HDFS     : 'ORACLE_HDFS';\nORACLE_HIVE     : 'ORACLE_HIVE';\nORACLE_LOADER   : 'ORACLE_LOADER';\nSHA2_512_Q      : '\"SHA2_512\"';\nSHARDED         : 'SHARDED';\nV1_Q            : '\"V1\"';\n\nISOLATE   : 'ISOLATE';\nROOT      : 'ROOT';\nUNITE     : 'UNITE';\nALGORITHM : 'ALGORITHM';\n\nCUME_DIST       : 'CUME_DIST';\nDENSE_RANK      : 'DENSE_RANK';\nLISTAGG         : 'LISTAGG';\nPERCENT_RANK    : 'PERCENT_RANK';\nPERCENTILE_CONT : 'PERCENTILE_CONT';\nPERCENTILE_DISC : 'PERCENTILE_DISC';\nRANK            : 'RANK';\n\nAVG              : 'AVG';\nCORR             : 'CORR';\nCOVAR_           : 'COVAR_';\nDECODE           : 'DECODE';\nLAG              : 'LAG';\nLAG_DIFF         : 'LAG_DIFF';\nLAG_DIFF_PERCENT : 'LAG_DIFF_PERCENT';\nLEAD             : 'LEAD';\nMAX              : 'MAX';\nMEDIAN           : 'MEDIAN';\nMEMOPTIMIZE      : 'MEMOPTIMIZE';\nMIN              : 'MIN';\nNTILE            : 'NTILE';\nNVL              : 'NVL';\nRATIO_TO_REPORT  : 'RATIO_TO_REPORT';\nREGR_            : 'REGR_';\nROUND            : 'ROUND';\nROW_NUMBER       : 'ROW_NUMBER';\nSUBSTR           : 'SUBSTR';\nTO_CHAR          : 'TO_CHAR';\nTRIM             : 'TRIM';\nSUM              : 'SUM';\nSTDDEV           : 'STDDEV';\nVAR_             : 'VAR_';\nVARIANCE         : 'VARIANCE';\nLEAST            : 'LEAST';\nGREATEST         : 'GREATEST';\nTO_DATE          : 'TO_DATE';\n\nCHARSETID   : 'CHARSETID';\nCHARSETFORM : 'CHARSETFORM';\nDURATION    : 'DURATION';\nEXTEND      : 'EXTEND';\nMAXLEN      : 'MAXLEN';\nPERSISTABLE : 'PERSISTABLE';\nPOLYMORPHIC : 'POLYMORPHIC';\nSTRUCT      : 'STRUCT';\nTDO         : 'TDO';\nWM_CONCAT   : 'WM_CONCAT';\n\n// Rule #358 <NATIONAL_CHAR_STRING_LIT> - subtoken typecast in <REGULAR_ID>, it also incorporates <character_representation>\n//  Lowercase 'n' is a usual addition to the standard\n\nNATIONAL_CHAR_STRING_LIT: 'N' '\\'' (~('\\'' | '\\r' | '\\n') | '\\'' '\\'' | NEWLINE)* '\\'';\n\n//  Rule #040 <BIT_STRING_LIT> - subtoken typecast in <REGULAR_ID>\n//  Lowercase 'b' is a usual addition to the standard\n\nBIT_STRING_LIT: 'B' ('\\'' [01]* '\\'')+;\n\n//  Rule #284 <HEX_STRING_LIT> - subtoken typecast in <REGULAR_ID>\n//  Lowercase 'x' is a usual addition to the standard\n//  The '0X' is used in external_table_clause sub-rules\n\nHEX_STRING_LIT : ('X' | '0X') ('\\'' [A-F0-9]* '\\'')+;\nDOUBLE_PERIOD  : '..';\nPERIOD         : '.';\n\n//{ Rule #238 <EXACT_NUM_LIT>\n//  This rule is a bit tricky - it resolves the ambiguity with <PERIOD>\n//  It also incorporates <mantisa> and <exponent> for the <APPROXIMATE_NUM_LIT>\n//  Rule #501 <signed_integer> was incorporated directly in the token <APPROXIMATE_NUM_LIT>\n//  See also the rule #617 <unsigned_num_lit>\n/*\n    : (\n            UNSIGNED_INTEGER\n            ( '.' UNSIGNED_INTEGER\n            | {$type = UNSIGNED_INTEGER;}\n            ) ( E ('+' | '-')? UNSIGNED_INTEGER {$type = APPROXIMATE_NUM_LIT;} )?\n    | '.' UNSIGNED_INTEGER ( E ('+' | '-')? UNSIGNED_INTEGER {$type = APPROXIMATE_NUM_LIT;} )?\n    )\n    (D | F)?\n    ;*/\n\nUNSIGNED_INTEGER    : [0-9]+;\nAPPROXIMATE_NUM_LIT : FLOAT_FRAGMENT ('E' ('+' | '-')? (FLOAT_FRAGMENT | [0-9]+))? ('D' | 'F')?;\n\n// Rule #--- <CHAR_STRING> is a base for Rule #065 <char_string_lit> , it incorporates <character_representation>\n// and a superfluous subtoken typecasting of the \"QUOTE\"\nCHAR_STRING: '\\'' (~('\\'' | '\\r' | '\\n') | '\\'' '\\'' | NEWLINE)* '\\'';\n\n// See https://livesql.oracle.com/apex/livesql/file/content_CIREYU9EA54EOKQ7LAMZKRF6P.html\n// TODO: context sensitive string quotes (any characted after quote)\nCHAR_STRING_PERL:\n    'Q' '\\'' (\n        QS_ANGLE\n        | QS_BRACE\n        | QS_BRACK\n        | QS_PAREN\n        | QS_EXCLAM\n        | QS_SHARP\n        | QS_QUOTE\n        | QS_DQUOTE\n        | QS_TILDA\n        | QS_SOLIDUS\n        | QS_RSOLIDUS\n    ) '\\'' -> type(CHAR_STRING)\n;\nfragment QS_ANGLE    : '<' .*? '>';\nfragment QS_BRACE    : '{' .*? '}';\nfragment QS_BRACK    : '[' .*? ']';\nfragment QS_PAREN    : '(' .*? ')';\nfragment QS_EXCLAM   : '!' .*? '!';\nfragment QS_SHARP    : '#' .*? '#';\nfragment QS_QUOTE    : '\\'' .*? '\\'';\nfragment QS_DQUOTE   : '\"' .*? '\"';\nfragment QS_TILDA    : '~' .*? '~';\nfragment QS_SOLIDUS  : '/' .*? '/';\nfragment QS_RSOLIDUS : '\\\\' .*? '\\\\';\n\nDELIMITED_ID: '\"' (~ [\\u0000\"] | '\"' '\"')+ '\"';\n\nPERCENT         : '%';\nAMPERSAND       : '&';\nLEFT_PAREN      : '(';\nRIGHT_PAREN     : ')';\nDOUBLE_ASTERISK : '**';\nASTERISK        : '*';\nPLUS_SIGN       : '+';\nMINUS_SIGN      : '-';\nCOMMA           : ',';\nSOLIDUS         : '/';\nAT_SIGN         : '@';\nASSIGN_OP       : ':=';\nHASH_OP         : '#';\n\nLEFT_CURLY_PAREN  : '{';\nRIGHT_CURLY_PAREN : '}';\n\nSQ: '\\'';\n\nBINDVAR:\n    ':' SIMPLE_LETTER (SIMPLE_LETTER | [0-9] | '_')*\n    | ':' DELIMITED_ID // not used in SQL but spotted in v$sqltext when using cursor_sharing\n    | ':' UNSIGNED_INTEGER\n    | QUESTION_MARK // not in SQL, not in Oracle, not in OCI, use this for JDBC\n;\n\nNOT_EQUAL_OP              : '!=' | '<>' | '^=' | '~=';\nCARRET_OPERATOR_PART      : '^';\nTILDE_OPERATOR_PART       : '~';\nEXCLAMATION_OPERATOR_PART : '!';\nGREATER_THAN_OP           : '>';\nLESS_THAN_OP              : '<';\nCOLON                     : ':';\nSEMICOLON                 : ';';\n\nBAR       : '|';\nEQUALS_OP : '=';\n\nLEFT_BRACKET  : '[';\nRIGHT_BRACKET : ']';\n\nINTRODUCER: '_';\n\n// Comments https://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements006.htm\n\nSINGLE_LINE_COMMENT : '--' ~('\\r' | '\\n')* NEWLINE_EOF -> channel(HIDDEN);\nMULTI_LINE_COMMENT  : '/*' .*? '*/'                    -> channel(HIDDEN);\n// https://docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve034.htm#SQPUG054\nREMARK_COMMENT:\n    'REM' {this.IsNewlineAtPos(-4)}? 'ARK'? (' ' ~('\\r' | '\\n')*)? NEWLINE_EOF -> channel(HIDDEN)\n;\n\n// https://docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve032.htm#SQPUG052\nPROMPT_MESSAGE: 'PRO' {this.IsNewlineAtPos(-4)}? 'MPT'? (' ' ~('\\r' | '\\n')*)? NEWLINE_EOF;\n\n// TODO: should starts with newline\nSTART_CMD: // https://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12002.htm\n    '@' '@'?\n; // https://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12003.htm\n\nREGULAR_ID: SIMPLE_LETTER (SIMPLE_LETTER | '$' | '_' | '#' | [0-9])*;\n\nINQUIRY_DIRECTIVE: '$$' (SIMPLE_LETTER | '_')+;\n\nSPACES: [ \\t\\r\\n]+ -> channel(HIDDEN);\n\n// Fragment rules\n\nfragment NEWLINE_EOF    : NEWLINE | EOF;\nfragment QUESTION_MARK  : '?';\nfragment SIMPLE_LETTER  : [\\p{Letter}];\nfragment FLOAT_FRAGMENT : UNSIGNED_INTEGER* '.'? UNSIGNED_INTEGER+;\nfragment NEWLINE        : '\\r'? '\\n';\nfragment SPACE          : [ \\t];\n"
  },
  {
    "path": "superior-oracle-parser/src/main/antlr4/io/github/melin/superior/parser/oracle/antlr4/OracleParser.g4",
    "content": "/**\n * Oracle(c) PL/SQL 11g Parser\n *\n * Copyright (c) 2009-2011 Alexandre Porcelli <alexandre.porcelli@gmail.com>\n * Copyright (c) 2015-2019 Ivan Kochurkin (KvanTTT, kvanttt@gmail.com, Positive Technologies).\n * Copyright (c) 2017-2018 Mark Adams <madams51703@gmail.com>\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nparser grammar OracleParser;\n\noptions {\n    tokenVocab=OracleLexer;\n    superClass=OracleParserBase;\n}\n\nsql_script\n    : (sql_plus_command  SEMICOLON?)* (\n        (sql_plus_command | unit_statement) (SEMICOLON '/'? (sql_plus_command | unit_statement))* SEMICOLON? '/'?\n    ) EOF\n    ;\n\nunit_statement\n    : alter_analytic_view\n    | alter_attribute_dimension\n    | alter_audit_policy\n    | alter_cluster\n    | alter_database\n    | alter_database_link\n    | alter_dimension\n    | alter_diskgroup\n    | alter_flashback_archive\n    | alter_function\n    | alter_hierarchy\n    | alter_index\n    | alter_inmemory_join_group\n    | alter_java\n    | alter_library\n    | alter_lockdown_profile\n    | alter_materialized_view\n    | alter_materialized_view_log\n    | alter_materialized_zonemap\n    | alter_operator\n    | alter_outline\n    | alter_package\n    | alter_pmem_filestore\n    | alter_procedure\n    | alter_resource_cost\n    | alter_role\n    | alter_rollback_segment\n    | alter_sequence\n    | alter_session\n    | alter_synonym\n    | alter_table\n    | alter_tablespace\n    | alter_tablespace_set\n    | alter_trigger\n    | alter_type\n    | alter_user\n    | alter_view\n    | anonymous_block\n    | call_statement\n    | create_analytic_view\n    | create_attribute_dimension\n    | create_audit_policy\n    | create_cluster\n    | create_context\n    | create_controlfile\n    | create_schema\n    | create_database\n    | create_database_link\n    | create_dimension\n    | create_directory\n    | create_diskgroup\n    | create_edition\n    | create_flashback_archive\n    | create_function_body\n    | create_hierarchy\n    | create_index\n    | create_inmemory_join_group\n    | create_java\n    | create_library\n    | create_lockdown_profile\n    | create_materialized_view\n    | create_materialized_view_log\n    | create_materialized_zonemap\n    | create_operator\n    | create_outline\n    | create_package\n    | create_package_body\n    | create_pmem_filestore\n    | create_procedure_body\n    | create_profile\n    | create_restore_point\n    | create_role\n    | create_rollback_segment\n    | create_sequence\n    | create_spfile\n    | create_synonym\n    | create_table\n    | create_tablespace\n    | create_tablespace_set\n    | create_trigger\n    | create_type\n    | create_user\n    | create_view\n    | drop_analytic_view\n    | drop_attribute_dimension\n    | drop_audit_policy\n    | drop_cluster\n    | drop_context\n    | drop_database\n    | drop_database_link\n    | drop_directory\n    | drop_diskgroup\n    | drop_edition\n    | drop_flashback_archive\n    | drop_function\n    | drop_hierarchy\n    | drop_index\n    | drop_indextype\n    | drop_inmemory_join_group\n    | drop_java\n    | drop_library\n    | drop_lockdown_profile\n    | drop_materialized_view\n    | drop_materialized_view_log\n    | drop_materialized_zonemap\n    | drop_operator\n    | drop_outline\n    | drop_package\n    | drop_pmem_filestore\n    | drop_procedure\n    | drop_restore_point\n    | drop_role\n    | drop_rollback_segment\n    | drop_sequence\n    | drop_synonym\n    | drop_table\n    | drop_tablespace\n    | drop_tablespace_set\n    | drop_trigger\n    | drop_type\n    | drop_user\n    | drop_view\n    | administer_key_management\n    | analyze\n    | associate_statistics\n    | audit_traditional\n    | comment_on_column\n    | comment_on_materialized\n    | comment_on_table\n    | data_manipulation_language_statements\n    | disassociate_statistics\n    | flashback_table\n    | grant_statement\n    | noaudit_statement\n    | purge_statement\n    | rename_object\n    | revoke_statement\n    | transaction_control_statements\n    | truncate_cluster\n    | truncate_table\n    | unified_auditing\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-DISKGROUP.html\nalter_diskgroup\n    : ALTER DISKGROUP (\n        id_expression (\n            ((add_disk_clause | drop_disk_clause)+ | resize_disk_clause) rebalance_diskgroup_clause?\n            | (\n                replace_disk_clause\n                | rename_disk_clause\n                | disk_online_clause\n                | disk_offline_clause\n                | rebalance_diskgroup_clause\n                | check_diskgroup_clause\n                | diskgroup_template_clauses\n                | diskgroup_directory_clauses\n                | diskgroup_alias_clauses\n                | diskgroup_volume_clauses\n                | diskgroup_attributes\n                | drop_diskgroup_file_clause\n                | convert_redundancy_clause\n                | usergroup_clauses\n                | user_clauses\n                | file_permissions_clause\n                | file_owner_clause\n                | scrub_clause\n                | quotagroup_clauses\n                | filegroup_clauses\n            )\n        )\n        | (id_expression (',' id_expression)* | ALL) (\n            undrop_disk_clause\n            | diskgroup_availability\n            | enable_disable_volume\n        )\n    )\n    ;\n\nadd_disk_clause\n    : ADD (\n        (SITE sn = id_expression)? quorum_regular? (FAILGROUP fgn = id_expression)? DISK qualified_disk_clause (\n            ',' qualified_disk_clause\n        )*\n    )+\n    ;\n\ndrop_disk_clause\n    : DROP (\n        quorum_regular? DISK id_expression force_noforce? (',' id_expression force_noforce?)*\n        | DISKS IN quorum_regular? FAILGROUP id_expression force_noforce? (\n            ',' id_expression force_noforce?\n        )*\n    )\n    ;\n\nresize_disk_clause\n    : RESIZE ALL (SIZE size_clause)?\n    ;\n\nreplace_disk_clause\n    : REPLACE DISK id_expression WITH CHAR_STRING force_noforce? (\n        ',' id_expression WITH CHAR_STRING force_noforce?\n    )* (POWER numeric)? wait_nowait?\n    ;\n\nwait_nowait\n    : WAIT\n    | NOWAIT\n    ;\n\nrename_disk_clause\n    : RENAME (\n        DISK id_expression TO id_expression (',' id_expression TO id_expression)*\n        | DISKS ALL\n    )\n    ;\n\ndisk_online_clause\n    : ONLINE (\n        (\n            quorum_regular? DISK id_expression (',' id_expression)*\n            | DISKS IN quorum_regular? FAILGROUP id_expression (',' id_expression)*\n        )+\n        | ALL\n    ) (POWER numeric)? wait_nowait?\n    ;\n\ndisk_offline_clause\n    : OFFLINE (\n        quorum_regular? DISK id_expression (',' id_expression)*\n        | DISKS IN quorum_regular? FAILGROUP id_expression (',' id_expression)*\n    ) timeout_clause?\n    ;\n\ntimeout_clause\n    : DROP AFTER numeric (M_LETTER | H_LETTER)\n    ;\n\nrebalance_diskgroup_clause\n    : REBALANCE (\n        ((WITH | WITHOUT) phase+)? (POWER numeric) (WAIT | NOWAIT)?\n        | MODIFY POWER numeric?\n    )\n    ;\n\nphase\n    : id_expression //TODO\n    ;\n\ncheck_diskgroup_clause\n    : CHECK ALL? (REPAIR | NOREPAIR)? //inconsistent documentation\n    ;\n\ndiskgroup_template_clauses\n    : (ADD | MODIFY) TEMPLATE id_expression qualified_template_clause (\n        ',' id_expression qualified_template_clause\n    )*\n    | DROP TEMPLATE id_expression (',' id_expression)*\n    ;\n\nqualified_template_clause\n    : ATTRIBUTES '(' redundancy_clause? striping_clause? ')' //inconsistent documentation\n    ;\n\nredundancy_clause\n    : MIRROR\n    | HIGH\n    | UNPROTECTED\n    | PARITY\n    | DOUBLE\n    ;\n\nstriping_clause\n    : FINE\n    | COARSE\n    ;\n\nforce_noforce\n    : FORCE\n    | NOFORCE\n    ;\n\ndiskgroup_directory_clauses\n    : ADD DIRECTORY filename (',' filename)*\n    | DROP DIRECTORY filename force_noforce? (',' filename force_noforce?)*\n    | RENAME DIRECTORY dir_name TO dir_name (',' dir_name TO dir_name)*\n    ;\n\ndir_name\n    : CHAR_STRING\n    ;\n\ndiskgroup_alias_clauses\n    : ADD ALIAS CHAR_STRING FOR CHAR_STRING (',' CHAR_STRING FOR CHAR_STRING)*\n    | DROP ALIAS CHAR_STRING (',' CHAR_STRING)*\n    | RENAME ALIAS CHAR_STRING TO CHAR_STRING (',' CHAR_STRING TO CHAR_STRING)*\n    ;\n\ndiskgroup_volume_clauses\n    : add_volume_clause\n    | modify_volume_clause\n    | RESIZE VOLUME id_expression SIZE size_clause\n    | DROP VOLUME id_expression\n    ;\n\nadd_volume_clause\n    : ADD VOLUME id_expression SIZE size_clause redundancy_clause? (\n        STRIPE_WIDTH numeric (K_LETTER | M_LETTER)\n    )? (STRIPE_COLUMNS numeric)?\n    ;\n\nmodify_volume_clause\n    : MODIFY VOLUME id_expression (MOUNTPATH CHAR_STRING)? (USAGE CHAR_STRING)?\n    ;\n\ndiskgroup_attributes\n    : SET ATTRIBUTE CHAR_STRING '=' CHAR_STRING\n    ;\n\ndrop_diskgroup_file_clause\n    : DROP FILE filename (',' filename)*\n    ;\n\nconvert_redundancy_clause\n    : CONVERT REDUNDANCY TO FLEX\n    ;\n\nusergroup_clauses\n    : ADD USERGROUP CHAR_STRING WITH MEMBER CHAR_STRING (',' CHAR_STRING)*\n    | MODIFY USERGROUP CHAR_STRING (ADD | DROP) MEMBER CHAR_STRING (',' CHAR_STRING)*\n    | DROP USERGROUP CHAR_STRING\n    ;\n\nuser_clauses\n    : ADD USER CHAR_STRING (',' CHAR_STRING)*\n    | DROP USER CHAR_STRING (',' CHAR_STRING)* CASCADE?\n    | REPLACE USER CHAR_STRING WITH CHAR_STRING (',' CHAR_STRING WITH CHAR_STRING)*\n    ;\n\nfile_permissions_clause\n    : SET PERMISSION (OWNER | GROUP | OTHER) '=' (NONE | READ (ONLY | WRITE)) (\n        ',' (OWNER | GROUP | OTHER) '=' (NONE | READ (ONLY | WRITE))\n    )* FOR FILE CHAR_STRING (',' CHAR_STRING)*\n    ;\n\nfile_owner_clause\n    : SET OWNERSHIP (OWNER | GROUP) '=' CHAR_STRING (',' (OWNER | GROUP) '=' CHAR_STRING)* FOR FILE CHAR_STRING (\n        ',' CHAR_STRING\n    )*\n    ;\n\nscrub_clause\n    : SCRUB (FILE CHAR_STRING | DISK id_expression)? (REPAIR | NOREPAIR)? (\n        POWER (AUTO | LOW | HIGH | MAX)\n    )? wait_nowait? force_noforce? STOP?\n    ;\n\nquotagroup_clauses\n    : ADD QUOTAGROUP id_expression (SET property_name '=' property_value)?\n    | MODIFY QUOTAGROUP id_expression SET property_name '=' property_value\n    | MOVE QUOTAGROUP id_expression TO id_expression\n    | DROP QUOTAGROUP id_expression\n    ;\n\nproperty_name\n    : id_expression\n    ;\n\nproperty_value\n    : id_expression\n    ;\n\nfilegroup_clauses\n    : add_filegroup_clause\n    | modify_filegroup_clause\n    | move_to_filegroup_clause\n    | drop_filegroup_clause\n    ;\n\nadd_filegroup_clause\n    : ADD FILEGROUP id_expression ((DATABASE | CLUSTER | VOLUME) id_expression | TEMPLATE) (\n        FROM TEMPLATE id_expression\n    )? (SET CHAR_STRING '=' CHAR_STRING)?\n    ;\n\nmodify_filegroup_clause\n    : MODIFY FILEGROUP id_expression SET CHAR_STRING '=' CHAR_STRING\n    ;\n\nmove_to_filegroup_clause\n    : MOVE FILE CHAR_STRING TO FILEGROUP id_expression\n    ;\n\ndrop_filegroup_clause\n    : DROP FILEGROUP id_expression CASCADE?\n    ;\n\nquorum_regular\n    : QUORUM\n    | REGULAR\n    ;\n\nundrop_disk_clause\n    : UNDROP DISKS\n    ;\n\ndiskgroup_availability\n    : MOUNT (RESTRICTED | NORMAL)? (FORCE | NOFORCE)?\n    | DISMOUNT (FORCE | NOFORCE)?\n    ;\n\nenable_disable_volume\n    : (ENABLE | DISABLE) VOLUME (id_expression (',' id_expression)* | ALL)\n    ;\n\n// DDL -> SQL Statements for Stored PL/SQL Units\n\n// Function DDLs\n\ndrop_function\n    : DROP FUNCTION function_name\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-FLASHBACK-ARCHIVE.html\nalter_flashback_archive\n    : ALTER FLASHBACK ARCHIVE fa = id_expression (\n        SET DEFAULT\n        | (ADD | MODIFY) TABLESPACE ts = id_expression flashback_archive_quota?\n        | REMOVE TABLESPACE rts = id_expression\n        | MODIFY /*RETENTION*/ flashback_archive_retention // inconsistent documentation\n        | PURGE (ALL | BEFORE (SCN expression | TIMESTAMP expression))\n        | NO? OPTIMIZE DATA\n    )\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-HIERARCHY.html\nalter_hierarchy\n    : ALTER HIERARCHY (schema_name '.')? hn = id_expression (\n        RENAME TO nhn = id_expression\n        | COMPILE\n    )\n    ;\n\nalter_function\n    : ALTER FUNCTION function_name (\n        EDITIONABLE\n        | NONEDITIONABLE\n        | COMPILE DEBUG? compiler_parameters_clause* (REUSE SETTINGS)?\n    )\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-JAVA.html\nalter_java\n    : ALTER JAVA (SOURCE | CLASS) (schema_name '.')? o = id_expression (\n        RESOLVER '(' ('(' match_string ','? (schema_name | '-') ')')+ ')'\n    )? (COMPILE | RESOLVE | invoker_rights_clause)\n    ;\n\nmatch_string\n    : DELIMITED_ID\n    | '*'\n    ;\n\ncreate_function_body\n    : CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? FUNCTION function_name (\n        '(' parameter (',' parameter)* ')'\n    )? RETURN type_spec (SHARING '=' (METADATA | NONE))? (\n        invoker_rights_clause\n        | accessible_by_clause\n        | default_collation_clause\n        | parallel_enable_clause\n        | result_cache_clause\n        | PIPELINED\n        | DETERMINISTIC\n    )* (\n        ((IS | AS) (DECLARE? seq_of_declare_specs? body | call_spec))\n        | aggregate_clause\n        | pipelined_using_clause\n        | sql_macro_body\n    )\n    ;\n\nsql_macro_body\n    : SQL_MACRO IS BEGIN RETURN quoted_string SEMICOLON END\n    ;\n\n// Creation Function - Specific Clauses\n\nparallel_enable_clause\n    : PARALLEL_ENABLE partition_by_clause?\n    ;\n\npartition_by_clause\n    : '(' PARTITION expression BY (ANY | (HASH | RANGE | LIST) paren_column_list) streaming_clause? ')'\n    ;\n\nresult_cache_clause\n    : RESULT_CACHE relies_on_part? ('(' MODE (DEFAULT | FORCE ) ')')?\n    ;\n\naccessible_by_clause\n    : ACCESSIBLE BY '(' accessor (',' accessor)* ')'\n    ;\n\ndefault_collation_clause\n    : DEFAULT COLLATION USING_NLS_COMP\n    ;\n\naggregate_clause\n    : AGGREGATE USING implementation_type_name\n    ;\n\npipelined_using_clause\n    : PIPELINED ((ROW | TABLE) POLYMORPHIC)? USING implementation_type_name\n    ;\n\naccessor\n    : unitKind = (FUNCTION | PROCEDURE | PACKAGE | TRIGGER | TYPE) function_name\n    ;\n\nrelies_on_part\n    : RELIES_ON '(' tableview_name (',' tableview_name)* ')'\n    ;\n\nstreaming_clause\n    : (ORDER | CLUSTER) expression BY paren_column_list\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-OUTLINE.html\nalter_outline\n    : ALTER OUTLINE (PUBLIC | PRIVATE)? o = id_expression outline_options+\n    ;\n\noutline_options\n    : REBUILD\n    | RENAME TO non = id_expression\n    | CHANGE CATEGORY TO ncn = id_expression\n    | ENABLE\n    | DISABLE\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-LOCKDOWN-PROFILE.html\nalter_lockdown_profile\n    : ALTER LOCKDOWN PROFILE id_expression (\n        lockdown_feature\n        | lockdown_options\n        | lockdown_statements\n    ) (USERS '=' (ALL | COMMON | LOCAL))?\n    ;\n\nlockdown_feature\n    : disable_enable FEATURE ('=' '(' string_list ')' | ALL (EXCEPT '=' '(' string_list ')')?)\n    ;\n\nlockdown_options\n    : disable_enable OPTION ('=' '(' string_list ')' | ALL (EXCEPT '=' '(' string_list ')')?)\n    ;\n\nlockdown_statements\n    : disable_enable STATEMENT (\n        '=' '(' string_list ')'\n        | '=' '(' CHAR_STRING ')' statement_clauses\n        | ALL (EXCEPT '=' '(' string_list ')')?\n    )\n    ;\n\nstatement_clauses\n    : CLAUSE (\n        '=' '(' string_list ')'\n        | '=' '(' CHAR_STRING ')' clause_options\n        | ALL (EXCEPT '=' '(' string_list ')')?\n    )\n    ;\n\nclause_options\n    : OPTION (\n        '=' '(' string_list ')'\n        | '=' '(' CHAR_STRING ')' option_values+\n        | ALL (EXCEPT '=' '(' string_list ')')?\n    )\n    ;\n\noption_values\n    : VALUE '=' '(' string_list ')'\n    | (MINVALUE | MAXVALUE) '=' CHAR_STRING\n    ;\n\nstring_list\n    : CHAR_STRING (',' CHAR_STRING)*\n    ;\n\ndisable_enable\n    : DISABLE\n    | ENABLE\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-LOCKDOWN-PROFILE.html\ndrop_lockdown_profile\n    : DROP LOCKDOWN PROFILE p = id_expression\n    ;\n\n// Package DDLs\n\ndrop_package\n    : DROP PACKAGE BODY? (schema_object_name '.')? package_name\n    ;\n\nalter_package\n    : ALTER PACKAGE package_name COMPILE DEBUG? (PACKAGE | BODY | SPECIFICATION)? compiler_parameters_clause* (\n        REUSE SETTINGS\n    )?\n    ;\n\ncreate_package\n    : CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? PACKAGE (schema_object_name '.')? package_name invoker_rights_clause? (\n        IS\n        | AS\n    ) package_obj_spec* END package_name?\n    ;\n\ncreate_package_body\n    : CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? PACKAGE BODY (schema_object_name '.')? package_name (\n        IS\n        | AS\n    ) package_obj_body*? (BEGIN seq_of_statements (EXCEPTION exception_handler+)?)? END package_name?\n    ;\n\n// Create Package Specific Clauses\n\npackage_obj_spec\n    : pragma_declaration\n    | exception_declaration\n    | procedure_spec\n    | function_spec\n    | variable_declaration\n    | subtype_declaration\n    | cursor_declaration\n    | type_declaration\n    ;\n\nprocedure_spec\n    : PROCEDURE identifier ('(' parameter ( ',' parameter)* ')')? (\n        accessible_by_clause\n        | PARALLEL_ENABLE\n        | DETERMINISTIC\n    )* (AS call_spec)? ';'\n    ;\n\nfunction_spec\n    : FUNCTION identifier ('(' parameter ( ',' parameter)* ')')? RETURN type_spec (\n        DETERMINISTIC\n        | PIPELINED\n        | parallel_enable_clause\n        | RESULT_CACHE\n        | streaming_clause\n    )* (AS call_spec)? ';'\n    ;\n\npackage_obj_body\n    : pragma_declaration\n    | exception_declaration\n    | procedure_spec\n    | function_spec\n    | subtype_declaration\n    | cursor_declaration\n    | variable_declaration\n    | type_declaration\n    | procedure_body\n    | function_body\n    | selection_directive\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/alter-pmem-filestore.html\nalter_pmem_filestore\n    : ALTER PMEM FILESTORE fsn = id_expression (\n        RESIZE size_clause\n        | autoextend_clause\n        | MOUNT (MOUNTPOINT file_path)? (BACKINGFILE filename)? FORCE? //inconsistent documentation\n        | DISMOUNT\n    )\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/drop-pmem-filestore.html\ndrop_pmem_filestore\n    : DROP PMEM FILESTORE fsn = id_expression ((FORCE? INCLUDING | EXCLUDING) CONTENTS)?\n    ;\n\n// Procedure DDLs\n\ndrop_procedure\n    : DROP PROCEDURE procedure_name\n    ;\n\nalter_procedure\n    : ALTER PROCEDURE procedure_name COMPILE DEBUG? compiler_parameters_clause* (REUSE SETTINGS)?\n    ;\n\nfunction_body\n    : FUNCTION identifier ('(' parameter (',' parameter)* ')')? RETURN type_spec (\n        PIPELINED\n        | DETERMINISTIC\n        | invoker_rights_clause\n        | parallel_enable_clause\n        | result_cache_clause\n        | streaming_clause\n            // see example in section \"How Table Functions Stream their Input Data\" on streaming_clause in Oracle 9i: https://docs.oracle.com/cd/B10501_01/appdev.920/a96624/08_subs.htm#20554\n    )* (\n        ( (IS | AS) (DECLARE? seq_of_declare_specs? body | call_spec))\n        | (PIPELINED | AGGREGATE) USING implementation_type_name\n    ) ';'\n    ;\n\nprocedure_body\n    : PROCEDURE identifier ('(' parameter (',' parameter)* ')')? (\n        accessible_by_clause\n        | PARALLEL_ENABLE\n        | DETERMINISTIC\n    )* (IS | AS) (DECLARE? seq_of_declare_specs? body | call_spec | EXTERNAL) ';'\n    ;\n\ncreate_procedure_body\n    : CREATE (OR REPLACE)? PROCEDURE procedure_name ('(' parameter (',' parameter)* ')')? invoker_rights_clause? (PARALLEL_ENABLE | DETERMINISTIC)* (\n        IS\n        | AS\n    ) (DECLARE? seq_of_declare_specs? body | call_spec | EXTERNAL)\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-RESOURCE-COST.html\nalter_resource_cost\n    : ALTER RESOURCE COST (\n        (CPU_PER_SESSION | CONNECT_TIME | LOGICAL_READS_PER_SESSION | PRIVATE_SGA) UNSIGNED_INTEGER\n    )+\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-OUTLINE.html\ndrop_outline\n    : DROP OUTLINE o = id_expression\n    ;\n\n// Rollback Segment DDLs\n\n//https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_2011.htm#SQLRF00816\nalter_rollback_segment\n    : ALTER ROLLBACK SEGMENT rollback_segment_name (\n        ONLINE\n        | OFFLINE\n        | storage_clause\n        | SHRINK (TO size_clause)?\n    )\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-RESTORE-POINT.html\ndrop_restore_point\n    : DROP RESTORE POINT rp = id_expression (FOR PLUGGABLE DATABASE pdb = id_expression)?\n    ;\n\ndrop_rollback_segment\n    : DROP ROLLBACK SEGMENT rollback_segment_name\n    ;\n\ndrop_role\n    : DROP ROLE role_name\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/create-pmem-filestore.html\ncreate_pmem_filestore\n    : CREATE PMEM FILESTORE fsn = id_expression pmem_filestore_options+\n    ;\n\npmem_filestore_options\n    : MOUNTPOINT file_path\n    | BACKINGFILE filename REUSE?\n    | (SIZE | BLOCKSIZE) size_clause\n    | autoextend_clause\n    ;\n\nfile_path\n    : CHAR_STRING\n    ;\n\ncreate_rollback_segment\n    : CREATE PUBLIC? ROLLBACK SEGMENT rollback_segment_name (\n        TABLESPACE tablespace\n        | storage_clause\n    )*\n    ;\n\n// Trigger DDLs\n\ndrop_trigger\n    : DROP TRIGGER trigger_name\n    ;\n\nalter_trigger\n    : ALTER TRIGGER alter_trigger_name = trigger_name (\n        (ENABLE | DISABLE)\n        | RENAME TO rename_trigger_name = trigger_name\n        | COMPILE DEBUG? compiler_parameters_clause* (REUSE SETTINGS)?\n    )\n    ;\n\ncreate_trigger\n    : CREATE (OR REPLACE)? TRIGGER trigger_name (\n        simple_dml_trigger\n        | compound_dml_trigger\n        | non_dml_trigger\n    ) trigger_follows_clause? (ENABLE | DISABLE)? trigger_when_clause? trigger_body\n    ;\n\ntrigger_follows_clause\n    : FOLLOWS trigger_name (',' trigger_name)*\n    ;\n\ntrigger_when_clause\n    : WHEN '(' condition ')'\n    ;\n\n// Create Trigger Specific Clauses\n\nsimple_dml_trigger\n    : (BEFORE | AFTER | INSTEAD OF) dml_event_clause referencing_clause? for_each_row?\n    ;\n\nfor_each_row\n    : FOR EACH ROW\n    ;\n\ncompound_dml_trigger\n    : FOR dml_event_clause referencing_clause?\n    ;\n\nnon_dml_trigger\n    : (BEFORE | AFTER) non_dml_event (OR non_dml_event)* ON (DATABASE | (schema_name '.')? SCHEMA)\n    ;\n\ntrigger_body\n    : compound_trigger_block\n    | CALL identifier\n    | trigger_block\n    ;\n\ncompound_trigger_block\n    : COMPOUND TRIGGER seq_of_declare_specs? timing_point_section+ END trigger_name?\n    ;\n\ntiming_point_section\n    : bk = BEFORE STATEMENT IS tps_block BEFORE STATEMENT ';'\n    | bk = BEFORE EACH ROW IS tps_block BEFORE EACH ROW ';'\n    | ak = AFTER STATEMENT IS tps_block AFTER STATEMENT ';'\n    | ak = AFTER EACH ROW IS tps_block AFTER EACH ROW ';'\n    ;\n\nnon_dml_event\n    : ALTER\n    | ANALYZE\n    | ASSOCIATE STATISTICS\n    | AUDIT\n    | COMMENT\n    | CREATE\n    | DISASSOCIATE STATISTICS\n    | DROP\n    | GRANT\n    | NOAUDIT\n    | RENAME\n    | REVOKE\n    | TRUNCATE\n    | DDL\n    | STARTUP\n    | SHUTDOWN\n    | DB_ROLE_CHANGE\n    | LOGON\n    | LOGOFF\n    | SERVERERROR\n    | SUSPEND\n    | DATABASE\n    | SCHEMA\n    | FOLLOWS\n    ;\n\ndml_event_clause\n    : dml_event_element (OR dml_event_element)* ON dml_event_nested_clause? tableview_name\n    ;\n\ndml_event_element\n    : (DELETE | INSERT | UPDATE) (OF column_list)?\n    ;\n\ndml_event_nested_clause\n    : NESTED TABLE tableview_name OF\n    ;\n\nreferencing_clause\n    : (REFERENCING referencing_element | REFERENCES) referencing_element*\n    ;\n\nreferencing_element\n    : (NEW | OLD | PARENT) column_alias\n    ;\n\n// DDLs\n\ndrop_type\n    : DROP TYPE BODY? type_name (FORCE | VALIDATE)?\n    ;\n\nalter_type\n    : ALTER TYPE type_name (\n        compile_type_clause\n        | replace_type_clause\n        | alter_method_spec\n        | alter_collection_clauses\n        | modifier_clause\n        | overriding_subprogram_spec\n    ) dependent_handling_clause?\n    ;\n\n// Alter Type Specific Clauses\n\ncompile_type_clause\n    : COMPILE DEBUG? (SPECIFICATION | BODY)? compiler_parameters_clause* (REUSE SETTINGS)?\n    ;\n\nreplace_type_clause\n    : REPLACE invoker_rights_clause? AS OBJECT '(' object_member_spec (',' object_member_spec)* ')'\n    ;\n\nalter_method_spec\n    : alter_method_element (',' alter_method_element)*\n    ;\n\nalter_method_element\n    : (ADD | DROP) (map_order_function_spec | subprogram_spec)\n    ;\n\nalter_collection_clauses\n    : MODIFY (LIMIT expression | ELEMENT TYPE type_spec)\n    ;\n\ndependent_handling_clause\n    : INVALIDATE\n    | CASCADE (CONVERT TO SUBSTITUTABLE | NOT? INCLUDING TABLE DATA)? dependent_exceptions_part?\n    ;\n\ndependent_exceptions_part\n    : FORCE? EXCEPTIONS INTO tableview_name\n    ;\n\ncreate_type\n    : CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? TYPE (type_definition | type_body)\n    ;\n\n// Create Type Specific Clauses\n\ntype_definition\n    : type_name (OID CHAR_STRING)? FORCE? object_type_def?\n    ;\n\nobject_type_def\n    : invoker_rights_clause? (object_as_part | object_under_part) sqlj_object_type? (\n        '(' object_member_spec (',' object_member_spec)* ')'\n    )? modifier_clause*\n    ;\n\nobject_as_part\n    : (IS | AS) (OBJECT | varray_type_def | nested_table_type_def)\n    ;\n\nobject_under_part\n    : UNDER type_spec\n    ;\n\nnested_table_type_def\n    : TABLE OF type_spec (NOT NULL_)?\n    ;\n\nsqlj_object_type\n    : EXTERNAL NAME expression LANGUAGE JAVA USING (SQLDATA | CUSTOMDATUM | ORADATA)\n    ;\n\ntype_body\n    : BODY type_name (IS | AS) (type_body_elements)+ END\n    ;\n\ntype_body_elements\n    : map_order_func_declaration\n    | subprog_decl_in_type\n    | overriding_subprogram_spec\n    ;\n\nmap_order_func_declaration\n    : (MAP | ORDER) MEMBER func_decl_in_type\n    ;\n\nsubprog_decl_in_type\n    : (MEMBER | STATIC)? (proc_decl_in_type | func_decl_in_type | constructor_declaration)\n    ;\n\nproc_decl_in_type\n    : PROCEDURE procedure_name\n        (\n            '(' type_elements_parameter (',' type_elements_parameter)* ')'\n        )?\n        (IS | AS) (call_spec | DECLARE? seq_of_declare_specs? body ';')\n    ;\n\nfunc_decl_in_type\n    : FUNCTION function_name ('(' type_elements_parameter (',' type_elements_parameter)* ')')? RETURN type_spec (\n        IS\n        | AS\n    ) (call_spec | DECLARE? seq_of_declare_specs? body ';')\n    ;\n\nconstructor_declaration\n    : FINAL? INSTANTIABLE? CONSTRUCTOR FUNCTION function_name\n        (\n            '(' (SELF IN OUT type_spec ',')? (type_elements_parameter (',' type_elements_parameter)*)? ')'\n        )?\n      RETURN SELF AS RESULT (IS | AS) (call_spec | DECLARE? seq_of_declare_specs? body ';')\n    ;\n\n// Common Type Clauses\n\nmodifier_clause\n    : NOT? (INSTANTIABLE | FINAL | OVERRIDING)\n    ;\n\nobject_member_spec\n    : identifier type_spec sqlj_object_type_attr?\n    | element_spec\n    ;\n\nsqlj_object_type_attr\n    : EXTERNAL NAME expression\n    ;\n\nelement_spec\n    : modifier_clause? element_spec_options+ (',' pragma_clause)?\n    ;\n\nelement_spec_options\n    : subprogram_spec\n    | constructor_spec\n    | map_order_function_spec\n    ;\n\nsubprogram_spec\n    : (MEMBER | STATIC) (type_procedure_spec | type_function_spec)\n    ;\n\n// TODO: should be refactored such as Procedure body and Function body, maybe Type_Function_Body and overriding_function_body\noverriding_subprogram_spec\n    : OVERRIDING MEMBER overriding_function_spec\n    | OVERRIDING MEMBER overriding_procedure_spec\n    ;\n\noverriding_function_spec\n    : FUNCTION function_name ('(' type_elements_parameter (',' type_elements_parameter)* ')')? RETURN (\n        type_spec\n        | SELF AS RESULT\n    ) (PIPELINED? (IS | AS) (DECLARE? seq_of_declare_specs? body))? ';'?\n    ;\n\noverriding_procedure_spec\n    : PROCEDURE procedure_name\n        (\n            '(' type_elements_parameter (',' type_elements_parameter)* ')'\n        )?\n        (IS | AS) (call_spec | DECLARE? seq_of_declare_specs? body ';')\n    ;\n\ntype_procedure_spec\n    : PROCEDURE procedure_name ('(' type_elements_parameter (',' type_elements_parameter)* ')')? (\n        (IS | AS) call_spec\n    )?\n    ;\n\ntype_function_spec\n    : FUNCTION function_name ('(' type_elements_parameter (',' type_elements_parameter)* ')')? RETURN (\n        type_spec\n        | SELF AS RESULT\n    ) ((IS | AS) call_spec | EXTERNAL VARIABLE? NAME expression)?\n    ;\n\nconstructor_spec\n    : FINAL? INSTANTIABLE? CONSTRUCTOR FUNCTION type_spec (\n        '(' (SELF IN OUT type_spec ',')? (type_elements_parameter (',' type_elements_parameter)*)? ')'\n    )? RETURN SELF AS RESULT ((IS | AS) call_spec)?\n    ;\n\nmap_order_function_spec\n    : (MAP | ORDER) MEMBER type_function_spec\n    ;\n\npragma_clause\n    : PRAGMA RESTRICT_REFERENCES '(' pragma_elements (',' pragma_elements)* ')'\n    ;\n\npragma_elements\n    : identifier\n    | DEFAULT\n    ;\n\ntype_elements_parameter\n    : parameter_name (IN OUT NOCOPY | IN OUT | OUT NOCOPY | OUT | IN)? type_spec (ASSIGN_OP constant)?\n    ;\n\n// Sequence DDLs\n\ndrop_sequence\n    : DROP SEQUENCE sequence_name\n    ;\n\nalter_sequence\n    : ALTER SEQUENCE sequence_name sequence_spec+\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-SESSION.html\nalter_session\n    : ALTER SESSION (\n        ADVISE ( COMMIT | ROLLBACK | NOTHING)\n        | CLOSE DATABASE LINK parameter_name\n        | enable_or_disable COMMIT IN PROCEDURE\n        | enable_or_disable GUARD\n        | (enable_or_disable | FORCE) PARALLEL (DML | DDL | QUERY) (\n            PARALLEL (literal | parameter_name)\n        )?\n        | SET alter_session_set_clause\n    )\n    ;\n\nalter_session_set_clause\n    : (parameter_name '=' parameter_value)+\n    | EDITION '=' en = id_expression\n    | CONTAINER '=' cn = id_expression (SERVICE '=' sn = id_expression)?\n    | ROW ARCHIVAL VISIBILITY '=' (ACTIVE | ALL)\n    | DEFAULT_COLLATION '=' (c = id_expression | NONE)\n    ;\n\ncreate_sequence\n    : CREATE SEQUENCE (IF NOT EXISTS)? sequence_name sequence_spec* (SHARING '=' (METADATA | DATA | NONE))?\n    ;\n\n// Common Sequence\n\nsequence_spec\n    : INCREMENT BY UNSIGNED_INTEGER\n    | sequence_start_clause\n    | MAXVALUE UNSIGNED_INTEGER\n    | NOMAXVALUE\n    | MINVALUE UNSIGNED_INTEGER\n    | NOMINVALUE\n    | CYCLE\n    | NOCYCLE\n    | CACHE UNSIGNED_INTEGER\n    | NOCACHE\n    | ORDER\n    | NOORDER\n    | KEEP\n    | NOKEEP\n    | SCALE (EXTEND | NOEXTEND)?\n    | NOSCALE\n    | SHARD (EXTEND | NOEXTEND)?\n    | NOSHARD\n    | SESSION\n    | GLOBAL\n    ;\n\nsequence_start_clause\n    : START WITH UNSIGNED_INTEGER\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-ANALYTIC-VIEW.html\ncreate_analytic_view\n    : CREATE (OR REPLACE)? (NOFORCE | FORCE)? ANALYTIC VIEW av = id_expression (\n        SHARING '=' (METADATA | NONE)\n    )? classification_clause* cav_using_clause? dim_by_clause? measures_clause? default_measure_clause? default_aggregate_clause? cache_clause?\n        fact_columns_clause? qry_transform_clause?\n    ;\n\nclassification_clause\n    // : (CAPTION c=quoted_string)? (DESCRIPTION d=quoted_string)? classification_item*\n    // to handle - 'rule contains a closure with at least one alternative that can match an empty string'\n    : (caption_clause description_clause? | caption_clause? description_clause) classification_item*\n    | caption_clause? description_clause? classification_item+\n    ;\n\ncaption_clause\n    : CAPTION c = quoted_string\n    ;\n\ndescription_clause\n    : DESCRIPTION d = quoted_string\n    ;\n\nclassification_item\n    : CLASSIFICATION cn = id_expression (VALUE cv = quoted_string)? (LANGUAGE language)?\n    ;\n\nlanguage\n    : NULL_\n    | nls = id_expression\n    ;\n\ncav_using_clause\n    : USING (schema_name '.')? t = id_expression REMOTE? (AS? ta = id_expression)?\n    ;\n\ndim_by_clause\n    : DIMENSION BY '(' dim_key (',' dim_key)* ')'\n    ;\n\ndim_key\n    : dim_ref classification_clause* KEY (\n        '(' (a = id_expression '.')? f = column_name (',' (a = id_expression '.')? f = column_name)* ')'\n        | (a = id_expression '.')? f = column_name\n    ) REFERENCES DISTINCT? ('(' attribute_name (',' attribute_name) ')' | attribute_name) HIERARCHIES '(' hier_ref (\n        ',' hier_ref\n    )* ')'\n    ;\n\ndim_ref\n    : (schema_name '.')? ad = id_expression (AS? da = id_expression)?\n    ;\n\nhier_ref\n    : (schema_name '.')? h = id_expression (AS? ha = id_expression)? DEFAULT?\n    ;\n\nmeasures_clause\n    : MEASURES '(' av_measure (',' av_measure)* ')'\n    ;\n\nav_measure\n    : mn = id_expression (base_meas_clause | calc_meas_clause)? //classification_clause*\n    ;\n\nbase_meas_clause\n    : FACT /*FOR MEASURE*/ bm = id_expression meas_aggregate_clause? //FIXME inconsistent documentation\n    ;\n\nmeas_aggregate_clause\n    : AGGREGATE BY aggregate_function_name\n    ;\n\ncalc_meas_clause\n    : /*m=id_expression*/ AS '(' expression ')' //FIXME inconsistent documentation\n    ;\n\ndefault_measure_clause\n    : DEFAULT MEASURE m = id_expression\n    ;\n\ndefault_aggregate_clause\n    : DEFAULT AGGREGATE BY aggregate_function_name\n    ;\n\ncache_clause\n    : CACHE cache_specification (',' cache_specification)*\n    ;\n\ncache_specification\n    : MEASURE GROUP (\n        ALL\n        | '(' id_expression (',' id_expression)* ')' levels_clause (',' levels_clause)*\n    )\n    ;\n\nlevels_clause\n    : LEVELS '(' level_specification (',' level_specification)* ')' level_group_type\n    ;\n\nlevel_specification\n    : '(' ((d = id_expression '.')? h = id_expression '.')? l = id_expression ')'\n    ;\n\nlevel_group_type\n    : DYNAMIC\n    | MATERIALIZED (USING (schema_name '.')? t = id_expression)?\n    ;\n\nfact_columns_clause\n    : FACT COLUMN f = column_name (AS? fa = id_expression (',' AS? fa = id_expression)*)?\n    ;\n\nqry_transform_clause\n    : ENABLE QUERY TRANSFORM (RELY | NORELY)?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-ATTRIBUTE-DIMENSION.html\ncreate_attribute_dimension\n    : CREATE (OR REPLACE)? (NOFORCE | FORCE)? ATTRIBUTE DIMENSION (schema_name '.')? ad = id_expression (\n        SHARING '=' (METADATA | NONE)\n    )? classification_clause* (DIMENSION TYPE (STANDARD | TIME))? ad_using_clause attributes_clause ad_level_clause+ all_clause?\n    ;\n\nad_using_clause\n    : USING source_clause (',' source_clause)* join_path_clause*\n    ;\n\nsource_clause\n    : (schema_name '.')? ftov = id_expression REMOTE? (AS? a = id_expression)?\n    ;\n\njoin_path_clause\n    : JOIN PATH jpn = id_expression ON join_condition\n    ;\n\njoin_condition\n    : join_condition_item (AND join_condition_item)*\n    ;\n\njoin_condition_item\n    : (a = id_expression '.')? column_name '=' (b = id_expression '.')? column_name\n    ;\n\nattributes_clause\n    : ATTRIBUTES '(' ad_attributes_clause (',' ad_attributes_clause)* ')'\n    ;\n\nad_attributes_clause\n    : (a = id_expression '.')? column_name (AS? an = id_expression)? classification_clause*\n    ;\n\nad_level_clause\n    : LEVEL l = id_expression (NOT NULL_ | SKIP_ WHEN NULL_)? (\n        LEVEL TYPE (\n            STANDARD\n            | YEARS\n            | HALF_YEARS\n            | QUARTERS\n            | MONTHS\n            | WEEKS\n            | DAYS\n            | HOURS\n            | MINUTES\n            | SECONDS\n        )\n    )? classification_clause* //inconsistent documentation - LEVEL TYPE goes after the classification_clause rule\n    key_clause alternate_key_clause? (MEMBER NAME expression)? (MEMBER CAPTION expression)? (\n        MEMBER DESCRIPTION expression\n    )? (ORDER BY (MIN | MAX)? dim_order_clause (',' (MIN | MAX)? dim_order_clause)*)? (\n        DETERMINES '(' id_expression (',' id_expression)* ')'\n    )?\n    ;\n\nkey_clause\n    : KEY (a = id_expression | '(' id_expression (',' id_expression)* ')')\n    ;\n\nalternate_key_clause\n    : ALTERNATE key_clause\n    ;\n\ndim_order_clause\n    : a = id_expression (ASC | DESC)? (NULLS (FIRST | LAST))?\n    ;\n\nall_clause\n    : ALL MEMBER (\n        NAME expression (MEMBER CAPTION expression)?\n        | CAPTION expression (MEMBER DESCRIPTION expression)?\n        | DESCRIPTION expression\n    )\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-AUDIT-POLICY-Unified-Auditing.html\ncreate_audit_policy\n    : CREATE AUDIT POLICY p = id_expression privilege_audit_clause? action_audit_clause? role_audit_clause? (\n        WHEN quoted_string EVALUATE PER (STATEMENT | SESSION | INSTANCE)\n    )? (ONLY TOPLEVEL)? container_clause?\n    ;\n\nprivilege_audit_clause\n    : PRIVILEGES system_privilege (',' system_privilege)*\n    ;\n\naction_audit_clause\n    : (standard_actions | component_actions | system_actions)+\n    ;\n\nsystem_actions\n    : ACTIONS system_privilege (',' system_privilege)*\n    ;\n\nstandard_actions\n    : ACTIONS actions_clause (',' actions_clause)*\n    ;\n\nactions_clause\n    : (object_action | ALL) ON (\n        DIRECTORY directory_name\n        | (MINING MODEL)? (schema_name '.')? id_expression\n    )\n    | (system_action | ALL)\n    ;\n\nobject_action\n    : ALTER\n    | GRANT\n    | READ\n    | EXECUTE\n    | AUDIT\n    | COMMENT\n    | DELETE\n    | INDEX\n    | INSERT\n    | LOCK\n    | SELECT\n    | UPDATE\n    | FLASHBACK\n    | RENAME\n    ;\n\nsystem_action\n    : id_expression // SELECT name FROM AUDITABLE_SYSTEM_ACTIONS WHERE component = 'Standard';\n    | (CREATE | ALTER | DROP) JAVA\n    | LOCK TABLE\n    | (READ | WRITE | EXECUTE) DIRECTORY\n    ;\n\ncomponent_actions\n    : ACTIONS COMPONENT '=' (\n        (DATAPUMP | DIRECT_LOAD | OLS | XS) component_action (',' component_action)*\n        | DV component_action ON id_expression (',' component_action ON id_expression)*\n        | PROTOCOL (FTP | HTTP | AUTHENTICATION)\n    )\n    ;\n\ncomponent_action\n    : id_expression // SELECT name FROM auditable_system_actions WHERE component = 'Datapump';\n    ;\n\nrole_audit_clause\n    : ROLES role_name (',' role_name)*\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-CONTROLFILE.html\ncreate_controlfile\n    : CREATE CONTROLFILE REUSE? SET? DATABASE d = id_expression logfile_clause? (\n        RESETLOGS\n        | NORESETLOGS\n    ) (DATAFILE file_specification (',' file_specification)*)? controlfile_options* character_set_clause?\n    ;\n\ncontrolfile_options\n    : MAXLOGFILES numeric\n    | MAXLOGMEMBERS numeric\n    | MAXLOGHISTORY numeric\n    | MAXDATAFILES numeric\n    | MAXINSTANCES numeric\n    | ARCHIVELOG\n    | NOARCHIVELOG\n    | FORCE LOGGING\n    | SET STANDBY NOLOGGING FOR (DATA AVAILABILITY | LOAD PERFORMANCE)\n    ;\n\nlogfile_clause\n    : LOGFILE (GROUP? numeric)? file_specification (',' (GROUP? numeric)? file_specification)*\n    ;\n\ncharacter_set_clause\n    : CHARACTER SET cs = id_expression\n    ;\n\nfile_specification\n    : datafile_tempfile_spec\n    | redo_log_file_spec\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-DISKGROUP.html\ncreate_diskgroup\n    : CREATE DISKGROUP id_expression (\n        (HIGH | NORMAL | FLEX | EXTENDED (SITE sn = id_expression)? | EXTERNAL) REDUNDANCY\n    )? (\n        quorum_regular? (FAILGROUP fg = id_expression)? DISK qualified_disk_clause (\n            ',' qualified_disk_clause\n        )*\n    )+ (ATTRIBUTE an = CHAR_STRING '=' av = CHAR_STRING (',' CHAR_STRING '=' CHAR_STRING)*)?\n    ;\n\nqualified_disk_clause\n    : ss = CHAR_STRING (NAME dn = id_expression)? (SIZE size_clause)? force_noforce?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-EDITION.html\ncreate_edition\n    : CREATE EDITION e = id_expression (AS CHILD OF pe = id_expression)?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-FLASHBACK-ARCHIVE.html\ncreate_flashback_archive\n    : CREATE FLASHBACK ARCHIVE DEFAULT? fa = id_expression TABLESPACE ts = id_expression flashback_archive_quota? (\n        NO? OPTIMIZE DATA\n    )? flashback_archive_retention\n    ;\n\nflashback_archive_quota\n    : QUOTA UNSIGNED_INTEGER (M_LETTER | G_LETTER | T_LETTER | P_LETTER | E_LETTER)\n    ;\n\nflashback_archive_retention\n    : RETENTION UNSIGNED_INTEGER (YEAR | MONTH | DAY)\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-HIERARCHY.html\ncreate_hierarchy\n    : CREATE (OR REPLACE)? (NO? FORCE)? HIERARCHY (schema_name '.')? h = id_expression (\n        SHARING '=' (METADATA | NONE)\n    )? classification_clause* hier_using_clause level_hier_clause hier_attrs_clause?\n    ;\n\nhier_using_clause\n    : USING (schema_name '.')? ad = id_expression\n    ;\n\nlevel_hier_clause\n    : '(' (l = id_expression (CHILD OF)?)+ ')'\n    ;\n\nhier_attrs_clause\n    : HIERARCHICAL ATTRIBUTES '(' hier_attr_clause ')'\n    ;\n\nhier_attr_clause\n    : hier_attr_name classification_clause*\n    ;\n\nhier_attr_name\n    : MEMBER_NAME\n    | MEMBER_UNIQUE_NAME\n    | MEMBER_CAPTION\n    | MEMBER_DESCRIPTION\n    | LEVEL_NAME\n    | HIER_ORDER\n    | DEPTH\n    | IS_LEAF\n    | PARENT_LEVEL_NAME\n    | PARENT_UNIQUE_NAME\n    ;\n\ncreate_index\n    : CREATE (UNIQUE | BITMAP)? INDEX index_name (IF NOT EXISTS)? ON (\n        cluster_index_clause\n        | table_index_clause\n        | bitmap_join_index_clause\n    ) (USABLE | UNUSABLE)? ((DEFERRED | IMMEDIATE) INVALIDATION)?\n    ;\n\ncluster_index_clause\n    : CLUSTER cluster_name index_attributes?\n    ;\n\ncluster_name\n    : (id_expression '.')? id_expression\n    ;\n\ntable_index_clause\n    : tableview_name table_alias? '(' index_expr (ASC | DESC)? (',' index_expr (ASC | DESC)?)* ')' index_properties?\n    ;\n\nbitmap_join_index_clause\n    : tableview_name '(' (tableview_name | table_alias)? column_name (ASC | DESC)? (\n        ',' (tableview_name | table_alias)? column_name (ASC | DESC)?\n    )* ')' FROM tableview_name table_alias (',' tableview_name table_alias)* where_clause local_partitioned_index? index_attributes?\n    ;\n\nindex_expr\n    : column_name\n    | expression\n    ;\n\nindex_properties\n    : (global_partitioned_index | local_partitioned_index | index_attributes)+\n    | INDEXTYPE IS (domain_index_clause | xmlindex_clause)\n    ;\n\ndomain_index_clause\n    : indextype local_domain_index_clause? parallel_clause? (PARAMETERS '(' odci_parameters ')')?\n    ;\n\nlocal_domain_index_clause\n    : LOCAL (\n        '(' PARTITION partition_name (PARAMETERS '(' odci_parameters ')')? (\n            ',' PARTITION partition_name (PARAMETERS '(' odci_parameters ')')?\n        )* ')'\n    )?\n    ;\n\nxmlindex_clause\n    : (XDB '.')? XMLINDEX local_xmlindex_clause? parallel_clause? //TODO xmlindex_parameters_clause?\n    ;\n\nlocal_xmlindex_clause\n    : LOCAL (\n        '(' PARTITION partition_name (\n            ',' PARTITION partition_name //TODO xmlindex_parameters_clause?\n        )* ')'\n    )?\n    ;\n\nglobal_partitioned_index\n    : GLOBAL PARTITION BY (\n        RANGE '(' column_name (',' column_name)* ')' '(' index_partitioning_clause (\n            ',' index_partitioning_clause\n        )* ')'\n        | HASH '(' column_name (',' column_name)* ')' (\n            individual_hash_partitions\n            | hash_partitions_by_quantity\n        )\n    )\n    ;\n\nindex_partitioning_clause\n    : PARTITION partition_name? VALUES LESS THAN '(' index_partitioning_values_list ')' segment_attributes_clause?\n    ;\n\nindex_partitioning_values_list\n    : literal (',' literal)*\n    | TIMESTAMP literal (',' TIMESTAMP literal)*\n    ;\n\nlocal_partitioned_index\n    : LOCAL (\n        on_range_partitioned_table\n        | on_list_partitioned_table\n        | on_hash_partitioned_table\n        | on_comp_partitioned_table\n    )?\n    ;\n\non_range_partitioned_table\n    : '(' partitioned_table (',' partitioned_table)* ')'\n    ;\n\non_list_partitioned_table\n    : '(' partitioned_table (',' partitioned_table)* ')'\n    ;\n\npartitioned_table\n    : PARTITION partition_name? (segment_attributes_clause | key_compression)* UNUSABLE?\n    ;\n\non_hash_partitioned_table\n    : STORE IN '(' tablespace (',' tablespace)* ')'\n    | '(' on_hash_partitioned_clause (',' on_hash_partitioned_clause)* ')'\n    ;\n\non_hash_partitioned_clause\n    : PARTITION partition_name? (TABLESPACE tablespace)? key_compression? UNUSABLE?\n    ;\n\non_comp_partitioned_table\n    : (STORE IN '(' tablespace (',' tablespace)* ')')? '(' on_comp_partitioned_clause (\n        ',' on_comp_partitioned_clause\n    )* ')'\n    ;\n\non_comp_partitioned_clause\n    : PARTITION partition_name? (segment_attributes_clause | key_compression)* UNUSABLE? index_subpartition_clause?\n    ;\n\nindex_subpartition_clause\n    : STORE IN '(' tablespace (',' tablespace)* ')'\n    | '(' index_subpartition_subclause (',' index_subpartition_subclause)* ')'\n    ;\n\nindex_subpartition_subclause\n    : SUBPARTITION subpartition_name? (TABLESPACE tablespace)? key_compression? UNUSABLE?\n    ;\n\nodci_parameters\n    : CHAR_STRING\n    ;\n\nindextype\n    : (id_expression '.')? id_expression\n    ;\n\n//https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_1010.htm#SQLRF00805\nalter_index\n    : ALTER INDEX index_name (alter_index_ops_set1 | alter_index_ops_set2)\n    ;\n\nalter_index_ops_set1\n    : (\n        deallocate_unused_clause\n        | allocate_extent_clause\n        | shrink_clause\n        | parallel_clause\n        | physical_attributes_clause\n        | logging_clause\n    )+\n    ;\n\nalter_index_ops_set2\n    : rebuild_clause\n    | PARAMETERS '(' odci_parameters ')'\n    | COMPILE\n    | enable_or_disable\n    | UNUSABLE\n    | visible_or_invisible\n    | RENAME TO new_index_name\n    | COALESCE\n    | monitoring_nomonitoring USAGE\n    | UPDATE BLOCK REFERENCES\n    | alter_index_partitioning\n    ;\n\nvisible_or_invisible\n    : VISIBLE\n    | INVISIBLE\n    ;\n\nmonitoring_nomonitoring\n    : MONITORING\n    | NOMONITORING\n    ;\n\nrebuild_clause\n    : REBUILD (PARTITION partition_name | SUBPARTITION subpartition_name | REVERSE | NOREVERSE)? (\n        parallel_clause\n        | TABLESPACE tablespace\n        | PARAMETERS '(' odci_parameters ')'\n        //TODO        | xmlindex_parameters_clause\n        | ONLINE\n        | physical_attributes_clause\n        | key_compression\n        | logging_clause\n    )*\n    ;\n\nalter_index_partitioning\n    : modify_index_default_attrs\n    | add_hash_index_partition\n    | modify_index_partition\n    | rename_index_partition\n    | drop_index_partition\n    | split_index_partition\n    | coalesce_index_partition\n    | modify_index_subpartition\n    ;\n\nmodify_index_default_attrs\n    : MODIFY DEFAULT ATTRIBUTES (FOR PARTITION partition_name)? (\n        physical_attributes_clause\n        | TABLESPACE (tablespace | DEFAULT)\n        | logging_clause\n    )\n    ;\n\nadd_hash_index_partition\n    : ADD PARTITION partition_name? (TABLESPACE tablespace)? key_compression? parallel_clause?\n    ;\n\ncoalesce_index_partition\n    : COALESCE PARTITION parallel_clause?\n    ;\n\nmodify_index_partition\n    : MODIFY PARTITION partition_name (\n        modify_index_partitions_ops+\n        | PARAMETERS '(' odci_parameters ')'\n        | COALESCE\n        | UPDATE BLOCK REFERENCES\n        | UNUSABLE\n    )\n    ;\n\nmodify_index_partitions_ops\n    : deallocate_unused_clause\n    | allocate_extent_clause\n    | physical_attributes_clause\n    | logging_clause\n    | key_compression\n    | shrink_clause\n    ;\n\nrename_index_partition\n    : RENAME (PARTITION partition_name | SUBPARTITION subpartition_name) TO new_partition_name\n    ;\n\ndrop_index_partition\n    : DROP PARTITION partition_name\n    ;\n\nsplit_index_partition\n    : SPLIT PARTITION partition_name_old AT '(' literal (',' literal)* ')' (\n        INTO '(' index_partition_description ',' index_partition_description ')'\n    )? parallel_clause?\n    ;\n\nindex_partition_description\n    : PARTITION (\n        partition_name (\n            (segment_attributes_clause | key_compression)+\n            | PARAMETERS '(' odci_parameters ')'\n        ) UNUSABLE?\n    )?\n    ;\n\nmodify_index_subpartition\n    : MODIFY SUBPARTITION subpartition_name (UNUSABLE | modify_index_partitions_ops)\n    ;\n\npartition_name_old\n    : partition_name\n    ;\n\nnew_partition_name\n    : partition_name\n    ;\n\nnew_index_name\n    : index_name\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-INMEMORY-JOIN-GROUP.html\nalter_inmemory_join_group\n    : ALTER INMEMORY JOIN GROUP (schema_name '.')? jg = id_expression (ADD | REMOVE) '(' (\n        schema_name '.'\n    )? t = id_expression '(' c = id_expression ')' ')'\n    ;\n\ncreate_user\n    : CREATE USER user_object_name (IF NOT EXISTS)? (\n        identified_by\n        | identified_other_clause\n        | user_tablespace_clause\n        | quota_clause\n        | profile_clause\n        | password_expire_clause\n        | user_lock_clause\n        | user_editions_clause\n        | container_clause\n    )+\n    ;\n\n// The standard clauses only permit one user per statement.\n// The proxy clause allows multiple users for a proxy designation.\nalter_user\n    : ALTER USER user_object_name (\n        alter_identified_by\n        | identified_other_clause\n        | user_tablespace_clause\n        | quota_clause\n        | profile_clause\n        | user_default_role_clause\n        | password_expire_clause\n        | user_lock_clause\n        | alter_user_editions_clause\n        | container_clause\n        | container_data_clause\n    )+\n    | user_object_name (',' user_object_name)* proxy_clause\n    ;\n\ndrop_user\n    : DROP USER user_object_name (IF EXISTS)? CASCADE?\n    ;\n\nalter_identified_by\n    : identified_by (REPLACE id_expression)?\n    ;\n\nidentified_by\n    : IDENTIFIED BY id_expression\n    ;\n\nidentified_other_clause\n    : IDENTIFIED (EXTERNALLY | GLOBALLY) (AS quoted_string)?\n    ;\n\nuser_tablespace_clause\n    : (DEFAULT | TEMPORARY) TABLESPACE id_expression\n    ;\n\nquota_clause\n    : QUOTA (size_clause | UNLIMITED) ON id_expression\n    ;\n\nprofile_clause\n    : PROFILE id_expression\n    ;\n\nrole_clause\n    : role_name (',' role_name)*\n    | ALL (EXCEPT role_name (',' role_name)*)*\n    ;\n\nuser_default_role_clause\n    : DEFAULT ROLE (NONE | role_clause)\n    ;\n\npassword_expire_clause\n    : PASSWORD EXPIRE\n    ;\n\nuser_lock_clause\n    : ACCOUNT (LOCK | UNLOCK)\n    ;\n\nuser_editions_clause\n    : ENABLE EDITIONS\n    ;\n\nalter_user_editions_clause\n    : user_editions_clause (FOR regular_id (',' regular_id)*)? FORCE?\n    ;\n\nproxy_clause\n    : REVOKE CONNECT THROUGH (ENTERPRISE USERS | user_object_name)\n    | GRANT CONNECT THROUGH (\n        ENTERPRISE USERS\n        | user_object_name (WITH (NO ROLES | ROLE role_clause))? (AUTHENTICATION REQUIRED)? (\n            AUTHENTICATED USING (PASSWORD | CERTIFICATE | DISTINGUISHED NAME)\n        )?\n    )\n    ;\n\ncontainer_names\n    : LEFT_PAREN id_expression (',' id_expression)* RIGHT_PAREN\n    ;\n\nset_container_data\n    : SET CONTAINER_DATA EQUALS_OP (ALL | DEFAULT | container_names)\n    ;\n\nadd_rem_container_data\n    : (ADD | REMOVE) CONTAINER_DATA EQUALS_OP container_names\n    ;\n\ncontainer_data_clause\n    : set_container_data\n    | add_rem_container_data (FOR container_tableview_name)?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ADMINISTER-KEY-MANAGEMENT.html\nadminister_key_management\n    : ADMINISTER KEY MANAGEMENT (\n        keystore_management_clauses\n        | key_management_clauses\n        | secret_management_clauses\n        | zero_downtime_software_patching_clauses\n    )\n    ;\n\nkeystore_management_clauses\n    : create_keystore\n    | open_keystore\n    | close_keystore\n    | backup_keystore\n    | alter_keystore_password\n    | merge_into_new_keystore\n    | merge_into_existing_keystore\n    | isolate_keystore\n    | unite_keystore\n    ;\n\ncreate_keystore\n    : CREATE (\n        KEYSTORE ksl = CHAR_STRING\n        | LOCAL? AUTO_LOGIN KEYSTORE FROM KEYSTORE ksl = CHAR_STRING\n    ) IDENTIFIED BY keystore_password\n    ;\n\nopen_keystore\n    : SET KEYSTORE OPEN force_keystore? identified_by_store container_clause?\n    ;\n\nforce_keystore\n    : FORCE KEYSTORE\n    ;\n\nclose_keystore\n    : SET KEYSTORE CLOSE identified_by_store? container_clause?\n    ;\n\nbackup_keystore\n    : BACKUP KEYSTORE (USING bi = CHAR_STRING)? force_keystore? identified_by_store (\n        TO ksl = CHAR_STRING\n    )?\n    ;\n\nalter_keystore_password\n    : ALTER KEYSTORE PASSWORD force_keystore? IDENTIFIED BY o = keystore_password SET n = keystore_password with_backup_clause?\n    ;\n\nmerge_into_new_keystore\n    : MERGE KEYSTORE ksl1 = CHAR_STRING identified_by_password_clause? AND KEYSTORE ksl2 = CHAR_STRING identified_by_password_clause? INTO NEW\n        KEYSTORE ksl2 = CHAR_STRING identified_by_password_clause\n    ;\n\nmerge_into_existing_keystore\n    : MERGE KEYSTORE ksl1 = CHAR_STRING identified_by_password_clause? INTO EXISTING KEYSTORE ksl2 = CHAR_STRING identified_by_password_clause\n        with_backup_clause?\n    ;\n\nisolate_keystore\n    : FORCE? ISOLATE KEYSTORE IDENTIFIED BY i = keystore_password FROM ROOT KEYSTORE force_keystore? identified_by_store with_backup_clause?\n    ;\n\nunite_keystore\n    : UNITE KEYSTORE IDENTIFIED BY i = keystore_password WITH ROOT KEYSTORE force_keystore? identified_by_store with_backup_clause?\n    ;\n\nkey_management_clauses\n    : set_key\n    | create_key\n    | use_key\n    | set_key_tag\n    | export_keys\n    | import_keys\n    | migrate_keys\n    | reverse_migrate_keys\n    | move_keys\n    ;\n\nset_key\n    : SET ENCRYPTION? KEY ((mkid ':')? mk)? using_tag_clause? using_algorithm_clause? force_keystore? identified_by_store with_backup_clause?\n        container_clause?\n    ;\n\ncreate_key\n    : CREATE ENCRYPTION? KEY ((mkid ':')? mk)? using_tag_clause? using_algorithm_clause? force_keystore? identified_by_store with_backup_clause?\n        container_clause?\n    ;\n\nmkid\n    : CHAR_STRING\n    ;\n\nmk\n    : CHAR_STRING\n    ;\n\nuse_key\n    : USE ENCRYPTION? KEY k = CHAR_STRING using_tag_clause? force_keystore? identified_by_store with_backup_clause?\n    ;\n\nset_key_tag\n    : SET TAG t = CHAR_STRING FOR k = CHAR_STRING force_keystore? identified_by_store with_backup_clause?\n    ;\n\nexport_keys\n    : EXPORT ENCRYPTION? KEYS WITH SECRET secret TO filename force_keystore? identified_by_store (\n        WITH IDENTIFIER IN (CHAR_STRING (',' CHAR_STRING)* | '(' subquery ')')\n    )?\n    ;\n\nimport_keys\n    : IMPORT ENCRYPTION? KEYS WITH SECRET secret FROM filename force_keystore? identified_by_store with_backup_clause?\n    ;\n\nmigrate_keys\n    : SET ENCRYPTION? KEY IDENTIFIED BY hsm = secret force_keystore? MIGRATE USING keystore_password with_backup_clause?\n    ;\n\nreverse_migrate_keys\n    : SET ENCRYPTION? KEY IDENTIFIED BY s = secret force_keystore? REVERSE MIGRATE USING hsm = secret\n    ;\n\nmove_keys\n    : MOVE ENCRYPTION? KEYS TO NEW KEYSTORE ksl1 = CHAR_STRING IDENTIFIED BY ksp1 = keystore_password FROM FORCE? KEYSTORE IDENTIFIED BY ksp =\n        keystore_password (WITH IDENTIFIER IN (CHAR_STRING (',' CHAR_STRING)* | subquery))? with_backup_clause?\n    ;\n\nidentified_by_store\n    : IDENTIFIED BY (EXTERNAL STORE | keystore_password)\n    ;\n\nusing_algorithm_clause\n    : USING ALGORITHM ea = CHAR_STRING\n    ;\n\nusing_tag_clause\n    : USING TAG t = CHAR_STRING\n    ;\n\nsecret_management_clauses\n    : add_update_secret\n    | delete_secret\n    | add_update_secret_seps\n    | delete_secret_seps\n    ;\n\nadd_update_secret\n    : (ADD | UPDATE) SECRET s = CHAR_STRING FOR CLIENT ci = CHAR_STRING using_tag_clause? force_keystore? identified_by_store? with_backup_clause?\n    ;\n\ndelete_secret\n    : DELETE SECRET FOR CLIENT ci = CHAR_STRING force_keystore? identified_by_store with_backup_clause?\n    ;\n\nadd_update_secret_seps\n    : (ADD | UPDATE) SECRET s = CHAR_STRING FOR CLIENT ci = CHAR_STRING using_tag_clause? TO LOCAL? AUTO_LOGIN KEYSTORE directory_path\n    ;\n\ndelete_secret_seps\n    : DELETE SECRET s = CHAR_STRING SQ FOR CLIENT ci = CHAR_STRING FROM LOCAL? AUTO_LOGIN KEYSTORE directory_path\n    ;\n\nzero_downtime_software_patching_clauses\n    : SWITCHOVER TO? LIBRARY path FOR ALL CONTAINERS //inconsistent documentation\n    ;\n\nwith_backup_clause\n    : WITH BACKUP (USING bi = CHAR_STRING)?\n    ;\n\nidentified_by_password_clause\n    : IDENTIFIED BY keystore_password\n    ;\n\nkeystore_password\n    : DELIMITED_ID\n    ;\n\npath\n    : CHAR_STRING\n    ;\n\nsecret\n    : DELIMITED_ID\n    ;\n\n// https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_4005.htm#SQLRF01105\nanalyze\n    : (\n        ANALYZE (TABLE tableview_name | INDEX index_name) partition_extention_clause?\n        | ANALYZE CLUSTER cluster_name\n    ) (\n        validation_clauses\n        | compute_clauses\n        | ESTIMATE SYSTEM? STATISTICS for_clause? (SAMPLE UNSIGNED_INTEGER (ROWS | PERCENT_KEYWORD))?\n        | LIST CHAINED ROWS into_clause1?\n        | DELETE SYSTEM? STATISTICS)\n    ;\n\npartition_extention_clause\n    : PARTITION (\n        '(' partition_name ')'\n        | FOR '(' partition_key_value (',' partition_key_value)* ')'\n    )\n    | SUBPARTITION (\n        '(' subpartition_name ')'\n        | FOR '(' subpartition_key_value (',' subpartition_key_value)* ')'\n    )\n    ;\n\nvalidation_clauses\n    : VALIDATE REF UPDATE (SET DANGLING TO NULL_)?\n    | VALIDATE STRUCTURE (CASCADE FAST | CASCADE online_or_offline? into_clause? | CASCADE)? online_or_offline? into_clause?\n    ;\n\ncompute_clauses\n    : COMPUTE SYSTEM? STATISTICS for_clause?\n    ;\n\nfor_clause\n    : FOR (\n        TABLE for_clause*\n        | ALL (INDEXED? COLUMNS (SIZE UNSIGNED_INTEGER)? for_clause* | LOCAL? INDEXES)\n        | COLUMNS (SIZE UNSIGNED_INTEGER)? (column_name SIZE UNSIGNED_INTEGER)+ for_clause*\n    )\n    ;\n\nonline_or_offline\n    : OFFLINE\n    | ONLINE\n    ;\n\ninto_clause1\n    : INTO tableview_name?\n    ;\n\n//Making assumption on partition ad subpartition key value clauses\npartition_key_value\n    : literal\n    | TIMESTAMP quoted_string\n    ;\n\nsubpartition_key_value\n    : literal\n    | TIMESTAMP quoted_string\n    ;\n\n//https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_4006.htm#SQLRF01106\nassociate_statistics\n    : ASSOCIATE STATISTICS WITH (column_association | function_association) storage_table_clause?\n    ;\n\ncolumn_association\n    : COLUMNS tableview_name '.' column_name (',' tableview_name '.' column_name)* using_statistics_type\n    ;\n\nfunction_association\n    : (\n        FUNCTIONS function_name (',' function_name)*\n        | PACKAGES package_name (',' package_name)*\n        | TYPES type_name (',' type_name)*\n        | INDEXES index_name (',' index_name)*\n        | INDEXTYPES indextype_name (',' indextype_name)*\n    ) (\n        using_statistics_type\n        | default_cost_clause (',' default_selectivity_clause)?\n        | default_selectivity_clause (',' default_cost_clause)?\n    )\n    ;\n\nindextype_name\n    : id_expression\n    ;\n\nusing_statistics_type\n    : USING (statistics_type_name | NULL_)\n    ;\n\nstatistics_type_name\n    : regular_id\n    ;\n\ndefault_cost_clause\n    : DEFAULT COST '(' cpu_cost ',' io_cost ',' network_cost ')'\n    ;\n\ncpu_cost\n    : UNSIGNED_INTEGER\n    ;\n\nio_cost\n    : UNSIGNED_INTEGER\n    ;\n\nnetwork_cost\n    : UNSIGNED_INTEGER\n    ;\n\ndefault_selectivity_clause\n    : DEFAULT SELECTIVITY default_selectivity\n    ;\n\ndefault_selectivity\n    : UNSIGNED_INTEGER\n    ;\n\nstorage_table_clause\n    : WITH (SYSTEM | USER) MANAGED STORAGE TABLES\n    ;\n\n// https://docs.oracle.com/database/121/SQLRF/statements_4008.htm#SQLRF56110\nunified_auditing\n    : {this.isVersion12()}? AUDIT (\n        POLICY policy_name ((BY | EXCEPT) audit_user (',' audit_user)*)? (WHENEVER NOT? SUCCESSFUL)?\n        | CONTEXT NAMESPACE oracle_namespace ATTRIBUTES attribute_name (',' attribute_name)* (\n            BY audit_user (',' audit_user)*\n        )?\n    )\n    ;\n\npolicy_name\n    : identifier\n    ;\n\n// https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_4007.htm#SQLRF01107\n// https://docs.oracle.com/database/121/SQLRF/statements_4007.htm#SQLRF01107\n\naudit_traditional\n    : AUDIT (\n        audit_operation_clause (auditing_by_clause | IN SESSION CURRENT)?\n        | audit_schema_object_clause\n        | NETWORK\n        | audit_direct_path\n    ) (BY (SESSION | ACCESS))? (WHENEVER NOT? SUCCESSFUL)? audit_container_clause?\n    ;\n\naudit_direct_path\n    : {this.isVersion12()}? DIRECT_PATH auditing_by_clause\n    ;\n\naudit_container_clause\n    : {this.isVersion12()}? (CONTAINER EQUALS_OP (CURRENT | ALL))\n    ;\n\naudit_operation_clause\n    : (\n        (sql_statement_shortcut | ALL STATEMENTS?) (',' (sql_statement_shortcut | ALL STATEMENTS?))*\n        | (system_privilege | ALL PRIVILEGES) (',' (system_privilege | ALL PRIVILEGES))*\n    )\n    ;\n\nauditing_by_clause\n    : BY audit_user (',' audit_user)*\n    ;\n\naudit_user\n    : regular_id\n    ;\n\naudit_schema_object_clause\n    : (sql_operation (',' sql_operation)* | ALL) auditing_on_clause\n    ;\n\nsql_operation\n    : ALTER\n    | AUDIT\n    | COMMENT\n    | DELETE\n    | EXECUTE\n    | FLASHBACK\n    | GRANT\n    | INDEX\n    | INSERT\n    | LOCK\n    | READ\n    | RENAME\n    | SELECT\n    | UPDATE\n    ;\n\nauditing_on_clause\n    : ON (\n        object_name\n        | DIRECTORY regular_id\n        | MINING MODEL model_name\n        | {this.isVersion12()}? SQL TRANSLATION PROFILE profile_name\n        | DEFAULT\n    )\n    ;\n\nmodel_name\n    : (id_expression '.')? id_expression\n    ;\n\nobject_name\n    : (id_expression '.')? id_expression\n    ;\n\nprofile_name\n    : (id_expression '.')? id_expression\n    ;\n\nsql_statement_shortcut\n    : ALTER SYSTEM\n    | CLUSTER\n    | CONTEXT\n    | DATABASE LINK\n    | DIMENSION\n    | DIRECTORY\n    | INDEX\n    | MATERIALIZED VIEW\n    | NOT EXISTS\n    | OUTLINE\n    | {this.isVersion12()}? PLUGGABLE DATABASE\n    | PROCEDURE\n    | PROFILE\n    | PUBLIC DATABASE LINK\n    | PUBLIC SYNONYM\n    | ROLE\n    | ROLLBACK SEGMENT\n    | SEQUENCE\n    | SESSION\n    | SYNONYM\n    | SYSTEM AUDIT\n    | SYSTEM GRANT\n    | TABLE\n    | TABLESPACE\n    | TRIGGER\n    | TYPE\n    | USER\n    | VIEW\n    | ALTER SEQUENCE\n    | ALTER TABLE\n    | COMMENT TABLE\n    | DELETE TABLE\n    | EXECUTE PROCEDURE\n    | GRANT DIRECTORY\n    | GRANT PROCEDURE\n    | GRANT SEQUENCE\n    | GRANT TABLE\n    | GRANT TYPE\n    | INSERT TABLE\n    | LOCK TABLE\n    | SELECT SEQUENCE\n    | SELECT TABLE\n    | UPDATE TABLE\n    ;\n\ndrop_index\n    : DROP INDEX index_name (IF EXISTS)?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DISASSOCIATE-STATISTICS.html\ndisassociate_statistics\n    : DISASSOCIATE STATISTICS FROM (\n        COLUMNS (schema_name '.')? tb = id_expression '.' c = id_expression (\n            ',' (schema_name '.')? tb = id_expression '.' c = id_expression\n        )*\n        | FUNCTIONS (schema_name '.')? fn = id_expression (\n            ',' (schema_name '.')? fn = id_expression\n        )*\n        | PACKAGES (schema_name '.')? pkg = id_expression (\n            ',' (schema_name '.')? pkg = id_expression\n        )*\n        | TYPES (schema_name '.')? t = id_expression (',' (schema_name '.')? t = id_expression)*\n        | INDEXES (schema_name '.')? ix = id_expression (',' (schema_name '.')? ix = id_expression)*\n        | INDEXTYPES (schema_name '.')? it = id_expression (\n            ',' (schema_name '.')? it = id_expression\n        )*\n    ) FORCE?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-INDEXTYPE.html\ndrop_indextype\n    : DROP INDEXTYPE (schema_name '.')? it = id_expression FORCE?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-INMEMORY-JOIN-GROUP.html\ndrop_inmemory_join_group\n    : DROP INMEMORY JOIN GROUP (schema_name '.')? jg = id_expression\n    ;\n\nflashback_table\n    : FLASHBACK TABLE tableview_name (',' tableview_name)* TO (\n        ((SCN | TIMESTAMP) expression | RESTORE POINT restore_point) ((ENABLE | DISABLE) TRIGGERS)?\n        | BEFORE DROP (RENAME TO tableview_name)?\n    )\n    ;\n\nrestore_point\n    : identifier ('.' id_expression)*\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/PURGE.html\npurge_statement\n    : PURGE (\n        (TABLE | INDEX) id_expression\n        | TABLESPACE SET? ts = id_expression (USER u = id_expression)?\n        | RECYCLEBIN\n        | DBA_RECYCLEBIN\n    )\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/NOAUDIT-Traditional-Auditing.html\nnoaudit_statement\n    : NOAUDIT (\n        audit_operation_clause auditing_by_clause?\n        | audit_schema_object_clause\n        | NETWORK\n        | DIRECT_PATH LOAD auditing_by_clause?\n    ) (WHENEVER NOT? SUCCESSFUL)? container_clause?\n    ;\n\nrename_object\n    : RENAME object_name TO object_name\n    ;\n\ngrant_statement\n    : GRANT (','? (role_name | system_privilege | object_privilege paren_column_list?))+ (\n        ON grant_object_name\n    )? TO (grantee_name | PUBLIC) (',' (grantee_name | PUBLIC))* (WITH (ADMIN | DELEGATE) OPTION)? (\n        WITH HIERARCHY OPTION\n    )? (WITH GRANT OPTION)? container_clause?\n    ;\n\ncontainer_clause\n    : CONTAINER EQUALS_OP (CURRENT | ALL)\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/REVOKE.html\nrevoke_statement\n    : REVOKE (\n        (revoke_system_privilege | revoke_object_privileges) container_clause?\n        | revoke_roles_from_programs\n    )\n    ;\n\nrevoke_system_privilege\n    : (system_privilege | role_name | ALL PRIVILEGES) FROM revokee_clause\n    ;\n\nrevokee_clause\n    : (id_expression | PUBLIC) (',' (id_expression | PUBLIC))*\n    ;\n\nrevoke_object_privileges\n    : (object_privilege | ALL PRIVILEGES?) (',' (object_privilege | ALL PRIVILEGES?))* on_object_clause FROM revokee_clause (\n        CASCADE CONSTRAINTS\n        | FORCE\n    )?\n    ;\n\non_object_clause\n    : ON (\n        (schema_name '.')? o = id_expression\n        | USER id_expression (',' id_expression)*\n        | DIRECTORY directory_name\n        | EDITION edition_name\n        | MINING MODEL (schema_name '.')? mmn = id_expression\n        | JAVA (SOURCE | RESOURCE) (schema_name '.')? o2 = id_expression\n        | SQL TRANSLATION PROFILE (schema_name '.')? p = id_expression\n    )\n    ;\n\nrevoke_roles_from_programs\n    : (role_name (',' role_name)* | ALL) FROM program_unit (',' program_unit)*\n    ;\n\nprogram_unit\n    : (FUNCTION | PROCEDURE | PACKAGE) (schema_name '.')? id_expression\n    ;\n\ncreate_dimension\n    : CREATE DIMENSION identifier level_clause+ (\n        hierarchy_clause\n        | attribute_clause\n        | extended_attribute_clause\n    )+\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-DIRECTORY.html\ncreate_directory\n    : CREATE (OR REPLACE)? DIRECTORY directory_name (SHARING '=' (METADATA | NONE))? AS directory_path\n    ;\n\ndirectory_name\n    : regular_id\n    ;\n\ndirectory_path\n    : CHAR_STRING\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-INMEMORY-JOIN-GROUP.html\ncreate_inmemory_join_group\n    : CREATE INMEMORY JOIN GROUP (schema_name '.')? jg = id_expression '(' (schema_name '.')? t = id_expression '(' c = id_expression ')' (\n        ',' (schema_name '.')? t = id_expression '(' c = id_expression ')'\n    )+ ')'\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-HIERARCHY.html\ndrop_hierarchy\n    : DROP HIERARCHY (schema_name '.')? hn = id_expression\n    ;\n\n// https://docs.oracle.com/cd/E11882_01/appdev.112/e25519/alter_library.htm#LNPLS99946\n// https://docs.oracle.com/database/121/LNPLS/alter_library.htm#LNPLS99946\nalter_library\n    : ALTER LIBRARY library_name (\n        COMPILE library_debug? compiler_parameters_clause* (REUSE SETTINGS)?\n        | library_editionable\n    )\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-JAVA.html\ndrop_java\n    : DROP JAVA (SOURCE | CLASS | RESOURCE) (schema_name '.')? id_expression\n    ;\n\ndrop_library\n    : DROP LIBRARY library_name\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-JAVA.html\ncreate_java\n    : CREATE (OR REPLACE)? (AND (RESOLVE | COMPILE))? NOFORCE? JAVA (\n        (SOURCE | RESOURCE) NAMED (schema_name '.')? pn = id_expression\n        | CLASS (SCHEMA id_expression)?\n    ) (SHARING '=' (METADATA | NONE))? invoker_rights_clause? (\n        RESOLVER '(' ('(' CHAR_STRING ','? (sn = id_expression | '-') ')')+ ')'\n    )? (\n        USING (\n            BFILE '(' d = id_expression ',' filename ')'\n            | (CLOB | BLOB | BFILE) subquery\n            | CHAR_STRING\n        )\n        | AS CHAR_STRING\n    )\n    ;\n\ncreate_library\n    : CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? LIBRARY plsql_library_source\n    ;\n\nplsql_library_source\n    : library_name (IS | AS) quoted_string (IN directory_name)? (AGENT quoted_string)? (\n        CREDENTIAL credential_name\n    )?\n    ;\n\ncredential_name\n    : (id_expression '.')? id_expression\n    ;\n\nlibrary_editionable\n    : {this.isVersion12()}? (EDITIONABLE | NONEDITIONABLE)\n    ;\n\nlibrary_debug\n    : {this.isVersion12()}? DEBUG\n    ;\n\ncompiler_parameters_clause\n    : parameter_name EQUALS_OP parameter_value\n    ;\n\nparameter_value\n    : regular_id\n    | CHAR_STRING\n    ;\n\nlibrary_name\n    : (regular_id '.')? regular_id\n    ;\n\nalter_dimension\n    : ALTER DIMENSION identifier (\n        (ADD (level_clause | hierarchy_clause | attribute_clause | extended_attribute_clause))+\n        | (\n            DROP (\n                LEVEL identifier (RESTRICT | CASCADE)?\n                | HIERARCHY identifier\n                | ATTRIBUTE identifier (\n                    LEVEL identifier (COLUMN column_name (',' COLUMN column_name)*)?\n                )?\n            )\n        )+\n        | COMPILE\n    )\n    ;\n\nlevel_clause\n    : LEVEL identifier IS (\n        table_name '.' column_name\n        | '(' table_name '.' column_name (',' table_name '.' column_name)* ')'\n    ) (SKIP_ WHEN NULL_)?\n    ;\n\nhierarchy_clause\n    : HIERARCHY identifier '(' identifier (CHILD OF identifier)+ dimension_join_clause? ')'\n    ;\n\ndimension_join_clause\n    : (JOIN KEY column_one_or_more_sub_clause REFERENCES identifier)+\n    ;\n\nattribute_clause\n    : (ATTRIBUTE identifier DETERMINES column_one_or_more_sub_clause)+\n    ;\n\nextended_attribute_clause\n    : ATTRIBUTE identifier (LEVEL identifier DETERMINES column_one_or_more_sub_clause)+\n    ;\n\ncolumn_one_or_more_sub_clause\n    : column_name\n    | '(' column_name (',' column_name)* ')'\n    ;\n\n// https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_4004.htm#SQLRF01104\n// https://docs.oracle.com/database/121/SQLRF/statements_4004.htm#SQLRF01104\nalter_view\n    : ALTER VIEW tableview_name (\n        ADD out_of_line_constraint\n        | MODIFY CONSTRAINT constraint_name (RELY | NORELY)\n        | DROP (\n            CONSTRAINT constraint_name\n            | PRIMARY KEY\n            | UNIQUE '(' column_name (',' column_name)* ')'\n        )\n        | COMPILE\n        | READ (ONLY | WRITE)\n        | alter_view_editionable?\n    )\n    ;\n\nalter_view_editionable\n    : {this.isVersion12()}? (EDITIONABLE | NONEDITIONABLE)\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-VIEW.html\ncreate_view\n    : CREATE (OR REPLACE)? (NO? FORCE)? editioning_clause? VIEW (schema_name '.')? v = id_expression (\n        IF NOT EXISTS\n    )? (SHARING '=' (METADATA | EXTENDED? DATA | NONE))? view_options? (\n        DEFAULT COLLATION cn = id_expression\n    )? (BEQUEATH (CURRENT_USER | DEFINER))? AS select_only_statement subquery_restriction_clause? (\n        CONTAINER_MAP\n        | CONTAINERS_DEFAULT\n    )?\n    ;\n\neditioning_clause\n    : EDITIONING\n    | EDITIONABLE EDITIONING?\n    | NONEDITIONABLE\n    ;\n\nview_options\n    : view_alias_constraint\n    | object_view_clause\n    | xmltype_view_clause\n    ;\n\nview_alias_constraint\n    : '(' (','? (table_alias inline_constraint* | out_of_line_constraint))+ ')'\n    ;\n\nobject_view_clause\n    : OF (schema_name '.')? tn = id_expression (\n        WITH OBJECT (IDENTIFIER | ID) (DEFAULT | '(' REGULAR_ID (',' REGULAR_ID)* ')')\n        | UNDER (schema_name '.')? sv = id_expression\n    ) ('(' (','? (out_of_line_constraint | REGULAR_ID inline_constraint))+ ')')*\n    ;\n\ninline_constraint\n    : (CONSTRAINT constraint_name)? (\n        NOT? NULL_\n        | UNIQUE\n        | PRIMARY KEY\n        | references_clause\n        | check_constraint\n    ) constraint_state?\n    ;\n\ninline_ref_constraint\n    : SCOPE IS tableview_name\n    | WITH ROWID\n    | (CONSTRAINT constraint_name)? references_clause constraint_state?\n    ;\n\nout_of_line_ref_constraint\n    : SCOPE FOR '(' ref_col_or_attr = regular_id ')' IS tableview_name\n    | REF '(' ref_col_or_attr = regular_id ')' WITH ROWID\n    | (CONSTRAINT constraint_name)? FOREIGN KEY '(' (','? ref_col_or_attr = regular_id)+ ')' references_clause constraint_state?\n    ;\n\nout_of_line_constraint\n    : (\n        ((CONSTRAINT | CONSTRAINTS) constraint_name)? (\n            UNIQUE '(' column_name (',' column_name)* ')'\n            | PRIMARY KEY '(' column_name (',' column_name)* ')'\n            | foreign_key_clause\n            | CHECK '(' condition ')'\n        )\n    )\n    constraint_state?\n    parallel_clause?\n    ;\n\nconstraint_state\n    : (\n        NOT? DEFERRABLE\n        | INITIALLY (IMMEDIATE | DEFERRED)\n        | (RELY | NORELY)\n        | (ENABLE | DISABLE)\n        | (VALIDATE | NOVALIDATE)\n        | using_index_clause\n    )+\n    ;\n\nxmltype_view_clause\n    : OF XMLTYPE xml_schema_spec? WITH OBJECT (IDENTIFIER | ID) (\n        DEFAULT\n        | '(' expression (',' expression)* ')'\n    )\n    ;\n\nxml_schema_spec\n    : (XMLSCHEMA xml_schema_url)? ELEMENT (element | xml_schema_url '#' element) (\n        STORE ALL VARRAYS AS (LOBS | TABLES)\n    )? (allow_or_disallow NONSCHEMA)? (allow_or_disallow ANYSCHEMA)?\n    ;\n\nxml_schema_url\n    : DELIMITED_ID\n    ;\n\nelement\n    : DELIMITED_ID\n    ;\n\nalter_tablespace\n    : ALTER TABLESPACE tablespace (\n        DEFAULT table_compression? storage_clause?\n        | MINIMUM EXTENT size_clause\n        | RESIZE size_clause\n        | COALESCE\n        | SHRINK SPACE_KEYWORD (KEEP size_clause)?\n        | RENAME TO new_tablespace_name\n        | begin_or_end BACKUP\n        | datafile_tempfile_clauses\n        | tablespace_logging_clauses\n        | tablespace_group_clause\n        | tablespace_state_clauses\n        | autoextend_clause\n        | flashback_mode_clause\n        | tablespace_retention_clause\n    )\n    ;\n\ndatafile_tempfile_clauses\n    : ADD (datafile_specification | tempfile_specification)\n    | DROP (DATAFILE | TEMPFILE) (filename | UNSIGNED_INTEGER) (KEEP size_clause)?\n    | SHRINK TEMPFILE (filename | UNSIGNED_INTEGER) (KEEP size_clause)?\n    | RENAME DATAFILE filename (',' filename)* TO filename (',' filename)*\n    | (DATAFILE | TEMPFILE) (online_or_offline)\n    ;\n\ntablespace_logging_clauses\n    : logging_clause\n    | NO? FORCE LOGGING\n    ;\n\ntablespace_group_clause\n    : TABLESPACE GROUP (tablespace_group_name | CHAR_STRING)\n    ;\n\ntablespace_group_name\n    : regular_id\n    ;\n\ntablespace_state_clauses\n    : ONLINE\n    | OFFLINE (NORMAL | TEMPORARY | IMMEDIATE)?\n    | READ (ONLY | WRITE)\n    | PERMANENT\n    | TEMPORARY\n    ;\n\nflashback_mode_clause\n    : FLASHBACK (ON | OFF)\n    ;\n\nnew_tablespace_name\n    : tablespace\n    ;\n\ncreate_tablespace\n    : CREATE (BIGFILE | SMALLFILE)? (\n        permanent_tablespace_clause\n        | temporary_tablespace_clause\n        | undo_tablespace_clause\n    )\n    ;\n\npermanent_tablespace_clause\n    : TABLESPACE id_expression (IF NOT EXISTS)? datafile_specification? (\n        MINIMUM EXTENT size_clause\n        | BLOCKSIZE size_clause\n        | logging_clause\n        | FORCE LOGGING\n        | (ONLINE | OFFLINE)\n        | ENCRYPTION tablespace_encryption_spec\n        | DEFAULT //TODO table_compression? storage_clause?\n        | extent_management_clause\n        | segment_management_clause\n        | flashback_mode_clause\n    )*\n    ;\n\ntablespace_encryption_spec\n    : USING encrypt_algorithm = CHAR_STRING\n    ;\n\nlogging_clause\n    : LOGGING\n    | NOLOGGING\n    | FILESYSTEM_LIKE_LOGGING\n    ;\n\nextent_management_clause\n    : EXTENT MANAGEMENT LOCAL (AUTOALLOCATE | UNIFORM (SIZE size_clause)?)?\n    ;\n\nsegment_management_clause\n    : SEGMENT SPACE_KEYWORD MANAGEMENT (AUTO | MANUAL)\n    ;\n\ntemporary_tablespace_clause\n    : TEMPORARY TABLESPACE tablespace_name = id_expression (IF NOT EXISTS)? tempfile_specification? tablespace_group_clause? extent_management_clause?\n    ;\n\nundo_tablespace_clause\n    : UNDO TABLESPACE tablespace_name = id_expression (IF NOT EXISTS)? datafile_specification? extent_management_clause? tablespace_retention_clause?\n    ;\n\ntablespace_retention_clause\n    : RETENTION (GUARANTEE | NOGUARANTEE)\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-TABLESPACE-SET.html\ncreate_tablespace_set\n    : CREATE TABLESPACE SET tss = id_expression (IN SHARDSPACE ss = id_expression)? (\n        USING TEMPLATE '(' (DATAFILE file_specification (',' file_specification)*)? permanent_tablespace_attrs+ ')'\n    )?\n    ;\n\npermanent_tablespace_attrs\n    : MINIMUM EXTENT size_clause\n    | BLOCKSIZE numeric K_LETTER?\n    | logging_clause\n    | FORCE LOGGING\n    | tablespace_encryption_clause\n    | default_tablespace_params\n    | ONLINE\n    | OFFLINE\n    | extent_management_clause\n    | segment_management_clause\n    | flashback_mode_clause\n    | lost_write_protection\n    ;\n\ntablespace_encryption_clause\n    : ENCRYPTION (tablespace_encryption_spec? ENCRYPT | DECRYPT)\n    ;\n\ndefault_tablespace_params\n    : DEFAULT default_table_compression? default_index_compression? inmmemory_clause? ilm_clause? storage_clause?\n    ;\n\ndefault_table_compression\n    : TABLE (COMPRESS FOR (OLTP | QUERY low_high | ARCHIVE low_high) | NOCOMPRESS)\n    ;\n\nlow_high\n    : LOW\n    | HIGH\n    ;\n\ndefault_index_compression\n    : INDEX (COMPRESS ADVANCED low_high | NOCOMPRESS)\n    ;\n\ninmmemory_clause\n    : INMEMORY inmemory_attributes? (\n        TEXT (\n            column_name (',' column_name)*\n            | column_name USING policy_name (',' column_name USING policy_name)*\n        )\n    )?\n    | NO INMEMORY\n    ;\n\n// asm_filename is just a charater string.  Would need to parse the string\n// to find diskgroup...\ndatafile_specification\n    : DATAFILE (','? datafile_tempfile_spec)\n    ;\n\ntempfile_specification\n    : TEMPFILE (','? datafile_tempfile_spec)\n    ;\n\ndatafile_tempfile_spec\n    : CHAR_STRING? (SIZE size_clause)? REUSE? autoextend_clause?\n    ;\n\nredo_log_file_spec\n    : (filename | '(' filename (',' filename)* ')') (SIZE size_clause)? (BLOCKSIZE size_clause)? REUSE?\n    ;\n\nautoextend_clause\n    : AUTOEXTEND (OFF | ON (NEXT size_clause)? maxsize_clause?)\n    ;\n\nmaxsize_clause\n    : MAXSIZE (UNLIMITED | size_clause)\n    ;\n\nbuild_clause\n    : BUILD (IMMEDIATE | DEFERRED)\n    ;\n\nparallel_clause\n    : NOPARALLEL\n    | PARALLEL (\n        parallel_count = UNSIGNED_INTEGER parallel_instances_clause?\n        // Deprecated, legacy format from Oracle 8 and prior, and while this is no longer documented,\n        // the DEGREE syntax continues to be accepted by the database engine.\n        | '(' DEGREE parallel_count = UNSIGNED_INTEGER parallel_instances_clause? ')'\n    )?\n    ;\n\n// This is Oracle RAC specific.\n// In modern Oracle, parallelism is controlled by the database initialization parameter PARALLEL_DEGREE_POLICY,\n// however, the database continues to accept and record this SQL syntax if its used.\nparallel_instances_clause\n    : INSTANCES (UNSIGNED_INTEGER | DEFAULT)\n    ;\n\nalter_materialized_view\n    : ALTER MATERIALIZED VIEW tableview_name (\n        physical_attributes_clause\n        | modify_mv_column_clause\n        | table_compression\n        | lob_storage_clause (',' lob_storage_clause)*\n        | modify_lob_storage_clause (',' modify_lob_storage_clause)*\n        //TODO | alter_table_partitioning\n        | parallel_clause\n        | logging_clause\n        | allocate_extent_clause\n        | deallocate_unused_clause\n        | shrink_clause\n        | (cache_or_nocache)\n    )? alter_iot_clauses? (USING INDEX physical_attributes_clause)? alter_mv_option1? (\n        enable_or_disable QUERY REWRITE\n        | COMPILE\n        | CONSIDER FRESH\n    )?\n    ;\n\nalter_mv_option1\n    : alter_mv_refresh\n    //TODO  | MODIFY scoped_table_ref_constraint\n    ;\n\nalter_mv_refresh\n    : REFRESH (\n        FAST\n        | COMPLETE\n        | FORCE\n        | ON (DEMAND | COMMIT)\n        | START WITH expression\n        | NEXT expression\n        | WITH PRIMARY KEY\n        | USING DEFAULT? MASTER ROLLBACK SEGMENT rollback_segment?\n        | USING (ENFORCED | TRUSTED) CONSTRAINTS\n    )+\n    ;\n\nrollback_segment\n    : regular_id\n    ;\n\nmodify_mv_column_clause\n    : MODIFY '(' column_name (ENCRYPT encryption_spec | DECRYPT)? ')'\n    ;\n\nalter_materialized_view_log\n    : ALTER MATERIALIZED VIEW LOG FORCE? ON tableview_name (\n        physical_attributes_clause\n        | add_mv_log_column_clause\n        //TODO | alter_table_partitioning\n        | parallel_clause\n        | logging_clause\n        | allocate_extent_clause\n        | shrink_clause\n        | move_mv_log_clause\n        | cache_or_nocache\n    )? mv_log_augmentation? mv_log_purge_clause?\n    ;\n\nadd_mv_log_column_clause\n    : ADD '(' column_name ')'\n    ;\n\nmove_mv_log_clause\n    : MOVE segment_attributes_clause parallel_clause?\n    ;\n\nmv_log_augmentation\n    : ADD (\n        (OBJECT ID | PRIMARY KEY | ROWID | SEQUENCE) ('(' column_name (',' column_name)* ')')?\n        | '(' column_name (',' column_name)* ')'\n    ) new_values_clause?\n    ;\n\ncreate_materialized_view_log\n    : CREATE MATERIALIZED VIEW LOG ON tableview_name (\n        (\n            physical_attributes_clause\n            | TABLESPACE tablespace_name = id_expression\n            | logging_clause\n            | (CACHE | NOCACHE)\n        )+\n    )? parallel_clause?\n    // table_partitioning_clauses TODO\n    (\n        WITH (','? ( OBJECT ID | PRIMARY KEY | ROWID | SEQUENCE | COMMIT SCN))* (\n            '(' ( ','? regular_id)+ ')' new_values_clause?\n        )? mv_log_purge_clause?\n    )*\n    ;\n\nnew_values_clause\n    : (INCLUDING | EXCLUDING) NEW VALUES\n    ;\n\nmv_log_purge_clause\n    : PURGE (\n        IMMEDIATE (SYNCHRONOUS | ASYNCHRONOUS)?\n        // |START WITH CLAUSES TODO\n    )\n    ;\n\ncreate_materialized_zonemap\n    : CREATE MATERIALIZED ZONEMAP zonemap_name (LEFT_PAREN column_list RIGHT_PAREN)? zonemap_attributes? zonemap_refresh_clause? (\n        (ENABLE | DISABLE) PRUNING\n    )? (create_zonemap_on_table | create_zonemap_as_subquery)\n    ;\n\nalter_materialized_zonemap\n    : ALTER MATERIALIZED ZONEMAP zonemap_name (\n        zonemap_attributes\n        | zonemap_refresh_clause\n        | (ENABLE | DISABLE) PRUNING\n        | COMPILE\n        | REBUILD\n        | UNUSABLE\n    )\n    ;\n\ndrop_materialized_zonemap\n    : DROP MATERIALIZED ZONEMAP zonemap_name\n    ;\n\nzonemap_refresh_clause\n    : REFRESH (FAST | COMPILE | FORCE)? (\n        ON (DEMAND | COMMIT | LOAD | DATA MOVEMENT | LOAD DATA MOVEMENT)\n    )?\n    ;\n\nzonemap_attributes\n    : (\n        PCTFREE numeric\n        | PCTUSED numeric\n        | SCALE numeric\n        | TABLESPACE tablespace\n        | (CACHE | NOCACHE)\n    )+\n    ;\n\nzonemap_name\n    : identifier ('.' id_expression)?\n    ;\n\noperator_name\n    : identifier ('.' id_expression)?\n    ;\n\noperator_function_name\n    : identifier ('.' id_expression)*\n    ;\n\ncreate_zonemap_on_table\n    : ON tableview_name LEFT_PAREN column_list RIGHT_PAREN\n    ;\n\ncreate_zonemap_as_subquery\n    : AS subquery\n    ;\n\nalter_operator\n    : ALTER OPERATOR operator_name (add_binding_clause | drop_binding_clause | COMPILE)\n    ;\n\ndrop_operator\n    : DROP OPERATOR operator_name FORCE?\n    ;\n\ncreate_operator\n    : CREATE (OR REPLACE)? OPERATOR operator_name BINDING binding_clause (COMMA binding_clause)* (\n        SHARING '=' (METADATA | NONE)\n    )?\n    ;\n\nbinding_clause\n    : LEFT_PAREN datatype (COMMA datatype)* RIGHT_PAREN RETURN LEFT_PAREN? datatype RIGHT_PAREN? implementation_clause? using_function_clause\n    ;\n\nadd_binding_clause\n    : ADD BINDING binding_clause\n    ;\n\nimplementation_clause\n    : ANCILLARY TO primary_operator_list\n    | operator_context_clause\n    ;\n\nprimary_operator_list\n    : primary_operator_item (COMMA primary_operator_item)*\n    ;\n\nprimary_operator_item\n    : schema_object_name LEFT_PAREN datatype (COMMA datatype)* RIGHT_PAREN\n    ;\n\noperator_context_clause\n    : WITH INDEX CONTEXT COMMA SCAN CONTEXT implementation_type_name (COMPUTE ANCILLARY DATA)? (\n        WITH COLUMN CONTEXT\n    )?\n    ;\n\nusing_function_clause\n    : USING operator_function_name\n    ;\n\ndrop_binding_clause\n    : DROP BINDING LEFT_PAREN datatype (COMMA datatype)* RIGHT_PAREN FORCE?\n    ;\n\ncreate_materialized_view\n    : CREATE MATERIALIZED VIEW tableview_name (OF type_name)? (\n        '(' (scoped_table_ref_constraint | mv_column_alias) (\n            ',' (scoped_table_ref_constraint | mv_column_alias)\n        )* ')'\n    )? (\n        ON PREBUILT TABLE ( (WITH | WITHOUT) REDUCED PRECISION)?\n        | physical_properties? (CACHE | NOCACHE)? parallel_clause? build_clause?\n    ) (\n        USING INDEX ((physical_attributes_clause | TABLESPACE mv_tablespace = id_expression)+)*\n        | USING NO INDEX\n    )? create_mv_refresh? (FOR UPDATE)? ((DISABLE | ENABLE) QUERY REWRITE)? AS select_only_statement\n    ;\n\nscoped_table_ref_constraint\n    : SCOPE FOR '(' ref_column_or_attribute = identifier ')' IS (schema_name '.')? scope_table_name_or_c_alias = identifier\n    ;\n\nmv_column_alias\n    : (identifier | quoted_string) (ENCRYPT encryption_spec)?\n    ;\n\ncreate_mv_refresh\n    : (\n        NEVER REFRESH\n        | REFRESH (\n            (FAST | COMPLETE | FORCE)\n            | ON (DEMAND | COMMIT)\n            | (START WITH | NEXT) //date goes here TODO\n            | WITH (PRIMARY KEY | ROWID)\n            | USING (\n                DEFAULT (MASTER | LOCAL)? ROLLBACK SEGMENT\n                | (MASTER | LOCAL)? ROLLBACK SEGMENT rb_segment = REGULAR_ID\n            )\n            | USING (ENFORCED | TRUSTED) CONSTRAINTS\n        )+\n    )\n    ;\n\ndrop_materialized_view\n    : DROP MATERIALIZED VIEW tableview_name (PRESERVE TABLE)?\n    ;\n\ndrop_materialized_view_log\n    : DROP MATERIALIZED VIEW LOG (IF EXISTS)? ON tableview_name\n    ;\n\ncreate_context\n    : CREATE (OR REPLACE)? CONTEXT oracle_namespace USING (schema_object_name '.')? package_name (\n        INITIALIZED (EXTERNALLY | GLOBALLY)\n        | ACCESSED GLOBALLY\n    )?\n    ;\n\noracle_namespace\n    : id_expression\n    ;\n\n//https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_5001.htm#SQLRF01201\ncreate_cluster\n    : CREATE CLUSTER cluster_name '(' column_name datatype SORT? (',' column_name datatype SORT?)* ')' (\n        physical_attributes_clause\n        | SIZE size_clause\n        | TABLESPACE tablespace\n        | INDEX\n        | (SINGLE TABLE)? HASHKEYS UNSIGNED_INTEGER (HASH IS expression)?\n    )* parallel_clause? (ROWDEPENDENCIES | NOROWDEPENDENCIES)? (CACHE | NOCACHE)?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-PROFILE.html\ncreate_profile\n    : CREATE MANDATORY? PROFILE p = id_expression LIMIT (resource_parameters | password_parameters)+ container_clause?\n    ;\n\nresource_parameters\n    : (\n        SESSIONS_PER_USER\n        | CPU_PER_SESSION\n        | CPU_PER_CALL\n        | CONNECT_TIME\n        | IDLE_TIME\n        | LOGICAL_READS_PER_SESSION\n        | LOGICAL_READS_PER_CALL\n        | COMPOSITE_LIMIT\n    ) (UNSIGNED_INTEGER | UNLIMITED | DEFAULT)\n    | PRIVATE_SGA (size_clause | UNLIMITED | DEFAULT)\n    ;\n\npassword_parameters\n    : (\n        FAILED_LOGIN_ATTEMPTS\n        | PASSWORD_LIFE_TIME\n        | PASSWORD_REUSE_TIME\n        | PASSWORD_REUSE_MAX\n        | PASSWORD_LOCK_TIME\n        | PASSWORD_GRACE_TIME\n        | INACTIVE_ACCOUNT_TIME\n    ) (expression | UNLIMITED | DEFAULT)\n    | PASSWORD_VERIFY_FUNCTION (function_name | NULL_ | DEFAULT)\n    | PASSWORD_ROLLOVER_TIME (expression | DEFAULT)\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-LOCKDOWN-PROFILE.html\ncreate_lockdown_profile\n    : CREATE LOCKDOWN PROFILE id_expression (static_base_profile | dynamic_base_profile)?\n    ;\n\nstatic_base_profile\n    : FROM bp = id_expression\n    ;\n\ndynamic_base_profile\n    : INCLUDING bp = id_expression\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-OUTLINE.html\ncreate_outline\n    : CREATE (OR REPLACE)? (PUBLIC | PRIVATE)? OUTLINE (o = id_expression)? (\n        FROM (PUBLIC | PRIVATE)? so = id_expression\n    )? (FOR CATEGORY c = id_expression)? (ON statement)?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-RESTORE-POINT.html\ncreate_restore_point\n    : CREATE CLEAN? RESTORE POINT rp = id_expression (FOR PLUGGABLE DATABASE pdb = id_expression)? (\n        AS OF (TIMESTAMP | SCN) expression\n    )? (PRESERVE | GUARANTEE FLASHBACK DATABASE)?\n    ;\n\ncreate_role\n    : CREATE ROLE role_name role_identified_clause? container_clause?\n    ;\n\ncreate_table\n    : CREATE (\n        (GLOBAL | PRIVATE) TEMPORARY\n        | SHARDED\n        | DUPLICATED\n        | IMMUTABLE? BLOCKCHAIN\n        | IMMUTABLE\n    )? TABLE (schema_name '.')? table_name (IF NOT EXISTS)? (\n        SHARING '=' (METADATA | EXTENDED? DATA | NONE)\n    )? (relational_table | xmltype_table | object_table) memoptimize_read_write_clause? (\n        PARENT tableview_name\n    )? (USAGE QUEUE)?\n    ;\n\nxmltype_table\n    : OF XMLTYPE ('(' object_properties ')')? (XMLTYPE xmltype_storage)? xmlschema_spec? xmltype_virtual_columns? (\n        ON COMMIT (DELETE | PRESERVE) ROWS\n    )? oid_clause? oid_index_clause? physical_properties? table_properties?\n    ;\n\nxmltype_virtual_columns\n    : VIRTUAL COLUMNS '(' column_name AS '(' expression ')' (',' column_name AS '(' expression ')')* ')'\n    ;\n\nxmltype_column_properties\n    : XMLTYPE COLUMN? column_name xmltype_storage? xmlschema_spec?\n    ;\n\nxmltype_storage\n    : STORE AS (\n        OBJECT RELATIONAL\n        | (SECUREFILE | BASICFILE)? (CLOB | BINARY XML) (\n            lob_segname ('(' lob_parameters ')')?\n            | '(' lob_parameters ')'\n        )?\n    )\n    | STORE VARRAYS AS (LOBS | TABLES)\n    ;\n\nxmlschema_spec\n    : (XMLSCHEMA DELIMITED_ID)? ELEMENT DELIMITED_ID (allow_or_disallow NONSCHEMA)? (\n        allow_or_disallow ANYSCHEMA\n    )?\n    ;\n\nobject_table\n    : OF (schema_name '.')? object_type object_table_substitution? (\n        '(' object_properties (',' object_properties)* ')'\n    )? (ON COMMIT (DELETE | PRESERVE) ROWS)? oid_clause? oid_index_clause? physical_properties? table_properties?\n    ;\n\nobject_type\n    : regular_id\n    ;\n\noid_index_clause\n    : OIDINDEX index_name? '(' (physical_attributes_clause | TABLESPACE tablespace)+ ')'\n    ;\n\noid_clause\n    : OBJECT IDENTIFIER IS (SYSTEM GENERATED | PRIMARY KEY)\n    ;\n\nobject_properties\n    : (column_name | attribute_name) (DEFAULT expression)? (\n        inline_constraint (',' inline_constraint)*\n        | inline_ref_constraint\n    )?\n    | out_of_line_constraint\n    | out_of_line_ref_constraint\n    | supplemental_logging_props\n    ;\n\nobject_table_substitution\n    : NOT? SUBSTITUTABLE AT ALL LEVELS\n    ;\n\nrelational_table\n    : ('(' relational_property (',' relational_property)* ')')? relational_table_properties?\n    ;\n\nrelational_table_properties\n    : relational_table_property+\n    ;\n\nrelational_table_property\n    : immutable_table_clauses\n    | blockchain_table_clauses\n    | DEFAULT COLLATION collation_name\n    | ON COMMIT ((DROP | PRESERVE) DEFINITION | (DELETE | PRESERVE) ROWS)\n    | physical_properties\n    | table_properties\n    ;\n\nimmutable_table_clauses\n    : immutable_table_no_drop_clause\n    | immutable_table_no_delete_clause\n    ;\n\nimmutable_table_no_drop_clause\n    : NO DROP (UNTIL numeric DAYS IDLE)?\n    ;\n\nimmutable_table_no_delete_clause\n    : NO DELETE (LOCKED? | UNTIL numeric DAYS AFTER INSERT LOCKED?)\n    ;\n\nblockchain_table_clauses\n    : blockchain_drop_table_clause blockchain_row_retention_clause blockchain_hash_and_data_format_clause\n    ;\n\nblockchain_drop_table_clause\n    : NO DROP (UNTIL numeric DAYS IDLE)?\n    ;\n\nblockchain_row_retention_clause\n    : NO DELETE (LOCKED? | UNTIL numeric DAYS AFTER INSERT LOCKED?)\n    ;\n\nblockchain_hash_and_data_format_clause\n    : HASHING USING SHA2_512_Q VERSION V1_Q\n    ;\n\ncollation_name\n    : identifier\n    ;\n\n// While Oracle's documented grammar defines an explicit order of clauses, in practice these clauses can\n// be specified in any order. This rule is designed to follow the grammar intent, and so semantic checks\n// should exist in the listeners to deal with concepts such as duplicates.\ntable_properties\n    : column_properties\n    | read_only_clause\n    | indexing_clause\n    | table_partitioning_clauses\n    | attribute_clustering_clause\n    | (CACHE | NOCACHE)\n    | result_cache_clause\n    | parallel_clause\n    | monitoring_nomonitoring\n    | (ROWDEPENDENCIES | NOROWDEPENDENCIES)\n    | enable_disable_clause\n    | row_movement_clause\n    | logical_replication_clause\n    | flashback_archive_clause\n    | physical_properties\n    | ROW ARCHIVAL\n    | AS select_only_statement\n    | FOR EXCHANGE WITH TABLE (schema_name '.')? table_name\n    | annotations_clause\n    ;\n\nread_only_clause\n    : READ (ONLY | WRITE)\n    ;\n\nindexing_clause\n    : INDEXING (ON | OFF)\n    ;\n\nattribute_clustering_clause\n    : CLUSTERING clustering_join? cluster_clause (yes_no? ON LOAD)? (yes_no? ON DATA MOVEMENT)? zonemap_clause?\n    ;\n\nclustering_join\n    : (schema_name '.')? table_name clustering_join_item (',' clustering_join_item)*\n    ;\n\nclustering_join_item\n    : JOIN (schema_name '.')? table_name ON '(' equijoin_condition ')'\n    ;\n\nequijoin_condition\n    : expression\n    ;\n\ncluster_clause\n    : BY (LINEAR | INTERLEAVED)? ORDER clustering_columns\n    ;\n\nclustering_columns\n    : clustering_column_group\n    | '(' clustering_column_group (',' clustering_column_group)* ')'\n    ;\n\nclustering_column_group\n    : '(' column_name (',' column_name)* ')'\n    ;\n\nyes_no\n    : YES\n    | NO\n    ;\n\nzonemap_clause\n    : WITH MATERIALIZED ZONEMAP ('(' zonemap_name ')')?\n    | WITHOUT MATERIALIZED ZONEMAP\n    ;\n\nlogical_replication_clause\n    : DISABLE LOGICAL REPLICATION\n    | ENABLE LOGICAL REPLICATION (\n        (ALL | ALLOW NOVALIDATE) KEYS\n        | NO? PARTIAL JSON\n    )?\n    ;\n\ntable_name\n    : identifier\n    ;\n\nrelational_property\n    : out_of_line_constraint\n    | out_of_line_ref_constraint\n    | column_definition\n    | virtual_column_definition\n    | period_definition\n    | supplemental_logging_props\n    ;\n\ntable_partitioning_clauses\n    : range_partitions\n    | list_partitions\n    | hash_partitions\n    | composite_range_partitions\n    | composite_list_partitions\n    | composite_hash_partitions\n    | reference_partitioning\n    | system_partitioning\n    ;\n\nrange_partitions\n    : PARTITION BY RANGE '(' column_name (',' column_name)* ')' (\n        INTERVAL '(' expression ')' (STORE IN '(' tablespace (',' tablespace)* ')')?\n    )? '(' PARTITION partition_name? range_values_clause table_partition_description (\n        ',' PARTITION partition_name? range_values_clause table_partition_description\n    )* ')'\n    ;\n\nlist_partitions\n    : PARTITION BY LIST '(' column_name ')' (\n        AUTOMATIC (STORE IN '(' tablespace (',' tablespace)* ')')?\n    )? (\n        '(' PARTITION partition_name? list_values_clause table_partition_description (\n            ',' PARTITION partition_name? list_values_clause table_partition_description\n        )* ')'\n    )?\n    ;\n\nhash_partitions\n    : PARTITION BY HASH '(' column_name (',' column_name)* ')' (\n        individual_hash_partitions\n        | hash_partitions_by_quantity\n    )\n    ;\n\nindividual_hash_partitions\n    : '(' PARTITION partition_name? partitioning_storage_clause? (\n        ',' PARTITION partition_name? partitioning_storage_clause?\n    )* ')'\n    ;\n\nhash_partitions_by_quantity\n    : PARTITIONS hash_partition_quantity (STORE IN '(' tablespace (',' tablespace)* ')')? (\n        table_compression\n        | key_compression\n    )? (OVERFLOW_ STORE IN '(' tablespace (',' tablespace)* ')')?\n    ;\n\nhash_partition_quantity\n    : UNSIGNED_INTEGER\n    ;\n\ncomposite_range_partitions\n    : PARTITION BY RANGE '(' column_name (',' column_name)* ')' (\n        INTERVAL '(' expression ')' (STORE IN '(' tablespace (',' tablespace)* ')')?\n    )? (subpartition_by_range | subpartition_by_list | subpartition_by_hash) '(' range_partition_desc (\n        ',' range_partition_desc\n    )* ')'\n    ;\n\ncomposite_list_partitions\n    : PARTITION BY LIST '(' column_name ')' (\n        subpartition_by_range\n        | subpartition_by_list\n        | subpartition_by_hash\n    ) '(' list_partition_desc (',' list_partition_desc)* ')'\n    ;\n\ncomposite_hash_partitions\n    : PARTITION BY HASH '(' (',' column_name)+ ')' (\n        subpartition_by_range\n        | subpartition_by_list\n        | subpartition_by_hash\n    ) (individual_hash_partitions | hash_partitions_by_quantity)\n    ;\n\nreference_partitioning\n    : PARTITION BY REFERENCE '(' constraint_name ')' (\n        '(' reference_partition_desc (',' reference_partition_desc)* ')'\n    )?\n    ;\n\nreference_partition_desc\n    : PARTITION partition_name? table_partition_description\n    ;\n\nsystem_partitioning\n    : PARTITION BY SYSTEM (\n        PARTITIONS UNSIGNED_INTEGER\n        | reference_partition_desc (',' reference_partition_desc)*\n    )?\n    ;\n\nrange_partition_desc\n    : PARTITION partition_name? range_values_clause? table_partition_description (\n        (\n            '(' (\n                range_subpartition_desc (',' range_subpartition_desc)*\n                | list_subpartition_desc (',' list_subpartition_desc)*\n                | individual_hash_subparts (',' individual_hash_subparts)*\n            ) ')'\n            | hash_subparts_by_quantity\n        )\n    )?\n    ;\n\nlist_partition_desc\n    : PARTITION partition_name? list_values_clause? table_partition_description (\n        (\n            '(' (\n                range_subpartition_desc (',' range_subpartition_desc)*\n                | list_subpartition_desc (',' list_subpartition_desc)*\n                | individual_hash_subparts (',' individual_hash_subparts)*\n            ) ')'\n            | hash_subparts_by_quantity\n        )\n    )?\n    ;\n\nsubpartition_template\n    : SUBPARTITION TEMPLATE (\n        (\n            '(' (\n                range_subpartition_desc (',' range_subpartition_desc)*\n                | list_subpartition_desc (',' list_subpartition_desc)*\n                | individual_hash_subparts (',' individual_hash_subparts)*\n            ) ')'\n            | hash_subpartition_quantity\n        )\n    )\n    ;\n\nhash_subpartition_quantity\n    : UNSIGNED_INTEGER\n    ;\n\nsubpartition_by_range\n    : SUBPARTITION BY RANGE '(' column_name (',' column_name)* ')' subpartition_template?\n    ;\n\nsubpartition_by_list\n    : SUBPARTITION BY LIST '(' column_name ')' subpartition_template?\n    ;\n\nsubpartition_by_hash\n    : SUBPARTITION BY HASH '(' column_name (',' column_name)* ')' (\n        SUBPARTITIONS UNSIGNED_INTEGER (STORE IN '(' tablespace (',' tablespace)* ')')?\n        | subpartition_template\n    )?\n    ;\n\nsubpartition_name\n    : partition_name\n    ;\n\nrange_subpartition_desc\n    : SUBPARTITION subpartition_name? range_values_clause partitioning_storage_clause?\n    ;\n\nlist_subpartition_desc\n    : SUBPARTITION subpartition_name? list_values_clause partitioning_storage_clause?\n    ;\n\nindividual_hash_subparts\n    : SUBPARTITION subpartition_name? partitioning_storage_clause?\n    ;\n\nhash_subparts_by_quantity\n    : SUBPARTITIONS UNSIGNED_INTEGER (STORE IN '(' tablespace (',' tablespace)* ')')?\n    ;\n\nrange_values_clause\n    : VALUES LESS THAN '(' range_values_list ')'\n    ;\n\nrange_values_list\n    : literal (',' literal)*\n    | TIMESTAMP literal (',' TIMESTAMP literal)*\n    ;\n\nlist_values_clause\n    : VALUES '(' (literal (',' literal)* | TIMESTAMP literal (',' TIMESTAMP literal)* | DEFAULT) ')'\n    ;\n\ntable_partition_description\n    : (INTERNAL | EXTERNAL)? deferred_segment_creation? read_only_clause? indexing_clause? segment_attributes_clause? (\n        table_compression\n        | key_compression\n    )? inmemory_table_clause? ilm_clause? (\n        OVERFLOW_ segment_attributes_clause?\n    )? (lob_storage_clause | varray_col_properties | nested_table_col_properties)*\n    ;\n\npartitioning_storage_clause\n    : (\n        TABLESPACE tablespace\n        | OVERFLOW_ (TABLESPACE tablespace)?\n        | table_compression\n        | key_compression\n        | inmemory_table_clause\n        | lob_partitioning_storage\n        | VARRAY varray_item STORE AS (BASICFILE | SECUREFILE)? LOB lob_segname\n    )+\n    ;\n\nlob_partitioning_storage\n    : LOB '(' lob_item ')' STORE AS (BASICFILE | SECUREFILE)? (\n        lob_segname ('(' TABLESPACE tablespace ')')?\n        | '(' TABLESPACE tablespace ')'\n    )\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/size_clause.html\n// Technically, this should only allow 'K' | 'M' | 'G' | 'T' | 'P' | 'E'\n// but having issues with examples/numbers01.sql line 11 \"sysdate -1m\"\nsize_clause\n    : UNSIGNED_INTEGER (K_LETTER | M_LETTER | G_LETTER | T_LETTER | P_LETTER | E_LETTER)?\n    ;\n\ntable_compression\n    : COMPRESS (\n        BASIC\n        | FOR (\n            OLTP\n            | (QUERY | ARCHIVE) (LOW | HIGH)?\n            | ALL OPERATIONS\n            | DIRECT_LOAD OPERATIONS\n        )\n    )?\n    | ROW STORE COMPRESS (BASIC | ADVANCED)?\n    | COLUMN STORE COMPRESS (FOR (QUERY | ARCHIVE) (LOW | HIGH)?)? (NO? ROW LEVEL LOCKING)?\n    | NOCOMPRESS\n    ;\n\n// avoid to match an empty string in\ninmemory_table_clause\n    : inmemory_column_clause+\n    | (INMEMORY inmemory_attributes? | NO INMEMORY) inmemory_column_clause*\n    ;\n\ninmemory_attributes\n    : (\n        inmemory_memcompress\n        | inmemory_priority\n        | inmemory_distribute\n        | inmemory_duplicate\n    )+\n    ;\n\ninmemory_memcompress\n    : MEMCOMPRESS FOR (DML | (QUERY | CAPACITY) (LOW | HIGH)?)\n    | NO MEMCOMPRESS\n    ;\n\ninmemory_priority\n    : PRIORITY (NONE | LOW | MEDIUM | HIGH | CRITICAL)\n    ;\n\ninmemory_distribute\n    : DISTRIBUTE (AUTO | BY (ROWID RANGE | PARTITION | SUBPARTITION))? (\n        FOR SERVICE (DEFAULT | ALL | identifier | NONE)\n    )?\n    ;\n\ninmemory_duplicate\n    : DUPLICATE ALL?\n    | NO DUPLICATE\n    ;\n\ninmemory_column_clause\n    : (INMEMORY inmemory_memcompress? | NO INMEMORY) '(' column_list ')'\n    ;\n\nphysical_attributes_clause\n    : (\n        PCTFREE pctfree = UNSIGNED_INTEGER\n        | PCTUSED pctused = UNSIGNED_INTEGER\n        | INITRANS inittrans = UNSIGNED_INTEGER\n        | MAXTRANS maxtrans = UNSIGNED_INTEGER\n        | storage_clause\n        | compute_clauses\n    )+\n    ;\n\nstorage_clause\n    : STORAGE '(' (\n        INITIAL initial_size = size_clause\n        | NEXT next_size = size_clause\n        | MINEXTENTS minextents = (UNSIGNED_INTEGER | UNLIMITED)\n        | MAXEXTENTS minextents = (UNSIGNED_INTEGER | UNLIMITED)\n        | PCTINCREASE pctincrease = UNSIGNED_INTEGER\n        | FREELISTS freelists = UNSIGNED_INTEGER\n        | FREELIST GROUPS freelist_groups = UNSIGNED_INTEGER\n        | OPTIMAL (size_clause | NULL_)\n        | BUFFER_POOL (KEEP | RECYCLE | DEFAULT)\n        | FLASH_CACHE (KEEP | NONE | DEFAULT)\n        | CELL_FLASH_CACHE (KEEP | NONE | DEFAULT)\n        | ENCRYPT\n    )+ ')'\n    ;\n\ndeferred_segment_creation\n    : SEGMENT CREATION (IMMEDIATE | DEFERRED)\n    ;\n\nsegment_attributes_clause\n    : (\n        physical_attributes_clause\n        | TABLESPACE (tablespace_name = id_expression | SET? identifier)\n        | table_compression\n        | logging_clause\n    )+\n    ;\n\nphysical_properties\n    : deferred_segment_creation\n    | segment_attributes_clause\n    | table_compression\n    | inmemory_table_clause\n    | ilm_clause\n    | ORGANIZATION (\n        HEAP segment_attributes_clause? heap_org_table_clause\n        | INDEX segment_attributes_clause? index_org_table_clause?\n        | EXTERNAL external_table_clause\n    )\n    | EXTERNAL PARTITION ATTRIBUTES external_table_clause (REJECT LIMIT)?\n    | CLUSTER cluster_name '(' column_name (',' column_name)* ')'\n    ;\n\nilm_clause\n    : ILM (\n        ADD POLICY ilm_policy_clause\n        | (DELETE | ENABLE | DISABLE) POLICY ilm_policy_clause\n        | DELETE_ALL\n        | ENABLE_ALL\n        | DISABLE_ALL\n    )\n    ;\n\nilm_policy_clause\n    : ilm_compression_policy\n    | ilm_tiering_policy\n    | ilm_inmemory_policy\n    ;\n\nilm_compression_policy\n    : table_compression segment_group ilm_after_on\n    | ((ROW | COLUMN) STORE COMPRESS (ADVANCED | FOR QUERY)) ROW AFTER ilm_time_period OF NO MODIFICATION\n    ;\n\nilm_tiering_policy\n    : TIER TO tablespace (\n        segment_group? (ON function_name)?\n        | READ ONLY segment_group? ilm_after_on\n    )\n    ;\n\nilm_after_on\n    : AFTER ilm_time_period OF (NO (ACCESS | MODIFICATION) | CREATION)\n    | ON function_name\n    ;\n\nsegment_group\n    : SEGMENT\n    | GROUP\n    ;\n\nilm_inmemory_policy\n    : (SET INMEMORY inmemory_attributes? | MODIFY INMEMORY inmemory_memcompress | NO INMEMORY) SEGMENT? ilm_after_on\n    ;\n\nilm_time_period\n    : numeric (DAY | DAYS | MONTH | MONTHS | YEAR | YEARS)\n    ;\n\nheap_org_table_clause\n    : table_compression? inmemory_table_clause? ilm_clause?\n    ;\n\nexternal_table_clause\n    : '(' (TYPE access_driver_type)? external_table_data_props ')' parallel_clause? (\n        REJECT LIMIT (numeric | UNLIMITED)\n    )? inmemory_table_clause?\n    ;\n\naccess_driver_type\n    : ORACLE_LOADER\n    | ORACLE_DATAPUMP\n    | ORACLE_HDFS\n    | ORACLE_HIVE\n    ;\n\nexternal_table_data_props\n    : (DEFAULT DIRECTORY external_table_directory)? (\n        ACCESS PARAMETERS (\n            '(' CHAR_STRING ')'\n            | '(' external_table_data_format+ ')'\n            | USING CLOB select_only_statement\n        )\n    )? (LOCATION '(' external_table_directory (',' external_table_directory)* ')')?\n    ;\n\nexternal_table_data_format\n    : RECORDS DELIMITED BY NEWLINE_\n    | COLUMN TRANSFORMS '(' external_table_transform (',' external_table_transform)* ')'\n    | external_table_records\n    | external_table_fields\n    | external_table_datapump\n    | external_table_hive\n    ;\n\nexternal_table_transform\n    : column_name FROM (\n        NULL_\n        | CONSTANT quoted_string\n        | (CONCAT | LOBFILE) (external_table_field | CONSTANT quoted_string)\n        | (\n            FROM '(' external_table_directory (',' external_table_directory)* ')'\n            | CLOB\n            | BLOB\n            | CHARACTERSET '=' char_set_name\n        )\n        | STARTOF external_table_field_list '(' UNSIGNED_INTEGER ')'\n    )\n    ;\n\nexternal_table_field\n    : column_name type_name? (NOT NULL_)? default_value_part?\n    ;\n\nexternal_table_field_list\n    : external_table_fields_clause (',' external_table_fields_clause)*\n    ;\n\nexternal_table_fields_clause\n    : external_table_field (\n        external_table_position_clause\n        | external_table_datatype_clause\n        | external_table_init_clause\n        | external_table_lls_clause\n    )*\n    ;\n\nexternal_table_position_clause\n    : POSITION? '(' ('*'? ('+' | '-')? UNSIGNED_INTEGER?) (BINDVAR | (':' ('+' | '-')? UNSIGNED_INTEGER)) ')'\n    ;\n\nexternal_table_datatype_clause\n    : UNSIGNED? INTEGER EXTERNAL? UNSIGNED_INTEGER? external_table_delimit_clause?\n    | (DECIMAL | ZONED) (\n        '(' UNSIGNED_INTEGER (',' UNSIGNED_INTEGER)? ')'\n        | EXTERNAL ('(' UNSIGNED_INTEGER ')')? external_table_delimit_clause?\n    )\n    | ORACLE_DATE\n    | ORACLE_NUMBER COUNTED?\n    | FLOAT EXTERNAL? UNSIGNED_INTEGER? external_table_delimit_clause?\n    | DOUBLE\n    | BINARY_FLOAT EXTERNAL? UNSIGNED_INTEGER? external_table_delimit_clause?\n    | BINARY_DOUBLE\n    | RAW UNSIGNED_INTEGER?\n    | CHAR EXTERNAL? ('(' UNSIGNED_INTEGER ')' )? external_table_delimit_clause? external_table_trim_clause? external_table_date_format_clause?\n    | (VARCHAR | VARRAW | VARCHARC | VARRAWC) '(' (UNSIGNED_INTEGER ',')? UNSIGNED_INTEGER ')'\n    ;\n\nexternal_table_delimit_clause\n    : ENCLOSED BY quoted_string (AND quoted_string)?\n    | TERMINATED BY (quoted_string | WHITESPACE) (OPTIONALLY? ENCLOSED BY quoted_string (AND quoted_string)?)?\n    ;\n\nexternal_table_trim_clause\n    : LRTRIM\n    | NOTRIM\n    | LTRIM\n    | RTRIM\n    | LDRTRIM\n    ;\n\nexternal_table_date_format_clause\n    : DATE_FORMAT? (\n        DATE\n        | TIMESTAMP (WITH LOCAL? TIME ZONE)? MASK quoted_string\n        | INTERVAL (YEAR_TO_MONTH | DAY_TO_SECOND)\n    )\n    ;\n\nexternal_table_init_clause\n    : (DEFAULTIF | NULLIF) external_table_condition_clause\n    ;\n\nexternal_table_condition_clause\n    : (field_spec | '(' UNSIGNED_INTEGER BINDVAR ')') relational_operator (quoted_string | HEX_STRING_LIT | BLANKS)\n    | external_table_condition_clause (AND | OR) external_table_condition_clause\n    ;\n\nexternal_table_lls_clause\n    : LLS external_table_directory\n    ;\n\nexternal_table_records\n    : RECORDS (\n        FIXED UNSIGNED_INTEGER\n        | VARIABLE UNSIGNED_INTEGER\n        | DELIMITED BY (DETECTED? NEWLINE_ | quoted_string)\n        | XMLTAG '('? id_expression (',' id_expression)* ')'?\n    ) external_table_record_options_clause*\n    | external_table_record_options_clause+\n    ;\n\nexternal_table_record_options_clause\n    : CHARACTERSET char_set_name\n    | EXTERNAL VARIABLE DATA\n    | PREPROCESSOR external_table_directory\n    | DATA IS (LITTLE | BIG) ENDIAN\n    | BYTEORDERMARK (CHECK | NOCHECK)\n    | STRING SIZES ARE IN (BYTES | CHARACTERS)\n    | LOAD WHEN external_table_condition_clause\n    | external_table_output_files\n    | READSIZE '='? UNSIGNED_INTEGER\n    | DISABLE_DIRECTORY_LINK_CHECK\n    | DATE_CACHE UNSIGNED_INTEGER\n    | SKIP_ UNSIGNED_INTEGER\n    | IO_OPTIONS (DIRECTIO | NODIRECTIO)\n    | (DNFS_ENABLE | DNFS_DISABLE)\n    | DNFS_READBUFFERS UNSIGNED_INTEGER\n    ;\n\nexternal_table_output_files\n    : (\n        (NOBADFILE | NODISCARDFILE | NOLOGFILE)\n        | (BADFILE | DISCARDFILE | LOGFILE) external_table_directory? filename\n    )\n    ;\n\nexternal_table_fields\n    : FIELDS\n        IGNORE_CHARS_AFTER_EOR?\n        (CSV (WITH | WITHOUT) EMBEDDED)?\n        external_table_delimit_clause?\n        external_table_trim_clause?\n        (ALL FIELDS OVERRIDE THESE FIELDS)?\n        (MISSING FIELD VALUES ARE NULL_)?\n        (REJECT ROWS WITH ALL NULL_ FIELDS)?\n        (DATE_FORMAT (DATE | TIMESTAMP) MASK quoted_string)?\n        (NULLIF (EQUALS_OP | NOT_EQUAL_OP) (quoted_string | HEX_STRING_LIT | BLANKS) | NONULLIF)?\n        '('? external_table_field_list? ')'?\n    ;\n\nexternal_table_datapump\n    : ENCRYPTION (ENABLE | DISABLED)\n    | NOLOGFILE\n    | LOGFILE external_table_directory? filename\n    | COMPRESSION (ENABLED (BASIC | LOW | MEDIUM | HIGH)? | DISABLED)?\n    | HADOOP_TRAILERS (ENABLED | DISABLED) VERSION (COMPATIBLE | LATEST | quoted_string)\n    | NOLOG\n    | DEBUG '=' '(' UNSIGNED_INTEGER ',' UNSIGNED_INTEGER ')'\n    | DATAPUMP INTERNAL TABLE tableview_name\n    | TEMPLATE_TABLE tableview_name\n    | JOB '(' schema_name ',' tableview_name ',' UNSIGNED_INTEGER ')'\n    | WORKERID UNSIGNED_INTEGER\n    | PARALLEL UNSIGNED_INTEGER\n    | VERSION quoted_string\n    | ENCRYPTPASSWORDISNULL\n    | DBLINK quoted_string\n    ;\n\nexternal_table_hive\n    : id_expression ('.' id_expression)* ('=' | ':') (\n        tableview_name\n        | external_table_hive_parameter_map\n        | '[' external_table_hive_parameter_map (',' external_table_hive_parameter_map)* ']'\n        | external_table_field datatype (COMMENT quoted_string)? (',' COMMENT quoted_string)*\n        | SEQUENCEFILE\n        | TEXTFILE\n        | RCFILE\n        | ORC\n        | PARQUET\n        | INPUTFORMAT quoted_string OUTPUTFORMAT quoted_string\n        | external_table_directory\n        | DELIMITED? (\n            FIELDS TERMINATED BY CHARACTER (ESCAPED BY CHARACTER)\n            | (COLLECTION ITEMS | MAP KEYS | LINES ) TERMINATED BY CHARACTER\n            | NULL_ DEFINED AS CHARACTER\n        )\n        | SERDE quoted_string (\n            WITH SERDEPROPERTIES (\n                quoted_string '=' quoted_string (',' quoted_string '=' quoted_string)*\n            )\n        )?\n    ) external_table_hive?\n    ;\n\nexternal_table_hive_parameter_map\n    : LEFT_CURLY_PAREN (external_table_hive_parameter_map_entry (',' external_table_hive_parameter_map_entry)*) RIGHT_CURLY_PAREN\n    ;\n\nexternal_table_hive_parameter_map_entry\n    : id_expression BINDVAR\n    | id_expression ':' '[' id_expression (',' id_expression)* ']'\n    | '[' id_expression (',' id_expression)* ']'\n    ;\n\nexternal_table_directory\n    : directory_name COLON CHAR_STRING\n    | (directory_name object_name? COLON)? CHAR_STRING\n    | quoted_string\n    | variable_name\n    ;\n\nrow_movement_clause\n    : (ENABLE | DISABLE)? ROW MOVEMENT\n    ;\n\nflashback_archive_clause\n    : FLASHBACK ARCHIVE fa = id_expression?\n    | NO FLASHBACK ARCHIVE\n    ;\n\nlog_grp\n    : UNSIGNED_INTEGER\n    | identifier\n    ;\n\nsupplemental_table_logging\n    : ADD SUPPLEMENTAL LOG (supplemental_log_grp_clause | supplemental_id_key_clause) (\n        ',' SUPPLEMENTAL LOG (supplemental_log_grp_clause | supplemental_id_key_clause)\n    )*\n    | DROP SUPPLEMENTAL LOG (supplemental_id_key_clause | GROUP log_grp) (\n        ',' SUPPLEMENTAL LOG (supplemental_id_key_clause | GROUP log_grp)\n    )*\n    ;\n\nsupplemental_log_grp_clause\n    : GROUP log_grp '(' column_name (NO LOG)? (',' column_name (NO LOG)?)* ')' ALWAYS?\n    ;\n\nsupplemental_id_key_clause\n    : DATA '(' (','? ( ALL | PRIMARY KEY | UNIQUE INDEX? | FOREIGN KEY))+ ')' COLUMNS\n    ;\n\nallocate_extent_clause\n    : ALLOCATE EXTENT (\n        '(' (\n            SIZE size_clause\n            | DATAFILE datafile = CHAR_STRING\n            | INSTANCE inst_num = UNSIGNED_INTEGER\n        )+ ')'\n    )?\n    ;\n\ndeallocate_unused_clause\n    : DEALLOCATE UNUSED (KEEP size_clause)?\n    ;\n\n// CHECK is an internal, undocumented Oracle option that is allowed and sometimes specified, used to check for proper\n// segment type and segment attributes allowed to shrink.\nshrink_clause\n    : SHRINK SPACE_KEYWORD COMPACT? CASCADE? CHECK?\n    ;\n\nrecords_per_block_clause\n    : (MINIMIZE | NOMINIMIZE)? RECORDS_PER_BLOCK\n    ;\n\nupgrade_table_clause\n    : UPGRADE (NOT? INCLUDING DATA) column_properties\n    ;\n\ntruncate_table\n    : TRUNCATE TABLE tableview_name ((PRESERVE | PURGE) (MATERIALIZED VIEW LOG)?)? ((DROP ALL? | REUSE) STORAGE)? CASCADE?\n    ;\n\ndrop_table\n    : DROP TABLE tableview_name (IF EXISTS)? (AS tableview_name)? (CASCADE (CONSTRAINT | CONSTRAINTS))? PURGE? (AS table_alias)? FORCE?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-TABLESPACE.html\ndrop_tablespace\n    : DROP TABLESPACE ts = id_expression (IF EXISTS)? ((DROP | KEEP) QUOTA?)? including_contents_clause?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-TABLESPACE-SET.html\ndrop_tablespace_set\n    : DROP TABLESPACE SET tss = id_expression including_contents_clause?\n    ;\n\nincluding_contents_clause\n    : INCLUDING CONTENTS ((AND | KEEP) DATAFILES)? (CASCADE CONSTRAINTS)?\n    ;\n\ndrop_view\n    : DROP VIEW tableview_name (IF EXISTS)? (CASCADE CONSTRAINT)?\n    ;\n\ncomment_on_column\n    : COMMENT ON COLUMN column_name IS quoted_string\n    ;\n\nenable_or_disable\n    : ENABLE\n    | DISABLE\n    ;\n\nallow_or_disallow\n    : ALLOW\n    | DISALLOW\n    ;\n\n// Synonym DDL Clauses\n\nalter_synonym\n    : ALTER PUBLIC? SYNONYM (schema_name '.')? synonym_name (\n        EDITIONABLE\n        | NONEDITIONABLE\n        | COMPILE\n    )\n    ;\n\ncreate_synonym\n    // Synonym's schema cannot be specified for public synonyms\n    : CREATE (OR REPLACE)? PUBLIC SYNONYM synonym_name FOR (schema_name PERIOD)? schema_object_name (\n        AT_SIGN link_name\n    )?\n    | CREATE (OR REPLACE)? SYNONYM (schema_name PERIOD)? synonym_name FOR (schema_name PERIOD)? schema_object_name (\n        AT_SIGN (schema_name PERIOD)? link_name\n    )?\n    ;\n\ndrop_synonym\n    : DROP PUBLIC? SYNONYM (schema_name '.')? synonym_name FORCE?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-SPFILE.html\ncreate_spfile\n    : CREATE SPFILE ('=' spfile_name)? FROM (PFILE ('=' pfile_name)? (AS COPY)? | MEMORY)\n    ;\n\nspfile_name\n    : CHAR_STRING\n    ;\n\npfile_name\n    : CHAR_STRING\n    ;\n\ncomment_on_table\n    : COMMENT ON TABLE tableview_name IS quoted_string\n    ;\n\ncomment_on_materialized\n    : COMMENT ON MATERIALIZED VIEW tableview_name IS quoted_string\n    ;\n\nalter_analytic_view\n    : ALTER ANALYTIC VIEW (schema_name '.')? av = id_expression (\n        RENAME TO id_expression\n        | COMPILE\n        | alter_add_cache_clause\n        | alter_drop_cache_clause\n    )\n    ;\n\nalter_add_cache_clause\n    : ADD CACHE MEASURE GROUP '(' (ALL | measure_list)? ')' LEVELS '(' levels_item (\n        ',' levels_item\n    )* ')'\n    ;\n\nlevels_item\n    : ((d = id_expression '.')? h = id_expression '.')? l = id_expression\n    ;\n\nmeasure_list\n    : id_expression (',' id_expression)*\n    ;\n\nalter_drop_cache_clause\n    : DROP CACHE MEASURE GROUP '(' (ALL | measure_list)? ')' LEVELS '(' levels_item (\n        ',' levels_item\n    )* ')'\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-ATTRIBUTE-DIMENSION.html\nalter_attribute_dimension\n    : ALTER ATTRIBUTE DIMENSION (schema_name '.')? ad = id_expression (\n        RENAME TO nad = id_expression\n        | COMPILE\n    )\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-AUDIT-POLICY-Unified-Auditing.html\nalter_audit_policy\n    : ALTER AUDIT POLICY p = id_expression ADD? (\n        privilege_audit_clause? action_audit_clause? role_audit_clause?\n        | (ONLY TOPLEVEL)?\n    ) DROP? (privilege_audit_clause? action_audit_clause? role_audit_clause? | (ONLY TOPLEVEL)?) (\n        CONDITION (DROP | CHAR_STRING EVALUATE PER (STATEMENT | SESSION | INSTANCE))\n    )?\n    ;\n\nalter_cluster\n    : ALTER CLUSTER cluster_name (\n        physical_attributes_clause\n        | SIZE size_clause\n        | allocate_extent_clause\n        | deallocate_unused_clause\n        | cache_or_nocache\n    )+ parallel_clause?\n    ;\n\ndrop_analytic_view\n    : DROP ANALYTIC VIEW (schema_name '.')? av = id_expression\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-ATTRIBUTE-DIMENSION.html\ndrop_attribute_dimension\n    : DROP ATTRIBUTE DIMENSION (schema_name '.')? ad = id_expression\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-AUDIT-POLICY-Unified-Auditing.html\ndrop_audit_policy\n    : DROP AUDIT POLICY p = id_expression\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-FLASHBACK-ARCHIVE.html\ndrop_flashback_archive\n    : DROP FLASHBACK ARCHIVE fa = id_expression\n    ;\n\ndrop_cluster\n    : DROP CLUSTER cluster_name (INCLUDING TABLES (CASCADE CONSTRAINTS)?)?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-CONTEXT.html\ndrop_context\n    : DROP CONTEXT ns = id_expression\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-DIRECTORY.html\ndrop_directory\n    : DROP DIRECTORY dn = id_expression\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-DISKGROUP.html\ndrop_diskgroup\n    : DROP DISKGROUP dgn = id_expression ((FORCE? INCLUDING | EXCLUDING) CONTENTS)?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-EDITION.html\ndrop_edition\n    : DROP EDITION e = id_expression CASCADE?\n    ;\n\ntruncate_cluster\n    : TRUNCATE CLUSTER cluster_name ((DROP | REUSE) STORAGE)?\n    ;\n\ncache_or_nocache\n    : CACHE\n    | NOCACHE\n    ;\n\ndatabase_name\n    : id_expression\n    ;\n\nalter_database\n    : ALTER database_clause (\n        startup_clauses\n        | recovery_clauses\n        | database_file_clauses\n        | logfile_clauses\n        | controlfile_clauses\n        | standby_database_clauses\n        | default_settings_clause\n        | instance_clauses\n        | security_clause\n        | prepare_clause\n        | drop_mirror_clause\n        | lost_write_protection\n        | cdb_fleet_clauses\n        | property_clauses\n        | replay_upgrade_clauses\n    )\n    ;\n\ndatabase_clause\n    : PLUGGABLE? DATABASE database_name?\n    ;\n\nstartup_clauses\n    : MOUNT ((STANDBY | CLONE) DATABASE)?\n    | OPEN (READ WRITE)? resetlogs_or_noresetlogs? upgrade_or_downgrade?\n    | OPEN READ ONLY\n    ;\n\nresetlogs_or_noresetlogs\n    : RESETLOGS\n    | NORESETLOGS\n    ;\n\nupgrade_or_downgrade\n    : UPGRADE\n    | DOWNGRADE\n    ;\n\nrecovery_clauses\n    : general_recovery\n    | managed_standby_recovery\n    | begin_or_end BACKUP\n    ;\n\nbegin_or_end\n    : BEGIN\n    | END\n    ;\n\ngeneral_recovery\n    : RECOVER AUTOMATIC? (FROM CHAR_STRING)? (\n        (full_database_recovery | partial_database_recovery | LOGFILE CHAR_STRING)? (\n            (TEST | ALLOW UNSIGNED_INTEGER CORRUPTION | parallel_clause)+\n        )?\n        | CONTINUE DEFAULT?\n        | CANCEL\n    )\n    ;\n\n//Need to come back to\nfull_database_recovery\n    : STANDBY? DATABASE (\n        (\n            UNTIL (CANCEL | TIME CHAR_STRING | CHANGE UNSIGNED_INTEGER | CONSISTENT)\n            | USING BACKUP CONTROLFILE\n            | SNAPSHOT TIME CHAR_STRING\n        )+\n    )?\n    ;\n\npartial_database_recovery\n    : TABLESPACE tablespace (',' tablespace)*\n    | DATAFILE CHAR_STRING\n    | filenumber (',' CHAR_STRING | filenumber)*\n    | partial_database_recovery_10g\n    ;\n\npartial_database_recovery_10g\n    : {this.isVersion10()}? STANDBY (\n        TABLESPACE tablespace (',' tablespace)*\n        | DATAFILE CHAR_STRING\n        | filenumber (',' CHAR_STRING | filenumber)*\n    ) UNTIL (CONSISTENT WITH)? CONTROLFILE\n    ;\n\nmanaged_standby_recovery\n    : RECOVER (\n        MANAGED STANDBY DATABASE (\n            (\n                USING CURRENT LOGFILE\n                | DISCONNECT (FROM SESSION)?\n                | NODELAY\n                | UNTIL CHANGE UNSIGNED_INTEGER\n                | UNTIL CONSISTENT\n                | parallel_clause\n            )+\n            | FINISH\n            | CANCEL\n        )?\n        | TO LOGICAL STANDBY (db_name | KEEP IDENTITY)\n    )\n    ;\n\ndb_name\n    : regular_id\n    ;\n\ndatabase_file_clauses\n    : RENAME FILE filename (',' filename)* TO filename\n    | create_datafile_clause\n    | alter_datafile_clause\n    | alter_tempfile_clause\n    | move_datafile_clause\n    ;\n\ncreate_datafile_clause\n    : CREATE DATAFILE (filename | filenumber) (',' (filename | filenumber))* (\n        AS (\n            //TODO (','? file_specification)+ |\n            NEW\n        )\n    )?\n    ;\n\nalter_datafile_clause\n    : DATAFILE (filename | filenumber) (',' (filename | filenumber))* (\n        ONLINE\n        | OFFLINE (FOR DROP)?\n        | RESIZE size_clause\n        | autoextend_clause\n        | END BACKUP\n    )\n    ;\n\nalter_tempfile_clause\n    : TEMPFILE (filename | filenumber) (',' (filename | filenumber))* (\n        RESIZE size_clause\n        | autoextend_clause\n        | DROP (INCLUDING DATAFILES)\n        | ONLINE\n        | OFFLINE\n    )\n    ;\n\nmove_datafile_clause\n    : MOVE DATAFILE (filename | filenumber) (',' (filename | filenumber))* (TO filename)? REUSE? KEEP?\n    ;\n\nlogfile_clauses\n    : (ARCHIVELOG MANUAL? | NOARCHIVELOG)\n    | NO? FORCE LOGGING\n    | SET STANDBY NOLOGGING FOR (DATA AVAILABILITY | LOAD PERFORMANCE)\n    | RENAME FILE filename (',' filename)* TO filename\n    | CLEAR UNARCHIVED? LOGFILE logfile_descriptor (',' logfile_descriptor)* (\n        UNRECOVERABLE DATAFILE\n    )?\n    | add_logfile_clauses\n    | drop_logfile_clauses\n    | switch_logfile_clause\n    | supplemental_db_logging\n    ;\n\nadd_logfile_clauses\n    : ADD STANDBY? LOGFILE (\n        (INSTANCE CHAR_STRING | THREAD UNSIGNED_INTEGER)? group_redo_logfile+\n        | MEMBER filename REUSE? (',' filename REUSE?)* TO logfile_descriptor (\n            ',' logfile_descriptor\n        )*\n    )\n    ;\n\ngroup_redo_logfile\n    : (GROUP UNSIGNED_INTEGER)? redo_log_file_spec\n    ;\n\ndrop_logfile_clauses\n    : DROP STANDBY? LOGFILE (\n        logfile_descriptor (',' logfile_descriptor)*\n        | MEMBER filename (',' filename)*\n    )\n    ;\n\nswitch_logfile_clause\n    : SWITCH ALL LOGFILES TO BLOCKSIZE UNSIGNED_INTEGER\n    ;\n\nsupplemental_db_logging\n    : add_or_drop SUPPLEMENTAL LOG (DATA | supplemental_id_key_clause | supplemental_plsql_clause)\n    ;\n\nadd_or_drop\n    : ADD\n    | DROP\n    ;\n\nsupplemental_plsql_clause\n    : DATA FOR PROCEDURAL REPLICATION\n    ;\n\nlogfile_descriptor\n    : GROUP UNSIGNED_INTEGER\n    | '(' filename (',' filename)* ')'\n    | filename\n    ;\n\ncontrolfile_clauses\n    : CREATE (LOGICAL | PHYSICAL)? STANDBY CONTROLFILE AS filename REUSE?\n    | BACKUP CONTROLFILE TO (filename REUSE? | trace_file_clause)\n    ;\n\ntrace_file_clause\n    : TRACE (AS filename REUSE?)? (RESETLOGS | NORESETLOGS)?\n    ;\n\nstandby_database_clauses\n    : (\n        activate_standby_db_clause\n        | maximize_standby_db_clause\n        | register_logfile_clause\n        | commit_switchover_clause\n        | start_standby_clause\n        | stop_standby_clause\n        | convert_database_clause\n    ) parallel_clause?\n    ;\n\nactivate_standby_db_clause\n    : ACTIVATE (PHYSICAL | LOGICAL)? STANDBY DATABASE (FINISH APPLY)?\n    ;\n\nmaximize_standby_db_clause\n    : SET STANDBY DATABASE TO MAXIMIZE (PROTECTION | AVAILABILITY | PERFORMANCE)\n    ;\n\nregister_logfile_clause\n    : REGISTER (OR REPLACE)? (PHYSICAL | LOGICAL) LOGFILE //TODO (','? file_specification)+\n    //TODO   (FOR logminer_session_name)?\n    ;\n\ncommit_switchover_clause\n    : (PREPARE | COMMIT) TO SWITCHOVER (\n        (\n            TO (\n                ((PHYSICAL | LOGICAL)? PRIMARY | PHYSICAL? STANDBY) (\n                    (WITH | WITHOUT)? SESSION SHUTDOWN (WAIT | NOWAIT)\n                )?\n                | LOGICAL STANDBY\n            )\n            | LOGICAL STANDBY\n        )\n        | CANCEL\n    )?\n    ;\n\nstart_standby_clause\n    : START LOGICAL STANDBY APPLY IMMEDIATE? NODELAY? (\n        NEW PRIMARY regular_id\n        | INITIAL scn_value = UNSIGNED_INTEGER?\n        | SKIP_ FAILED TRANSACTION\n        | FINISH\n    )?\n    ;\n\nstop_standby_clause\n    : (STOP | ABORT) LOGICAL STANDBY APPLY\n    ;\n\nconvert_database_clause\n    : CONVERT TO (PHYSICAL | SNAPSHOT) STANDBY\n    ;\n\ndefault_settings_clause\n    : DEFAULT EDITION EQUALS_OP edition_name\n    | SET DEFAULT (BIGFILE | SMALLFILE) TABLESPACE\n    | DEFAULT TABLESPACE tablespace\n    | DEFAULT TEMPORARY TABLESPACE (tablespace | tablespace_group_name)\n    | RENAME GLOBAL_NAME TO database ('.' domain)+\n    | ENABLE BLOCK CHANGE TRACKING (USING FILE filename REUSE?)?\n    | DISABLE BLOCK CHANGE TRACKING\n    | flashback_mode_clause\n    | set_time_zone_clause\n    ;\n\nset_time_zone_clause\n    : SET TIMEZONE EQUALS_OP CHAR_STRING\n    ;\n\ninstance_clauses\n    : enable_or_disable INSTANCE CHAR_STRING\n    ;\n\nsecurity_clause\n    : GUARD (ALL | STANDBY | NONE)\n    ;\n\ndomain\n    : id_expression\n    ;\n\ndatabase\n    : id_expression\n    ;\n\nedition_name\n    : regular_id\n    ;\n\nfilenumber\n    : UNSIGNED_INTEGER\n    ;\n\nfilename\n    : CHAR_STRING\n    ;\n\nprepare_clause\n    : PREPARE MIRROR COPY c = id_expression (WITH (UNPROTECTED | MIRROR | HIGH) REDUNDANCY)? (\n        FOR DATABASE id_expression\n    )?\n    ;\n\ndrop_mirror_clause\n    : DROP MIRROR COPY mn = id_expression\n    ;\n\nlost_write_protection\n    : (ENABLE | DISABLE | REMOVE | SUSPEND) LOST WRITE PROTECTION\n    ;\n\ncdb_fleet_clauses\n    : lead_cdb_clause\n    | lead_cdb_uri_clause\n    ;\n\nlead_cdb_clause\n    : SET LEAD_CDB '=' (TRUE | FALSE)\n    ;\n\nlead_cdb_uri_clause\n    : SET LEAD_CDB_URI '=' CHAR_STRING\n    ;\n\nproperty_clauses\n    : PROPERTY (SET | REMOVE) DEFAULT_CREDENTIAL '=' qcn = id_expression\n    ;\n\nreplay_upgrade_clauses\n    : UPGRADE SYNC (ON | OFF)\n    ;\n\nalter_database_link\n    : ALTER SHARED? PUBLIC? DATABASE LINK local_link_name (\n        CONNECT TO user_object_name IDENTIFIED BY password_value link_authentication?\n        | link_authentication\n    )\n    ;\n\npassword_value\n    : id_expression\n    | numeric\n    | VALUES CHAR_STRING\n    ;\n\nlink_authentication\n    : AUTHENTICATED BY user_object_name IDENTIFIED BY password_value\n    ;\n\n//https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/CREATE-SCHEMA.html\ncreate_schema\n    : CREATE SCHEMA AUTHORIZATION schema_name (create_table | create_view | grant_statement)*\n    ;\n\n// added by zrh\ncreate_database\n    : CREATE DATABASE database_name (\n        USER (SYS | SYSTEM) IDENTIFIED BY password_value\n        | CONTROLFILE REUSE\n        | (MAXDATAFILES | MAXINSTANCES) UNSIGNED_INTEGER\n        | NATIONAL? CHARACTER SET char_set_name\n        | SET DEFAULT (BIGFILE | SMALLFILE) TABLESPACE\n        | database_logging_clauses\n        | tablespace_clauses\n        | set_time_zone_clause\n        | (BIGFILE | SMALLFILE)? USER_DATA TABLESPACE tablespace_group_name DATAFILE datafile_tempfile_spec (\n            ',' datafile_tempfile_spec\n        )*\n        | enable_pluggable_database\n    )+\n    ;\n\ndatabase_logging_clauses\n    : LOGFILE database_logging_sub_clause (',' database_logging_sub_clause)*\n    | (MAXLOGFILES | MAXLOGMEMBERS | MAXLOGHISTORY) UNSIGNED_INTEGER\n    | ARCHIVELOG\n    | NOARCHIVELOG\n    | FORCE LOGGING\n    ;\n\ndatabase_logging_sub_clause\n    : (GROUP UNSIGNED_INTEGER)? file_specification\n    ;\n\ntablespace_clauses\n    : EXTENT MANAGEMENT LOCAL\n    | SYSAUX? DATAFILE file_specification (',' file_specification)*\n    | default_tablespace\n    | default_temp_tablespace\n    | undo_tablespace\n    ;\n\nenable_pluggable_database\n    : ENABLE PLUGGABLE DATABASE (\n        SEED file_name_convert? (SYSTEM tablespace_datafile_clauses)? (\n            SYSAUX tablespace_datafile_clauses\n        )?\n    )? undo_mode_clause?\n    ;\n\nfile_name_convert\n    : FILE_NAME_CONVERT EQUALS_OP (\n        '(' filename_convert_sub_clause (',' filename_convert_sub_clause)* ')'\n        | NONE\n    )\n    ;\n\nfilename_convert_sub_clause\n    : CHAR_STRING (',' CHAR_STRING)?\n    ;\n\ntablespace_datafile_clauses\n    : DATAFILES (SIZE size_clause | autoextend_clause)+\n    ;\n\nundo_mode_clause\n    : LOCAL UNDO (ON | OFF)\n    ;\n\ndefault_tablespace\n    : DEFAULT TABLESPACE tablespace (DATAFILE datafile_tempfile_spec)? extent_management_clause?\n    ;\n\ndefault_temp_tablespace\n    : (BIGFILE | SMALLFILE)? DEFAULT (\n        TEMPORARY TABLESPACE\n        | LOCAL TEMPORARY TABLESPACE FOR (ALL | LEAF)\n    ) tablespace (TEMPFILE file_specification (',' file_specification)*)? extent_management_clause?\n    ;\n\nundo_tablespace\n    : (BIGFILE | SMALLFILE)? UNDO TABLESPACE tablespace (\n        DATAFILE file_specification (',' file_specification)*\n    )?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-DATABASE.html\ndrop_database\n    : DROP DATABASE (INCLUDING BACKUPS)? NOPROMPT?\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-DATABASE-LINK.html\ncreate_database_link\n    : CREATE SHARED? PUBLIC? DATABASE LINK link_name (\n        CONNECT TO (\n            CURRENT_USER\n            | user_object_name IDENTIFIED BY password_value link_authentication?\n        )\n        | link_authentication\n    )* (USING CHAR_STRING)?\n    ;\n\ndrop_database_link\n    : DROP PUBLIC? DATABASE LINK link_name\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-TABLESPACE-SET.html\nalter_tablespace_set\n    : ALTER TABLESPACE SET tss = id_expression alter_tablespace_attrs\n    ;\n\nalter_tablespace_attrs\n    : default_tablespace_params\n    | MINIMUM EXTENT size_clause\n    | RESIZE size_clause\n    | COALESCE\n    | SHRINK SPACE_KEYWORD (KEEP size_clause)?\n    | RENAME TO nts = id_expression\n    | (BEGIN | END) BACKUP\n    | datafile_tempfile_clauses\n    | tablespace_logging_clauses\n    | tablespace_group_clause\n    | tablespace_state_clauses\n    | autoextend_clause\n    | flashback_mode_clause\n    | tablespace_retention_clause\n    | alter_tablespace_encryption\n    | lost_write_protection\n    ;\n\nalter_tablespace_encryption\n    : ENCRYPTION (\n        OFFLINE (tablespace_encryption_spec? ENCRYPT | DECRYPT)\n        | ONLINE (tablespace_encryption_spec? (ENCRYPT | REKEY) | DECRYPT) ts_file_name_convert?\n        | FINISH (ENCRYPT | REKEY | DECRYPT) ts_file_name_convert?\n    )\n    ;\n\nts_file_name_convert\n    : FILE_NAME_CONVERT '=' '(' CHAR_STRING ',' CHAR_STRING (',' CHAR_STRING ',' CHAR_STRING)* ')' KEEP?\n    ;\n\nalter_role\n    : ALTER ROLE role_name role_identified_clause container_clause?\n    ;\n\nrole_identified_clause\n    : NOT IDENTIFIED\n    | IDENTIFIED (\n        BY identifier\n        | USING identifier ('.' id_expression)?\n        | EXTERNALLY\n        | GLOBALLY (AS CHAR_STRING)?\n    )\n    ;\n\nalter_table\n    : ALTER TABLE tableview_name memoptimize_read_write_clause* (\n        | alter_table_properties\n        | constraint_clauses\n        | column_clauses\n        | alter_table_partitioning\n        //TODO      | alter_external_table\n        | move_table_clause\n    ) ((enable_disable_clause | enable_or_disable (TABLE LOCK | ALL TRIGGERS))+)?\n    ;\n\nmemoptimize_read_write_clause\n    : NO? MEMOPTIMIZE FOR (READ | WRITE)\n    ;\n\nalter_table_properties\n    : alter_table_properties_1\n    | RENAME TO tableview_name\n    | shrink_clause\n    | READ ONLY\n    | READ WRITE\n    | REKEY CHAR_STRING\n    | annotations_clause\n    ;\n\nalter_table_partitioning\n    : add_table_partition\n    | drop_table_partition\n    | merge_table_partition\n    | modify_table_partition\n    | split_table_partition\n    | truncate_table_partition\n    | exchange_table_partition\n    | coalesce_table_partition\n    | alter_interval_partition\n    | move_table_partition\n    | rename_table_partition\n    ;\n\nadd_table_partition\n    : ADD (\n        range_partition_desc\n        | list_partition_desc\n        | PARTITION partition_name? (TABLESPACE tablespace)? key_compression? UNUSABLE?\n    )\n    ;\n\ndrop_table_partition\n    : DROP (partition_extended_names | subpartition_extended_names) (\n        update_index_clauses parallel_clause?\n    )?\n    ;\n\nmerge_table_partition\n    : MERGE PARTITION partition_name AND partition_name INTO PARTITION partition_name\n    ;\n\nmodify_table_partition\n    : MODIFY (\n        (PARTITION | SUBPARTITION) partition_name ((ADD | DROP) list_values_clause)? (ADD range_subpartition_desc)? (\n            REBUILD? UNUSABLE LOCAL INDEXES\n        )? shrink_clause?\n        | range_partitions\n    )\n    ;\n\nsplit_table_partition\n    : SPLIT partition_extended_names (\n        AT '(' literal (',' literal)* ')' INTO '(' range_partition_desc (',' range_partition_desc)* ')'\n        | INTO '(' (\n            range_partition_desc (',' range_partition_desc)*\n            | list_partition_desc (',' list_partition_desc)*\n        ) ')'\n    ) (update_global_index_clause | update_index_clauses | ONLINE)?\n    ;\n\ntruncate_table_partition\n    : TRUNCATE (partition_extended_names | subpartition_extended_names) (\n        (DROP ALL? | REUSE)? STORAGE\n    )? CASCADE? (update_index_clauses parallel_clause?)?\n    ;\n\nexchange_table_partition\n    : EXCHANGE PARTITION partition_name WITH TABLE tableview_name ((INCLUDING | EXCLUDING) INDEXES)? (\n        (WITH | WITHOUT) VALIDATION\n    )?\n    ;\n\ncoalesce_table_partition\n    : COALESCE PARTITION parallel_clause? (allow_or_disallow CLUSTERING)?\n    ;\n\nalter_interval_partition\n    : SET INTERVAL '(' (constant | expression)? ')'\n    ;\n\nmove_table_partition\n    : MOVE (\n        partition_extended_names (MAPPING TABLE)? table_partition_description\n        | subpartition_extended_names indexing_clause? partitioning_storage_clause?\n    ) (\n        filter_condition\n        | update_index_clauses\n        | parallel_clause\n        | allow_or_disallow CLUSTERING\n        | ONLINE\n    )*\n    ;\n\nfilter_condition\n    : INCLUDING ROWS where_clause\n    ;\n\nrename_table_partition\n    : RENAME (partition_extended_names | subpartition_extended_names) TO partition_name\n    ;\n\npartition_extended_names\n    : (PARTITION | PARTITIONS) (\n        partition_name (',' partition_name)*\n        | '(' partition_name (',' partition_name)* ')'\n        | FOR '('? partition_key_value (',' partition_key_value)* ')'?\n    )\n    ;\n\nsubpartition_extended_names\n    : (SUBPARTITION | SUBPARTITIONS) (\n        partition_name (UPDATE INDEXES)?\n        | '(' partition_name (',' partition_name)* ')'\n        | FOR '('? subpartition_key_value (',' subpartition_key_value)* ')'?\n    )\n    ;\n\nalter_table_properties_1\n    : (\n        physical_attributes_clause\n        | logging_clause\n        | table_compression\n        | inmemory_table_clause\n        | supplemental_table_logging\n        | allocate_extent_clause\n        | deallocate_unused_clause\n        | (CACHE | NOCACHE)\n        | RESULT_CACHE '(' MODE (DEFAULT | FORCE) ')'\n        | upgrade_table_clause\n        | records_per_block_clause\n        | parallel_clause\n        | row_movement_clause\n        | logical_replication_clause\n        | flashback_archive_clause\n    )+ alter_iot_clauses?\n    ;\n\nalter_iot_clauses\n    : index_org_table_clause\n    | alter_overflow_clause\n    | alter_mapping_table_clause\n    | COALESCE\n    ;\n\nalter_mapping_table_clause\n    : MAPPING TABLE (allocate_extent_clause | deallocate_unused_clause)\n    ;\n\nalter_overflow_clause\n    : add_overflow_clause\n    | OVERFLOW_ (\n        segment_attributes_clause\n        | allocate_extent_clause\n        | shrink_clause\n        | deallocate_unused_clause\n    )+\n    ;\n\nadd_overflow_clause\n    : ADD OVERFLOW_ segment_attributes_clause? (\n        '(' PARTITION segment_attributes_clause? (',' PARTITION segment_attributes_clause?)* ')'\n    )?\n    ;\n\nupdate_index_clauses\n    : update_global_index_clause\n    | update_all_indexes_clause\n    ;\n\nupdate_global_index_clause\n    : (UPDATE | INVALIDATE) GLOBAL INDEXES\n    ;\n\nupdate_all_indexes_clause\n    : UPDATE INDEXES ('(' update_all_indexes_index_clause ')')?\n    ;\n\nupdate_all_indexes_index_clause\n    : index_name '(' (update_index_partition | update_index_subpartition) ')' (\n        ',' update_all_indexes_clause\n    )*\n    ;\n\nupdate_index_partition\n    : index_partition_description index_subpartition_clause? (',' update_index_partition)*\n    ;\n\nupdate_index_subpartition\n    : SUBPARTITION subpartition_name? (TABLESPACE tablespace)? (',' update_index_subpartition)*\n    ;\n\nenable_disable_clause\n    : (ENABLE | DISABLE) (VALIDATE | NOVALIDATE)? (\n        UNIQUE '(' column_name (',' column_name)* ')'\n        | PRIMARY KEY\n        | CONSTRAINT constraint_name\n    ) using_index_clause? exceptions_clause? CASCADE? ((KEEP | DROP) INDEX)?\n    ;\n\nusing_index_clause\n    : USING INDEX (index_name | '(' create_index ')' | index_properties)\n    ;\n\nindex_attributes\n    : (\n        physical_attributes_clause\n        | logging_clause\n        | TABLESPACE (tablespace | DEFAULT)\n        | key_compression\n        | sort_or_nosort\n        | REVERSE\n        | visible_or_invisible\n        | parallel_clause\n    )+\n    ;\n\nsort_or_nosort\n    : SORT\n    | NOSORT\n    ;\n\nexceptions_clause\n    : EXCEPTIONS INTO tableview_name\n    ;\n\nmove_table_clause\n    : MOVE ONLINE? segment_attributes_clause? table_compression? index_org_table_clause? (\n        lob_storage_clause\n        | varray_col_properties\n    )* parallel_clause?\n    ;\n\nindex_org_table_clause\n    : (mapping_table_clause | PCTTHRESHOLD UNSIGNED_INTEGER | key_compression)+ index_org_overflow_clause?\n    | index_org_overflow_clause // rule move_table_clause contains an optional block with at least one alternative that can match an empty string\n    ;\n\nmapping_table_clause\n    : MAPPING TABLE\n    | NOMAPPING\n    ;\n\nkey_compression\n    : NOCOMPRESS\n    | COMPRESS UNSIGNED_INTEGER\n    ;\n\nindex_org_overflow_clause\n    : (INCLUDING column_name)? OVERFLOW_ segment_attributes_clause?\n    ;\n\ncolumn_clauses\n    : add_modify_drop_column_clauses\n    | rename_column_clause\n    | modify_collection_retrieval\n    | modify_lob_storage_clause\n    ;\n\nmodify_collection_retrieval\n    : MODIFY NESTED TABLE collection_item RETURN AS (LOCATOR | VALUE)\n    ;\n\ncollection_item\n    : tableview_name\n    ;\n\nrename_column_clause\n    : RENAME COLUMN old_column_name TO new_column_name\n    ;\n\nold_column_name\n    : column_name\n    ;\n\nnew_column_name\n    : column_name\n    ;\n\nadd_modify_drop_column_clauses\n    : (constraint_clauses | add_column_clause | modify_column_clauses | drop_column_clause)+\n    ;\n\ndrop_column_clause\n    : SET UNUSED (COLUMN column_name | ('(' column_name (',' column_name)* ')')) (\n        CASCADE CONSTRAINTS\n        | INVALIDATE\n    )*\n    | DROP (COLUMN column_name | '(' column_name (',' column_name)* ')') (\n        CASCADE CONSTRAINTS\n        | INVALIDATE\n    )* (CHECKPOINT UNSIGNED_INTEGER)?\n    | DROP (UNUSED COLUMNS | COLUMNS CONTINUE) (CHECKPOINT UNSIGNED_INTEGER)\n    ;\n\nmodify_column_clauses\n    : MODIFY (\n        '(' modify_col_properties (',' modify_col_properties)* ')'\n        | '(' modify_col_visibility (',' modify_col_visibility)* ')'\n        | modify_col_properties\n        | modify_col_visibility\n        | modify_col_substitutable\n    )\n    ;\n\nmodify_col_properties\n    : column_name datatype? (DEFAULT (ON NULL_)? expression)? (ENCRYPT encryption_spec | DECRYPT)? inline_constraint* lob_storage_clause? annotations_clause?\n    //TODO alter_xmlschema_clause\n    ;\n\nmodify_col_visibility\n    : column_name (VISIBLE | INVISIBLE)\n    ;\n\nmodify_col_substitutable\n    : COLUMN column_name NOT? SUBSTITUTABLE AT ALL LEVELS FORCE?\n    ;\n\nadd_column_clause\n    : ADD (\n        '(' (column_definition | virtual_column_definition) (\n            ',' (column_definition | virtual_column_definition)\n        )* ')'\n        | ( column_definition | virtual_column_definition)\n    ) column_properties?\n    ;\n\nvarray_col_properties\n    : VARRAY varray_item (\n        substitutable_column_clause? varray_storage_clause\n        | substitutable_column_clause\n    )\n    ;\n\nvarray_storage_clause\n    : STORE AS (SECUREFILE | BASICFILE)? LOB (\n        lob_segname? '(' lob_storage_parameters ')'\n        | lob_segname\n    )?\n    ;\n\nlob_segname\n    : regular_id\n    ;\n\nlob_item\n    : regular_id\n    | quoted_string\n    | DELIMITED_ID\n    ;\n\nlob_storage_parameters\n    : TABLESPACE tablespace_name = id_expression\n    | (lob_parameters storage_clause?)\n    | storage_clause\n    ;\n\nlob_storage_clause\n    : LOB (\n        '(' lob_item (',' lob_item)* ')' STORE AS (\n            (SECUREFILE | BASICFILE)\n            | '(' lob_storage_parameters* ')'\n        )+\n        | '(' lob_item ')' STORE AS (\n            (SECUREFILE | BASICFILE)\n            | lob_segname\n            | '(' lob_storage_parameters* ')'\n        )+\n    )\n    ;\n\nmodify_lob_storage_clause\n    : MODIFY LOB '(' lob_item ')' '(' modify_lob_parameters ')'\n    ;\n\nmodify_lob_parameters\n    : (\n        storage_clause\n        | (PCTVERSION | FREEPOOLS) UNSIGNED_INTEGER\n        | REBUILD FREEPOOLS\n        | lob_retention_clause\n        | lob_deduplicate_clause\n        | lob_compression_clause\n        | ENCRYPT encryption_spec\n        | DECRYPT\n        | CACHE\n        | (CACHE | NOCACHE | CACHE READS) logging_clause?\n        | allocate_extent_clause\n        | shrink_clause\n        | deallocate_unused_clause\n    )+\n    ;\n\nlob_parameters\n    : (\n        (ENABLE | DISABLE) STORAGE IN ROW\n        | CHUNK UNSIGNED_INTEGER\n        | PCTVERSION UNSIGNED_INTEGER\n        | FREEPOOLS UNSIGNED_INTEGER\n        | lob_retention_clause\n        | lob_deduplicate_clause\n        | lob_compression_clause\n        | ENCRYPT encryption_spec\n        | DECRYPT\n        | (CACHE | NOCACHE | CACHE READS) logging_clause?\n    )+\n    ;\n\nlob_deduplicate_clause\n    : DEDUPLICATE\n    | KEEP_DUPLICATES\n    ;\n\nlob_compression_clause\n    : NOCOMPRESS\n    | COMPRESS (HIGH | MEDIUM | LOW)?\n    ;\n\nlob_retention_clause\n    : RETENTION (MAX | MIN UNSIGNED_INTEGER | AUTO | NONE)?\n    ;\n\nencryption_spec\n    : (USING CHAR_STRING)? (IDENTIFIED BY REGULAR_ID)? CHAR_STRING? (NO? SALT)?\n    ;\n\ntablespace\n    : id_expression\n    ;\n\nvarray_item\n    : (id_expression '.')? (id_expression '.')? id_expression\n    ;\n\ncolumn_properties\n    : (\n        object_type_col_properties\n        | nested_table_col_properties\n        | (varray_col_properties | lob_storage_clause) (\n            '(' lob_partition_storage (',' lob_partition_storage)* ')'\n        )? //TODO '(' ( ','? lob_partition_storage)+ ')'\n        | xmltype_column_properties\n    )+\n    ;\n\nlob_partition_storage\n    : LOB (\n        '(' lob_item (',' lob_item) ')' STORE AS (\n            (SECUREFILE | BASICFILE)\n            | '(' lob_storage_parameters ')'\n        )+\n        | '(' lob_item ')' STORE AS (\n            (SECUREFILE | BASICFILE)\n            | lob_segname\n            | '(' lob_storage_parameters ')'\n        )+\n    )\n    ;\n\nperiod_definition\n    : {this.isVersion12()}? PERIOD FOR column_name ('(' start_time_column ',' end_time_column ')')?\n    ;\n\nstart_time_column\n    : column_name\n    ;\n\nend_time_column\n    : column_name\n    ;\n\ncolumn_definition\n    : column_name ((datatype | type_name) (COLLATE column_collation_name)?)? SORT? (\n        VISIBLE\n        | INVISIBLE\n    )? (DEFAULT (ON NULL_)? expression | identity_clause)? (ENCRYPT encryption_spec)? (\n        inline_constraint+\n        | inline_ref_constraint\n    )? annotations_clause?\n    ;\n\ncolumn_collation_name\n    : id_expression\n    ;\n\nidentity_clause\n    : GENERATED (ALWAYS | BY DEFAULT (ON NULL_)?)? AS IDENTITY identity_options_parentheses?\n    ;\n\n//https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-TABLE.html#GUID-F9CE0CC3-13AE-4744-A43C-EAC7A71AAAB6\n// NOTE to identity options\n// according to the SQL Reference, identity_options be nested in parentheses.\n// But statements without parentheses can also be executed successfully on a oracle database.\n// See this issue for more details: https://github.com/antlr/grammars-v4/issues/3183\nidentity_options_parentheses\n    : identity_options+\n    | '(' identity_options+ ')'\n    ;\n\nidentity_options\n    : START WITH (numeric | LIMIT VALUE)\n    | INCREMENT BY numeric\n    | MAXVALUE numeric\n    | NOMAXVALUE\n    | MINVALUE numeric\n    | NOMINVALUE\n    | CYCLE\n    | NOCYCLE\n    | CACHE numeric\n    | NOCACHE\n    | ORDER\n    | NOORDER\n    | SCALE (EXTEND | NOEXTEND)\n    | NOSCALE\n    | KEEP\n    | NOKEEP\n    ;\n\nvirtual_column_definition\n    : column_name (datatype (COLLATE column_collation_name)?)? (VISIBLE | INVISIBLE)? virtual_column_expression? VIRTUAL?\n        evaluation_edition_clause? (UNUSABLE BEFORE (CURRENT EDITION | EDITION edition_name))? (\n        UNUSABLE BEGINNING WITH ((CURRENT | NULL_) EDITION | EDITION edition_name)\n    )? inline_constraint* by_user_for_statistics_clause?\n    ;\n\nvirtual_column_expression\n    : autogenerated_sequence_definition\n    | (GENERATED ALWAYS?)? AS '(' expression ')'\n    ;\n\nautogenerated_sequence_definition\n    : GENERATED (ALWAYS | BY DEFAULT (ON NULL_)?)? AS IDENTITY (\n        '(' (sequence_start_clause | sequence_spec)* ')'\n    )?\n    ;\n\n// Oracle tools and DBMS_METADATA can return this in some use cases\n// This is used internally by Oracle to mark the virtual column for statistics only\nby_user_for_statistics_clause\n    : BY USER FOR STATISTICS\n    ;\n\nevaluation_edition_clause\n    : EVALUATE USING ((CURRENT | NULL_) EDITION | EDITION edition_name)\n    ;\n\nnested_table_col_properties\n    : NESTED TABLE (nested_item | COLUMN_VALUE) substitutable_column_clause? (LOCAL | GLOBAL)? STORE AS tableview_name (\n        '(' ('(' object_properties ')' | physical_properties | column_properties)+ ')'\n    )? (RETURN AS? (LOCATOR | VALUE))?\n    ;\n\nnested_item\n    : regular_id\n    ;\n\nsubstitutable_column_clause\n    : ELEMENT? IS OF TYPE? '(' type_name ')'\n    | NOT? SUBSTITUTABLE AT ALL LEVELS\n    ;\n\npartition_name\n    : regular_id\n    | DELIMITED_ID\n    ;\n\nsupplemental_logging_props\n    : SUPPLEMENTAL LOG (supplemental_log_grp_clause | supplemental_id_key_clause)\n    ;\n\nobject_type_col_properties\n    : COLUMN column = regular_id substitutable_column_clause\n    ;\n\nconstraint_clauses\n    : ADD '(' (out_of_line_constraint (',' out_of_line_constraint)* | out_of_line_ref_constraint) ')'\n    | ADD (out_of_line_constraint | out_of_line_ref_constraint)\n    | MODIFY (\n        CONSTRAINT constraint_name\n        | PRIMARY KEY\n        | UNIQUE '(' column_name (',' column_name)* ')'\n    ) constraint_state CASCADE?\n    | RENAME CONSTRAINT old_constraint_name TO new_constraint_name\n    | drop_constraint_clause+\n    ;\n\nold_constraint_name\n    : constraint_name\n    ;\n\nnew_constraint_name\n    : constraint_name\n    ;\n\ndrop_constraint_clause\n    : DROP (\n        PRIMARY KEY\n        | UNIQUE '(' column_name (',' column_name)* ')'\n        | CONSTRAINT constraint_name\n    ) CASCADE? ((KEY | DROP) INDEX)? ONLINE?\n    ;\n\ncheck_constraint\n    : CHECK '(' condition ')' DISABLE?\n    ;\n\nforeign_key_clause\n    : FOREIGN KEY paren_column_list references_clause on_delete_clause?\n    ;\n\nreferences_clause\n    : REFERENCES tableview_name paren_column_list? (ON DELETE (CASCADE | SET NULL_))?\n    ;\n\non_delete_clause\n    : ON DELETE (CASCADE | SET NULL_)\n    ;\n\n// Anonymous PL/SQL code block\n\nanonymous_block\n    : (DECLARE seq_of_declare_specs?)? BEGIN seq_of_statements (EXCEPTION exception_handler+)? END\n    ;\n\n// Common DDL Clauses\n\ninvoker_rights_clause\n    : AUTHID (CURRENT_USER | DEFINER)\n    ;\n\ncall_spec\n    : java_spec\n    | c_spec\n    ;\n\n// Call Spec Specific Clauses\n\njava_spec\n    : LANGUAGE JAVA NAME CHAR_STRING\n    ;\n\nc_spec\n    : (LANGUAGE C_LETTER | EXTERNAL) (\n        NAME id_expression LIBRARY identifier\n        | LIBRARY identifier (NAME id_expression)?\n    ) c_agent_in_clause? (WITH CONTEXT)? c_parameters_clause?\n    ;\n\nc_agent_in_clause\n    : AGENT IN '(' expressions_ ')'\n    ;\n\nc_parameters_clause\n    : PARAMETERS '(' c_external_parameter (',' c_external_parameter)* ')'\n    ;\n\nc_external_parameter\n    : CONTEXT\n    | SELF (TDO | c_property)?\n    | (parameter_name | RETURN) c_property? (BY REFERENCE)? external_datatype = regular_id?\n    ;\n\nc_property\n    : INDICATOR (STRUCT | TDO)?\n    | LENGTH\n    | DURATION\n    | MAXLEN\n    | CHARSETID\n    | CHARSETFORM\n    ;\n\nparameter\n    : parameter_name (IN | OUT | INOUT | NOCOPY)* type_spec? default_value_part?\n    ;\n\ndefault_value_part\n    : (ASSIGN_OP | DEFAULT) expression\n    ;\n\n// Elements Declarations\n\nseq_of_declare_specs\n    : declare_spec+\n    ;\n\ndeclare_spec\n    : pragma_declaration\n    | exception_declaration\n    | procedure_spec\n    | function_spec\n    | variable_declaration\n    | subtype_declaration\n    | cursor_declaration\n    | type_declaration\n    | procedure_body\n    | function_body\n    | selection_directive\n    ;\n\n// incorporates constant_declaration\nvariable_declaration\n    : identifier CONSTANT? type_spec (NOT? NULL_)? default_value_part? ';'\n    ;\n\nsubtype_declaration\n    : SUBTYPE identifier IS type_spec (RANGE expression '..' expression)? (NOT NULL_)? ';'\n    ;\n\n// cursor_declaration incorportates curscursor_body and cursor_spec\n\ncursor_declaration\n    : CURSOR identifier ('(' parameter_spec (',' parameter_spec)* ')')? (RETURN type_spec)? (\n        IS select_statement\n    )? ';'\n    ;\n\nparameter_spec\n    : parameter_name (IN? type_spec)? default_value_part?\n    ;\n\nexception_declaration\n    : identifier EXCEPTION ';'\n    ;\n\npragma_declaration\n    : PRAGMA (\n        SERIALLY_REUSABLE\n        | AUTONOMOUS_TRANSACTION\n        | EXCEPTION_INIT '(' exception_name ',' numeric_negative ')'\n        | INLINE '(' id1 = identifier ',' expression ')'\n        | RESTRICT_REFERENCES '(' (identifier | DEFAULT) (',' identifier)+ ')'\n        | DEPRECATE '(' identifier ( ',' CHAR_STRING)? ')'\n        | UDF\n    ) ';'\n    ;\n\n// Record Declaration Specific Clauses\n\n// incorporates ref_cursor_type_definition\n\nrecord_type_def\n    : RECORD '(' field_spec (',' field_spec)* ')'\n    ;\n\nfield_spec\n    : column_name type_spec? (NOT NULL_)? default_value_part?\n    ;\n\nref_cursor_type_def\n    : REF CURSOR (RETURN type_spec)?\n    ;\n\ntype_declaration\n    : TYPE identifier IS (table_type_def | varray_type_def | record_type_def | ref_cursor_type_def) ';'\n    ;\n\ntable_type_def\n    : TABLE OF type_spec (NOT NULL_)? table_indexed_by_part?\n    ;\n\ntable_indexed_by_part\n    : (idx1 = INDEXED | idx2 = INDEX) BY type_spec\n    ;\n\n//https://docs.oracle.com/en/database/oracle/oracle-database/21/lnpls/collection-variable.html#GUID-89A1863C-65A1-40CF-9392-86E9FDC21BE9\nvarray_type_def\n    : (VARRAY | VARYING? ARRAY) '(' expression ')' OF type_spec (NOT NULL_)?\n    ;\n\n// Statements\n\nseq_of_statements\n    : (pragma_declaration* statement (';' | EOF) | label_declaration | selection_directive)+\n    ;\n\nlabel_declaration\n    : ltp1 = '<' '<' label_name '>' '>'\n    ;\n\nstatement\n    : body\n    | block\n    | assignment_statement\n    | continue_statement\n    | exit_statement\n    | goto_statement\n    | if_statement\n    | loop_statement\n    | forall_statement\n    | null_statement\n    | raise_statement\n    | return_statement\n    | case_statement\n    | sql_statement\n    | call_statement\n    | pipe_row_statement\n    | grant_statement\n    ;\n\nassignment_statement\n    : (general_element | bind_variable) ASSIGN_OP expression\n    ;\n\ncontinue_statement\n    : CONTINUE label_name? (WHEN condition)?\n    ;\n\nexit_statement\n    : EXIT label_name? (WHEN condition)?\n    ;\n\ngoto_statement\n    : GOTO label_name\n    ;\n\nif_statement\n    : IF condition THEN seq_of_statements elsif_part* else_part? END IF\n    ;\n\nelsif_part\n    : ELSIF condition THEN seq_of_statements\n    ;\n\nelse_part\n    : ELSE seq_of_statements\n    ;\n\nloop_statement\n    : label_declaration? (WHILE condition | FOR cursor_loop_param)? LOOP seq_of_statements END LOOP label_name?\n    ;\n\n// Loop Specific Clause\n\ncursor_loop_param\n    : index_name IN REVERSE? lower_bound range_separator = '..' upper_bound\n    | record_name IN (cursor_name ('(' expressions_? ')')? | '(' select_statement ')')\n    ;\n\n//https://docs.oracle.com/en/database/oracle/oracle-database/21/lnpls/FORALL-statement.html#GUID-C45B8241-F9DF-4C93-8577-C840A25963DB\nforall_statement\n    : FORALL index_name IN bounds_clause (SAVE EXCEPTIONS)? (data_manipulation_language_statements | execute_immediate)\n    ;\n\nbounds_clause\n    : lower_bound '..' upper_bound\n    | INDICES OF general_element between_bound?\n    | VALUES OF index_name\n    ;\n\nbetween_bound\n    : BETWEEN lower_bound AND upper_bound\n    ;\n\nlower_bound\n    : concatenation\n    ;\n\nupper_bound\n    : concatenation\n    ;\n\nnull_statement\n    : NULL_\n    ;\n\nraise_statement\n    : RAISE exception_name?\n    ;\n\nreturn_statement\n    : RETURN expression?\n    ;\n\ncall_statement\n    : CALL? routine_name function_argument? ('.' routine_name function_argument?)* (\n        INTO bind_variable\n    )?\n    ;\n\npipe_row_statement\n    : PIPE ROW '(' expression ')'\n    ;\n\nselection_directive\n    : DOLLAR_IF condition DOLLAR_THEN selection_directive_body (\n        DOLLAR_ELSIF selection_directive_body\n    )* (DOLLAR_ELSE selection_directive_body)? DOLLAR_END\n    ;\n\nerror_directive\n    : DOLLAR_ERROR concatenation DOLLAR_END\n    ;\n\nselection_directive_body\n    : (\n        pragma_declaration? statement ';'\n        | variable_declaration\n        | error_directive\n        | function_body\n        | procedure_body\n    )+\n    ;\n\nbody\n    : BEGIN seq_of_statements (EXCEPTION exception_handler+)? END label_name?\n    ;\n\n// Body Specific Clause\n\nexception_handler\n    : WHEN exception_name (OR exception_name)* THEN seq_of_statements\n    ;\n\ntrigger_block\n    : (DECLARE declare_spec*)? body\n    ;\n\ntps_block\n    : declare_spec* body\n    ;\n\nblock\n    : (DECLARE declare_spec*)? body\n    ;\n\n// SQL Statements\n\nsql_statement\n    : execute_immediate\n    | data_manipulation_language_statements\n    | cursor_manipulation_statements\n    | transaction_control_statements\n    | collection_method_call\n    ;\n\nexecute_immediate\n    : EXECUTE IMMEDIATE expression (\n        into_clause using_clause?\n        | using_clause dynamic_returning_clause?\n        | dynamic_returning_clause\n    )?\n    ;\n\n// Execute Immediate Specific Clause\n\ndynamic_returning_clause\n    : (RETURNING | RETURN) into_clause\n    ;\n\n// DML Statements\n\ndata_manipulation_language_statements\n    : merge_statement\n    | lock_table_statement\n    | select_statement\n    | update_statement\n    | delete_statement\n    | insert_statement\n    | explain_statement\n    ;\n\n// Cursor Manipulation Statements\n\ncursor_manipulation_statements\n    : close_statement\n    | open_statement\n    | fetch_statement\n    | open_for_statement\n    ;\n\nclose_statement\n    : CLOSE cursor_name\n    ;\n\nopen_statement\n    : OPEN cursor_name ('(' expressions_? ')')?\n    ;\n\nfetch_statement\n    : FETCH cursor_name (\n        it1 = INTO variable_or_collection (',' variable_or_collection)*\n        | BULK COLLECT INTO variable_or_collection (',' variable_or_collection)* (\n            LIMIT (numeric | variable_or_collection)\n        )?\n    )\n    ;\n\nvariable_or_collection\n    : variable_name\n    | collection_expression\n    ;\n\nopen_for_statement\n    : OPEN variable_name FOR (select_statement | expression) using_clause?\n    ;\n\n// Transaction Control SQL Statements\n\ntransaction_control_statements\n    : set_transaction_command\n    | set_constraint_command\n    | commit_statement\n    | rollback_statement\n    | savepoint_statement\n    ;\n\nset_transaction_command\n    : SET TRANSACTION (\n        READ (ONLY | WRITE)\n        | ISOLATION LEVEL (SERIALIZABLE | READ COMMITTED)\n        | USE ROLLBACK SEGMENT rollback_segment_name\n    )? (NAME quoted_string)?\n    ;\n\nset_constraint_command\n    : SET (CONSTRAINT | CONSTRAINTS) (ALL | constraint_name (',' constraint_name)*) (\n        IMMEDIATE\n        | DEFERRED\n    )\n    ;\n\n// https://docs.oracle.com/cd/E18283_01/server.112/e17118/statements_4010.htm#SQLRF01110\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/COMMIT.html\ncommit_statement\n    : COMMIT WORK? write_clause? (\n        COMMENT CHAR_STRING write_clause?\n        | FORCE (CHAR_STRING (',' numeric)? | CORRUPT_XID CHAR_STRING | CORRUPT_XID_ALL)\n    )?\n    ;\n\nwrite_clause\n    : WRITE (\n        (IMMEDIATE | BATCH)\n        | (WAIT | NOWAIT)\n        )*\n    ;\n\nrollback_statement\n    : ROLLBACK WORK? (TO SAVEPOINT? savepoint_name | FORCE quoted_string)?\n    ;\n\nsavepoint_statement\n    : SAVEPOINT savepoint_name\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/collection-method.html#GUID-7AF1A3C4-D04B-4F91-9D7B-C92C75E3A300\ncollection_method_call // collection methods invocation that could be used as a statement\n    : expression '.' (\n        (DELETE | EXTEND) ('(' index += expression (',' index += expression)* ')')?\n        | TRIM ('(' index += expression ')')?\n    )\n    ;\n\n// Dml\n\n/* TODO\n//SHOULD BE OVERRIDEN!\ncompilation_unit\n    : seq_of_statements* EOF\n    ;\n\n//SHOULD BE OVERRIDEN!\nseq_of_statements\n    : select_statement\n    | update_statement\n    | delete_statement\n    | insert_statement\n    | lock_table_statement\n    | merge_statement\n    | explain_statement\n//    | case_statement[true]\n    ;\n*/\n\nexplain_statement\n    : EXPLAIN PLAN (SET STATEMENT_ID '=' quoted_string)? (INTO tableview_name)? FOR (\n        select_statement\n        | update_statement\n        | delete_statement\n        | insert_statement\n        | merge_statement\n    )\n    ;\n\nselect_only_statement\n    : with_clause? subquery\n    ;\n\nselect_statement\n    : select_only_statement (for_update_clause | order_by_clause | offset_clause | fetch_clause)*\n    ;\n\n// Select Specific Clauses\nwith_clause\n    : WITH (function_body | procedure_body)* with_factoring_clause (',' with_factoring_clause)*\n    | WITH (function_body | procedure_body)+ (with_factoring_clause (',' with_factoring_clause)*)?\n    ;\n\nwith_factoring_clause\n    : subquery_factoring_clause\n    | subav_factoring_clause\n    ;\n\nsubquery_factoring_clause\n    : query_name paren_column_list? AS '(' subquery order_by_clause? ')' search_clause? cycle_clause?\n    ;\n\nsearch_clause\n    : SEARCH (DEPTH | BREADTH) FIRST BY column_name ASC? DESC? (NULLS FIRST)? (NULLS LAST)? (\n        ',' column_name ASC? DESC? (NULLS FIRST)? (NULLS LAST)?\n    )* SET column_name\n    ;\n\ncycle_clause\n    : CYCLE column_list SET column_name TO expression DEFAULT expression\n    ;\n\nsubav_factoring_clause\n    : subav_name = id_expression ANALYTIC VIEW AS '(' subav_clause ')'\n    ;\n\nsubav_clause\n    : USING subav_name = object_name hierarchies_clause? filter_clauses? add_calcs_clause?\n    ;\n\nhierarchies_clause\n    : HIERARCHIES '(' hier_alias += object_name (',' hier_alias += object_name)* ')'\n    ;\n\nfilter_clauses\n    : FILTER FACT '(' filter_clause (',' filter_clause)* ')'\n    ;\n\nfilter_clause\n    : (MEASURES | hier_alias = object_name) TO condition\n    ;\n\nadd_calcs_clause\n    : ADD MEASURES '(' add_calc_meas_clause (',' add_calc_meas_clause)* ')'\n    ;\n\nadd_calc_meas_clause\n    : meas_name = id_expression AS '(' expression ')'\n    ;\n\nsubquery\n    : subquery_basic_elements subquery_operation_part*\n    ;\n\nsubquery_basic_elements\n    : query_block\n    | '(' subquery ')'\n    ;\n\nsubquery_operation_part\n    : (UNION ALL? | INTERSECT | MINUS) subquery_basic_elements\n    ;\n\nquery_block\n    : SELECT (DISTINCT | UNIQUE | ALL)? selected_list into_clause? from_clause where_clause? (\n        hierarchical_query_clause\n        | group_by_clause\n    )* model_clause? order_by_clause? offset_clause? fetch_clause?\n    ;\n\nselected_list\n    : '*'\n    | select_list_elements (',' select_list_elements)*\n    ;\n\nfrom_clause\n    : FROM table_ref_list\n    ;\n\nselect_list_elements\n    : tableview_name '.' ASTERISK\n    | expression column_alias?\n    ;\n\ntable_ref_list\n    : table_ref (',' table_ref)*\n    ;\n\n// NOTE to PIVOT clause\n// according the SQL reference this should not be possible\n// according to he reality it is. Here we probably apply pivot/unpivot onto whole join clause\n// eventhough it is not enclosed in parenthesis. See pivot examples 09,10,11\n\ntable_ref\n    : table_ref_aux join_clause* (pivot_clause | unpivot_clause)?\n    ;\n\ntable_ref_aux\n    : table_ref_aux_internal flashback_query_clause* (/*{isTableAlias()}?*/ table_alias)?\n    ;\n\ntable_ref_aux_internal\n    : dml_table_expression_clause (pivot_clause | unpivot_clause)?                # table_ref_aux_internal_one\n    | '(' table_ref subquery_operation_part* ')' (pivot_clause | unpivot_clause)? # table_ref_aux_internal_two\n    | ONLY '(' dml_table_expression_clause ')'                                    # table_ref_aux_internal_thre\n    ;\n\njoin_clause\n    : query_partition_clause? (CROSS | NATURAL)? (INNER | outer_join_type)? JOIN table_ref_aux query_partition_clause? (\n        join_on_part\n        | join_using_part\n    )*\n    | (CROSS | OUTER) APPLY table_ref_aux\n    ;\n\njoin_on_part\n    : ON condition\n    ;\n\njoin_using_part\n    : USING paren_column_list\n    ;\n\nouter_join_type\n    : (FULL | LEFT | RIGHT) OUTER?\n    ;\n\nquery_partition_clause\n    : PARTITION BY (('(' (subquery | expressions_)? ')') | expressions_)\n    ;\n\nflashback_query_clause\n    : VERSIONS (PERIOD_KEYWORD FOR column_name BETWEEN | BETWEEN (SCN | TIMESTAMP)) expression AND expression\n    | AS OF ((SCN | TIMESTAMP | SNAPSHOT) expression | PERIOD_KEYWORD FOR column_name expression)\n    ;\n\npivot_clause\n    : PIVOT XML? '(' pivot_element (',' pivot_element)* pivot_for_clause pivot_in_clause ')' table_alias?\n    ;\n\npivot_element\n    : (numeric_function | aggregate_function_name '(' expression ')') column_alias?\n    ;\n\npivot_for_clause\n    : FOR (column_name | paren_column_list)\n    ;\n\npivot_in_clause\n    : IN '(' (subquery | ANY (',' ANY)* | pivot_in_clause_element (',' pivot_in_clause_element)*) ')'\n    ;\n\npivot_in_clause_element\n    : pivot_in_clause_elements column_alias?\n    ;\n\npivot_in_clause_elements\n    : expression\n    | '(' expressions_? ')'\n    ;\n\nunpivot_clause\n    : UNPIVOT ((INCLUDE | EXCLUDE) NULLS)? '(' (column_name | paren_column_list) pivot_for_clause unpivot_in_clause ')' table_alias?\n    ;\n\nunpivot_in_clause\n    : IN '(' unpivot_in_elements (',' unpivot_in_elements)* ')'\n    ;\n\nunpivot_in_elements\n    : (column_name | paren_column_list) (AS (constant | '(' constant (',' constant)* ')'))?\n    ;\n\nhierarchical_query_clause\n    : CONNECT BY NOCYCLE? condition start_part?\n    | start_part CONNECT BY NOCYCLE? condition\n    ;\n\nstart_part\n    : START WITH condition\n    ;\n\ngroup_by_clause\n    : GROUP BY group_by_elements (',' group_by_elements)* having_clause?\n    | having_clause (GROUP BY group_by_elements (',' group_by_elements)*)?\n    ;\n\ngroup_by_elements\n    : grouping_sets_clause\n    | rollup_cube_clause\n    | expression\n    ;\n\nrollup_cube_clause\n    : (ROLLUP | CUBE) '(' grouping_sets_elements (',' grouping_sets_elements)* ')'\n    ;\n\ngrouping_sets_clause\n    : GROUPING SETS '(' grouping_sets_elements (',' grouping_sets_elements)* ')'\n    ;\n\ngrouping_sets_elements\n    : rollup_cube_clause\n    | '(' expressions_? ')'\n    | expression\n    ;\n\nhaving_clause\n    : HAVING condition\n    ;\n\nmodel_clause\n    : MODEL cell_reference_options* return_rows_clause? reference_model* main_model\n    ;\n\ncell_reference_options\n    : (IGNORE | KEEP) NAV\n    | UNIQUE (DIMENSION | SINGLE REFERENCE)\n    ;\n\nreturn_rows_clause\n    : RETURN (UPDATED | ALL) ROWS\n    ;\n\nreference_model\n    : REFERENCE reference_model_name ON '(' subquery ')' model_column_clauses cell_reference_options*\n    ;\n\nmain_model\n    : (MAIN main_model_name)? model_column_clauses cell_reference_options* model_rules_clause\n    ;\n\nmodel_column_clauses\n    : model_column_partition_part? DIMENSION BY model_column_list MEASURES model_column_list\n    ;\n\nmodel_column_partition_part\n    : PARTITION BY model_column_list\n    ;\n\nmodel_column_list\n    : '(' model_column (',' model_column)* ')'\n    ;\n\nmodel_column\n    : (expression | query_block) column_alias?\n    ;\n\nmodel_rules_clause\n    : model_rules_part? '(' (model_rules_element (',' model_rules_element)*)? ')'\n    ;\n\nmodel_rules_part\n    : RULES (UPDATE | UPSERT ALL?)? ((AUTOMATIC | SEQUENTIAL) ORDER)? model_iterate_clause?\n    ;\n\nmodel_rules_element\n    : (UPDATE | UPSERT ALL?)? cell_assignment order_by_clause? '=' expression\n    ;\n\ncell_assignment\n    : model_expression\n    ;\n\nmodel_iterate_clause\n    : ITERATE '(' expression ')' until_part?\n    ;\n\nuntil_part\n    : UNTIL '(' condition ')'\n    ;\n\norder_by_clause\n    : ORDER SIBLINGS? BY order_by_elements (',' order_by_elements)*\n    ;\n\norder_by_elements\n    : expression (ASC | DESC)? (NULLS (FIRST | LAST))?\n    ;\n\noffset_clause\n    : OFFSET expression (ROW | ROWS)\n    ;\n\nfetch_clause\n    : FETCH (FIRST | NEXT) (expression PERCENT_KEYWORD?)? (ROW | ROWS) (ONLY | WITH TIES)\n    ;\n\nfor_update_clause\n    : FOR UPDATE for_update_of_part? for_update_options?\n    ;\n\nfor_update_of_part\n    : OF column_list\n    ;\n\nfor_update_options\n    : SKIP_ LOCKED\n    | NOWAIT\n    | WAIT expression\n    ;\n\nupdate_statement\n    : UPDATE general_table_ref update_set_clause where_clause? static_returning_clause? error_logging_clause?\n    ;\n\n// Update Specific Clauses\n\nupdate_set_clause\n    : SET (\n        column_based_update_set_clause (',' column_based_update_set_clause)*\n        | VALUE '(' identifier ')' '=' expression\n    )\n    ;\n\ncolumn_based_update_set_clause\n    : column_name '=' expression\n    | paren_column_list '=' subquery\n    ;\n\ndelete_statement\n    : DELETE FROM? general_table_ref where_clause? static_returning_clause? error_logging_clause?\n    ;\n\ninsert_statement\n    : INSERT (single_table_insert | multi_table_insert)\n    ;\n\n// Insert Specific Clauses\n\nsingle_table_insert\n    : insert_into_clause (values_clause static_returning_clause? | select_statement) error_logging_clause?\n    ;\n\nmulti_table_insert\n    : (ALL multi_table_element+ | conditional_insert_clause) select_statement\n    ;\n\nmulti_table_element\n    : insert_into_clause values_clause? error_logging_clause?\n    ;\n\nconditional_insert_clause\n    : (ALL | FIRST)? conditional_insert_when_part+ conditional_insert_else_part?\n    ;\n\nconditional_insert_when_part\n    : WHEN condition THEN multi_table_element+\n    ;\n\nconditional_insert_else_part\n    : ELSE multi_table_element+\n    ;\n\ninsert_into_clause\n    : INTO general_table_ref (FIELDS)? paren_column_list?\n    ;\n\nvalues_clause\n    : VALUES (REGULAR_ID | '(' expressions_ ')' | collection_expression)\n    ;\n\nmerge_statement\n    : MERGE INTO tableview_name table_alias? USING selected_tableview ON '(' condition ')' (\n        merge_update_clause merge_insert_clause?\n        | merge_insert_clause merge_update_clause?\n    )? error_logging_clause?\n    ;\n\n// Merge Specific Clauses\n\nmerge_update_clause\n    : WHEN MATCHED THEN UPDATE SET merge_element (',' merge_element)* where_clause? merge_update_delete_part?\n    ;\n\nmerge_element\n    : column_name '=' expression\n    ;\n\nmerge_update_delete_part\n    : DELETE where_clause\n    ;\n\nmerge_insert_clause\n    : WHEN NOT MATCHED THEN INSERT paren_column_list? values_clause where_clause?\n    ;\n\nselected_tableview\n    : ( tableview_name | '(' select_statement ')' | table_collection_expression | '(' table_collection_expression ')') table_alias?\n    ;\n\nlock_table_statement\n    : LOCK TABLE lock_table_element (',' lock_table_element)* IN lock_mode MODE wait_nowait_part?\n    ;\n\nwait_nowait_part\n    : WAIT expression\n    | NOWAIT\n    ;\n\n// Lock Specific Clauses\n\nlock_table_element\n    : tableview_name partition_extension_clause?\n    ;\n\nlock_mode\n    : ROW SHARE\n    | ROW EXCLUSIVE\n    | SHARE UPDATE?\n    | SHARE ROW EXCLUSIVE\n    | EXCLUSIVE\n    ;\n\n// Common DDL Clauses\n\ngeneral_table_ref\n    : (dml_table_expression_clause | ONLY '(' dml_table_expression_clause ')') table_alias?\n    ;\n\nstatic_returning_clause\n    : (RETURNING | RETURN) expressions_ into_clause\n    ;\n\nerror_logging_clause\n    : LOG ERRORS error_logging_into_part? expression? error_logging_reject_part?\n    ;\n\nerror_logging_into_part\n    : INTO tableview_name\n    ;\n\nerror_logging_reject_part\n    : REJECT LIMIT (UNLIMITED | expression)\n    ;\n\ndml_table_expression_clause\n    : table_collection_expression\n    | '(' select_statement subquery_restriction_clause? ')'\n    | tableview_name hierarchies_clause? sample_clause?\n    | json_table_clause (AS identifier)?\n    | LATERAL '(' subquery subquery_restriction_clause? ')'\n    // Deprecated Oracle 10/11 RELATIONAL alias for casting object-types to relational tables\n    | {this.isVersion11()}? (RELATIONAL '(' tableview_name NOT XMLTYPE ')')\n    ;\n\ntable_collection_expression\n    : (TABLE | THE) ('(' subquery ')' | '(' expression ')' outer_join_sign?)\n    ;\n\nsubquery_restriction_clause\n    : WITH (READ ONLY | CHECK OPTION (CONSTRAINT constraint_name)?)\n    ;\n\nsample_clause\n    : SAMPLE BLOCK? '(' expression (',' expression)? ')' seed_part?\n    ;\n\nseed_part\n    : SEED '(' expression ')'\n    ;\n\n// Expression & Condition\n\ncondition\n    : expression\n    | JSON_EQUAL '(' expressions_ ')'\n    ;\n\nexpressions_\n    : expression (',' expression)*\n    ;\n\nexpression\n    : cursor_expression\n    | logical_expression\n    ;\n\ncursor_expression\n    : CURSOR '(' subquery ')'\n    ;\n\nlogical_expression\n    : unary_logical_expression\n    | logical_expression AND logical_expression\n    | logical_expression OR logical_expression\n    ;\n\nunary_logical_expression\n    : NOT? multiset_expression unary_logical_operation?\n    ;\n\nunary_logical_operation\n    : IS NOT? logical_operation\n    ;\n\nlogical_operation\n    : (\n        NULL_\n        | NAN_\n        | PRESENT\n        | INFINITE\n        | A_LETTER SET\n        | EMPTY_\n        | OF TYPE? '(' ONLY? type_spec (',' type_spec)* ')'\n        | JSON (FORMAT JSON)? (STRICT | LAX)? ((WITH | WITHOUT) UNIQUE KEYS)?\n    )\n    ;\n\nmultiset_expression\n    : relational_expression (multiset_type = NOT? (MEMBER | SUBMULTISET) OF? concatenation)?\n    | multiset_expression MULTISET multiset_operator = (EXCEPT | INTERSECT | UNION) (\n        ALL\n        | DISTINCT\n    )? relational_expression\n    ;\n\nrelational_expression\n    : relational_expression relational_operator relational_expression\n    | relational_expression NOT? IN in_elements\n    | compound_expression\n    ;\n\ncompound_expression\n    : concatenation (\n        NOT? (\n            IN in_elements\n            | BETWEEN between_elements\n            | like_type = (LIKE | LIKEC | LIKE2 | LIKE4) concatenation (ESCAPE concatenation)?\n        )\n    )?\n    ;\n\nrelational_operator\n    : '='\n    | (NOT_EQUAL_OP | '<' '>' | '!' '=' | '^' '=')\n    | ('<' | '>') '='?\n    ;\n\nin_elements\n    : '(' subquery ')'\n    | '(' concatenation (',' concatenation)* ')'\n    | constant\n    | bind_variable\n    | general_element\n    ;\n\nbetween_elements\n    : concatenation AND concatenation\n    ;\n\nconcatenation\n    : model_expression (AT (LOCAL | TIME ZONE concatenation) | interval_expression)? (\n        ON OVERFLOW_ (TRUNCATE | ERROR)\n    )?\n    | concatenation op = DOUBLE_ASTERISK concatenation\n    | concatenation op = (ASTERISK | SOLIDUS | MOD) concatenation\n    | concatenation op = (PLUS_SIGN | MINUS_SIGN) concatenation\n    | concatenation BAR BAR concatenation\n    | concatenation COLLATE column_collation_name\n    ;\n\ninterval_expression\n    : DAY ('(' concatenation ')')? TO SECOND ('(' concatenation ')')?\n    | YEAR ('(' concatenation ')')? TO MONTH\n    | concatenation (SECOND | DAY | MONTH | YEAR)\n    ;\n\nmodel_expression\n    : unary_expression ('[' model_expression_element ']')?\n    ;\n\nmodel_expression_element\n    : (ANY | expression) (',' (ANY | expression))*\n    | single_column_for_loop (',' single_column_for_loop)*\n    | multi_column_for_loop\n    ;\n\nsingle_column_for_loop\n    : FOR column_name (\n        IN '(' expressions_? ')'\n        | (LIKE expression)? FROM fromExpr = expression TO toExpr = expression action_type = (\n            INCREMENT\n            | DECREMENT\n        ) action_expr = expression\n    )\n    ;\n\nmulti_column_for_loop\n    : FOR paren_column_list IN '(' (subquery | '(' expressions_? ')') ')'\n    ;\n\nunary_expression\n    : ('-' | '+') unary_expression\n    | PRIOR unary_expression\n    | CONNECT_BY_ROOT unary_expression\n    | /*TODO {input.LT(1).getText().equalsIgnoreCase(\"new\") && !input.LT(2).getText().equals(\".\")}?*/ NEW unary_expression\n    | DISTINCT unary_expression\n    | ALL unary_expression\n    | /*TODO{(input.LA(1) == CASE || input.LA(2) == CASE)}?*/ case_expression\n    | unary_expression '.' (\n        (COUNT | FIRST | LAST | LIMIT)\n        | (EXISTS | NEXT | PRIOR) '(' index += expression ')'\n    )\n    | quantified_expression\n    | standard_function\n    | atom\n    | implicit_cursor_expression\n    ;\n\n// https://docs.oracle.com/en/database/oracle/oracle-database/21/lnpls/plsql-optimization-and-tuning.html#GUID-DAF46F06-EF3F-4B1A-A518-5238B80C69FA\nimplicit_cursor_expression\n    : SQL (\n        PERCENT_BULK_ROWCOUNT '(' index = expression ')'\n        | PERCENT_BULK_EXCEPTIONS ('.' COUNT | '(' expression ')' '.' (ERROR_INDEX | ERROR_CODE))\n    )\n    ;\n\ncollection_expression\n    : collation_name '(' expression ')' ('.' general_element_part)*\n    ;\n\n// CASE statement\ncase_statement\n    : searched_case_statement\n    | simple_case_statement\n    ;\n\nsimple_case_statement\n    : label_declaration? ck1 = CASE expression case_when_part_statement+ case_else_part_statement? END CASE? label_name?\n    ;\n\nsearched_case_statement\n    : label_declaration? ck1 = CASE case_when_part_statement+ case_else_part_statement? END CASE? label_name?\n    ;\n\ncase_when_part_statement\n    : WHEN expression THEN seq_of_statements\n    ;\n\ncase_else_part_statement\n    : ELSE seq_of_statements\n    ;\n\n\n// CASE expression\ncase_expression\n    : searched_case_expression\n    | simple_case_expression\n    ;\n\nsimple_case_expression\n    : ck1 = CASE expression case_when_part_expression+ case_else_part_expression? END CASE?\n    ;\n\nsearched_case_expression\n    : ck1 = CASE case_when_part_expression+ case_else_part_expression? END CASE?\n    ;\n\ncase_when_part_expression\n    : WHEN expression THEN expression\n    ;\n\ncase_else_part_expression\n    : ELSE expression\n    ;\n\natom\n    : bind_variable\n    | constant\n    | inquiry_directive\n    | general_element outer_join_sign?\n    | '(' subquery ')' subquery_operation_part*\n    | '(' expressions_ ')'\n    ;\n\nquantified_expression\n    : (SOME | EXISTS | ALL | ANY) (\n        '(' select_only_statement ')'\n        | '(' expression (',' expression)* ')'\n    )\n    ;\n\nstring_function\n    : SUBSTR '(' expression ',' expression (',' expression)? ')'\n    | TO_CHAR '(' (table_element | standard_function | expression) (',' quoted_string)? (\n        ',' quoted_string\n    )? ')'\n    | DECODE '(' expressions_ ')'\n    | CHR '(' concatenation USING NCHAR_CS ')'\n    | NVL '(' expression ',' expression ')'\n    | TRIM '(' ((LEADING | TRAILING | BOTH)? expression? FROM)? concatenation ')'\n    | TO_DATE '(' (table_element | standard_function | expression) (\n        DEFAULT concatenation ON CONVERSION ERROR\n    )? (',' quoted_string (',' quoted_string)?)? ')'\n    ;\n\nstandard_function\n    : string_function\n    | numeric_function_wrapper\n    | json_function\n    | other_function\n    ;\n\n//see as https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/JSON_ARRAY.html#GUID-46CDB3AF-5795-455B-85A8-764528CEC43B\njson_function\n    : JSON_ARRAY '(' json_array_element (',' json_array_element)* json_on_null_clause? json_return_clause? STRICT? ')'\n    | JSON_ARRAYAGG '(' expression (FORMAT JSON)? order_by_clause? json_on_null_clause? json_return_clause? STRICT? ')'\n    | JSON_OBJECT '(' json_object_content ')'\n    | JSON_OBJECTAGG '(' KEY? expression VALUE expression ((NULL_ | ABSENT) ON NULL_)? (\n        RETURNING (VARCHAR2 ('(' UNSIGNED_INTEGER ( BYTE | CHAR)? ')')? | CLOB | BLOB)\n    )? STRICT? (WITH UNIQUE KEYS)? ')'\n    | JSON_QUERY '(' expression (FORMAT JSON)? ',' CHAR_STRING json_query_returning_clause json_query_wrapper_clause? json_query_on_error_clause?\n        json_query_on_empty_clause? ')'\n    | JSON_SERIALIZE '(' CHAR_STRING (RETURNING json_query_return_type)? PRETTY? ASCII? TRUNCATE? (\n        (NULL_ | ERROR | EMPTY_ (ARRAY | OBJECT)) ON ERROR\n    )? ')'\n    | JSON_TRANSFORM '(' expression ',' json_transform_op (',' json_transform_op)* ')'\n    | JSON_VALUE '(' expression (FORMAT JSON)? (\n        ',' CHAR_STRING? json_value_return_clause? ((ERROR | NULL_ | DEFAULT literal)? ON ERROR)? (\n            (ERROR | NULL_ | DEFAULT literal)? ON EMPTY_\n        )? json_value_on_mismatch_clause? ')'\n    )?\n    ;\n\njson_object_content\n    : (json_object_entry (',' json_object_entry)* | '*') json_on_null_clause? json_return_clause? STRICT? (\n        WITH UNIQUE KEYS\n    )?\n    ;\n\njson_object_entry\n    : (KEY? expression (VALUE | IS)? expression | expression ':' expression | identifier) (\n        FORMAT JSON\n    )?\n    ;\n\njson_table_clause\n    : JSON_TABLE '(' expression (FORMAT JSON)? (',' CHAR_STRING)? ((ERROR | NULL_) ON ERROR)? (\n        (EMPTY_ | NULL_) ON EMPTY_\n    )? json_column_clause? ')'\n    ;\n\njson_array_element\n    : (expression | CHAR_STRING | NULL_ | UNSIGNED_INTEGER | json_function) (FORMAT JSON)?\n    ;\n\njson_on_null_clause\n    : (NULL_ | ABSENT) ON NULL_\n    ;\n\njson_return_clause\n    : RETURNING (VARCHAR2 ('(' UNSIGNED_INTEGER ( BYTE | CHAR)? ')')? | CLOB | BLOB)\n    ;\n\njson_transform_op\n    : REMOVE CHAR_STRING ((IGNORE | ERROR)? ON MISSING)?\n    | INSERT CHAR_STRING '=' CHAR_STRING ((REPLACE | IGNORE | ERROR) ON EXISTING)? (\n        (NULL_ | IGNORE | ERROR | REMOVE)? ON NULL_\n    )?\n    | REPLACE CHAR_STRING '=' CHAR_STRING ((CREATE | IGNORE | ERROR) ON MISSING)? (\n        (NULL_ | IGNORE | ERROR)? ON NULL_\n    )?\n    | expression (FORMAT JSON)?\n    | APPEND CHAR_STRING '=' CHAR_STRING ((CREATE | IGNORE | ERROR) ON MISSING)? (\n        (NULL_ | IGNORE | ERROR)? ON NULL_\n    )?\n    | SET CHAR_STRING '=' expression (FORMAT JSON)? ((REPLACE | IGNORE | ERROR) ON EXISTING)? (\n        (CREATE | IGNORE | ERROR) ON MISSING\n    )? ((NULL_ | IGNORE | ERROR)? ON NULL_)?\n    ;\n\njson_column_clause\n    : COLUMNS '(' json_column_definition (',' json_column_definition)* ')'\n    ;\n\njson_column_definition\n    : expression json_value_return_type? (EXISTS? PATH CHAR_STRING | TRUNCATE (PATH CHAR_STRING)?)? json_query_on_error_clause?\n        json_query_on_empty_clause?\n    | expression json_query_return_type? TRUNCATE? FORMAT JSON json_query_wrapper_clause? PATH CHAR_STRING\n    | NESTED PATH? expression ('[' ASTERISK ']')? json_column_clause\n    | expression FOR ORDINALITY\n    ;\n\njson_query_returning_clause\n    : (RETURNING json_query_return_type)? PRETTY? ASCII?\n    ;\n\njson_query_return_type\n    : VARCHAR2 ('(' UNSIGNED_INTEGER ( BYTE | CHAR)? ')')?\n    | CLOB\n    | BLOB\n    ;\n\njson_query_wrapper_clause\n    : (WITHOUT ARRAY? WRAPPER)\n    | (WITH (UNCONDITIONAL | CONDITIONAL)? ARRAY? WRAPPER)\n    ;\n\njson_query_on_error_clause\n    : (ERROR | NULL_ | EMPTY_ | EMPTY_ ARRAY | EMPTY_ OBJECT)? ON ERROR\n    ;\n\njson_query_on_empty_clause\n    : (ERROR | NULL_ | EMPTY_ | EMPTY_ ARRAY | EMPTY_ OBJECT)? ON EMPTY_\n    ;\n\njson_value_return_clause\n    : RETURNING json_value_return_type? ASCII?\n    ;\n\njson_value_return_type\n    : VARCHAR2 ('(' UNSIGNED_INTEGER ( BYTE | CHAR)? ')')? TRUNCATE?\n    | CLOB\n    | DATE\n    | NUMBER ('(' INTEGER (',' INTEGER)? ')')?\n    | TIMESTAMP (WITH TIMEZONE)?\n    | SDO_GEOMETRY\n    | expression (USING CASESENSITIVE MAPPING)?\n    ;\n\njson_value_on_mismatch_clause\n    : (IGNORE | ERROR | NULL_) ON MISMATCH ('(' MISSING DATA | EXTRA DATA | TYPE ERROR ')')?\n    ;\n\nliteral\n    : CHAR_STRING\n    | string_function\n    | numeric\n    | numeric_negative\n    | MAXVALUE\n    ;\n\nnumeric_function_wrapper\n    : numeric_function (single_column_for_loop | multi_column_for_loop)?\n    ;\n\nnumeric_function\n    : SUM '(' (DISTINCT | ALL)? expression ')'\n    | COUNT '(' (ASTERISK | ((DISTINCT | UNIQUE | ALL)? concatenation)?) ')' over_clause?\n    | ROUND '(' expression (',' UNSIGNED_INTEGER)? ')'\n    | AVG '(' (DISTINCT | ALL)? expression ')'\n    | MAX '(' (DISTINCT | ALL)? expression ')'\n    | LEAST '(' expressions_ ')'\n    | GREATEST '(' expressions_ ')'\n    ;\n\nlistagg_overflow_clause\n    : ON OVERFLOW_ (ERROR | TRUNCATE) CHAR_STRING? ((WITH | WITHOUT) COUNT)?\n    ;\n\nother_function\n    : over_clause_keyword function_argument_analytic over_clause?\n    | /*TODO stantard_function_enabling_using*/ regular_id function_argument_modeling using_clause?\n    | COUNT '(' (ASTERISK | (DISTINCT | UNIQUE | ALL)? concatenation) ')' over_clause?\n    | (CAST | XMLCAST) '(' (MULTISET '(' subquery ')' | concatenation) AS type_spec (\n        DEFAULT concatenation ON CONVERSION ERROR\n    )? (',' quoted_string (',' quoted_string)?)? ')'\n    | COALESCE '(' table_element (',' (numeric | quoted_string))? ')'\n    | COLLECT '(' (DISTINCT | UNIQUE)? concatenation collect_order_by_part? ')'\n    | within_or_over_clause_keyword function_argument within_or_over_part+\n    // Modified to allow expressions as delimiter to LISTAGG\n    | LISTAGG '(' (ALL | DISTINCT | UNIQUE)? argument (',' expression)? listagg_overflow_clause? ')' (\n        WITHIN GROUP '(' order_by_clause ')'\n    )? over_clause?\n    | cursor_name (PERCENT_ISOPEN | PERCENT_FOUND | PERCENT_NOTFOUND | PERCENT_ROWCOUNT)\n    | DECOMPOSE '(' concatenation (CANONICAL | COMPATIBILITY)? ')'\n    | EXTRACT '(' regular_id FROM concatenation ')'\n    | (FIRST_VALUE | LAST_VALUE) function_argument_analytic respect_or_ignore_nulls? over_clause\n    | (LEAD | LAG) function_argument_analytic respect_or_ignore_nulls? over_clause\n    | standard_prediction_function_keyword '(' expressions_ cost_matrix_clause? using_clause? ')'\n    | (TO_BINARY_DOUBLE | TO_BINARY_FLOAT | TO_NUMBER | TO_TIMESTAMP | TO_TIMESTAMP_TZ) '(' concatenation (\n        DEFAULT concatenation ON CONVERSION ERROR\n    )? (',' quoted_string (',' quoted_string)?)? ')'\n    | (TO_DSINTERVAL | TO_YMINTERVAL) '(' concatenation (DEFAULT concatenation ON CONVERSION ERROR)? ')'\n    | TRANSLATE '(' expression (USING (CHAR_CS | NCHAR_CS))? (',' expression)* ')'\n    | TREAT '(' expression AS REF? type_spec ')' ('.' general_element_part)*\n    | TRIM '(' ((LEADING | TRAILING | BOTH)? quoted_string? FROM)? concatenation ')'\n    | VALIDATE_CONVERSION '(' concatenation AS type_spec (',' quoted_string (',' quoted_string)?)? ')'\n    | XMLAGG '(' expression order_by_clause? ')' ('.' general_element_part)*\n    | (XMLCOLATTVAL | XMLFOREST) '(' xml_multiuse_expression_element (\n        ',' xml_multiuse_expression_element\n    )* ')' ('.' general_element_part)*\n    | XMLELEMENT '(' (ENTITYESCAPING | NOENTITYESCAPING)? (NAME | EVALNAME)? expression (\n        /*TODO{input.LT(2).getText().equalsIgnoreCase(\"xmlattributes\")}?*/ ',' xml_attributes_clause\n    )? (',' expression column_alias?)* ')' ('.' general_element_part)*\n    | XMLEXISTS '(' expression xml_passing_clause? ')'\n    | XMLPARSE '(' (DOCUMENT | CONTENT) concatenation WELLFORMED? ')' ('.' general_element_part)*\n    | XMLPI '(' (NAME identifier | EVALNAME concatenation) (',' concatenation)? ')' (\n        '.' general_element_part\n    )*\n    | XMLQUERY '(' concatenation xml_passing_clause? RETURNING CONTENT (NULL_ ON EMPTY_)? ')' (\n        '.' general_element_part\n    )*\n    | XMLROOT '(' concatenation (',' xmlroot_param_version_part)? (\n        ',' xmlroot_param_standalone_part\n    )? ')' ('.' general_element_part)*\n    | XMLSERIALIZE '(' (DOCUMENT | CONTENT) concatenation (AS type_spec)? xmlserialize_param_enconding_part? xmlserialize_param_version_part?\n        xmlserialize_param_ident_part? ((HIDE | SHOW) DEFAULTS)? ')' ('.' general_element_part)?\n    | TIME CHAR_STRING\n    | xmltable\n    ;\n\nover_clause_keyword\n    : AVG\n    | CORR\n    | LAG_DIFF\n    | LAG_DIFF_PERCENT\n    | MAX\n    | MEDIAN\n    | MIN\n    | NTH_VALUE\n    | NTILE\n    | RATIO_TO_REPORT\n    | ROW_NUMBER\n    | SUM\n    | VARIANCE\n    | REGR_\n    | STDDEV\n    | VAR_\n    | VAR_POP\n    | COVAR_\n    | WM_CONCAT\n    ;\n\nwithin_or_over_clause_keyword\n    : CUME_DIST\n    | DENSE_RANK\n    | PERCENT_RANK\n    | PERCENTILE_CONT\n    | PERCENTILE_DISC\n    | RANK\n    ;\n\nstandard_prediction_function_keyword\n    : PREDICTION\n    | PREDICTION_BOUNDS\n    | PREDICTION_COST\n    | PREDICTION_DETAILS\n    | PREDICTION_PROBABILITY\n    | PREDICTION_SET\n    ;\n\nover_clause\n    : OVER '(' (\n        query_partition_clause? (order_by_clause windowing_clause?)?\n        | HIERARCHY th = id_expression OFFSET numeric (ACROSS ANCESTOR AT LEVEL id_expression)?\n    ) ')'\n    ;\n\nwindowing_clause\n    : windowing_type (BETWEEN windowing_elements AND windowing_elements | windowing_elements)\n    ;\n\nwindowing_type\n    : ROWS\n    | RANGE\n    ;\n\nwindowing_elements\n    : UNBOUNDED PRECEDING\n    | CURRENT ROW\n    | concatenation (PRECEDING | FOLLOWING)\n    ;\n\nusing_clause\n    : USING (ASTERISK | using_element (',' using_element)*)\n    ;\n\nusing_element\n    : IN expression\n    | IN OUT assignable_element\n    | OUT assignable_element\n    | expression\n    ;\n\n// Elemento assegnabile: usato per OUT/IN OUT\nassignable_element\n    : general_element\n    | bind_variable\n    ;\n\ncollect_order_by_part\n    : ORDER BY concatenation (',' concatenation)*\n    ;\n\nwithin_or_over_part\n    : WITHIN GROUP '(' order_by_clause ')'\n    | over_clause\n    ;\n\nstring_delimiter\n    : CHAR_STRING\n    | string_function\n    | string_delimiter BAR BAR string_delimiter\n    | '(' string_delimiter ')'\n    | id_expression\n    ;\n\ncost_matrix_clause\n    : COST (\n        MODEL AUTO?\n        | '(' cost_class_name (',' cost_class_name)* ')' VALUES '(' expressions_? ')'\n    )\n    ;\n\nxml_passing_clause\n    : PASSING (BY VALUE)? expression column_alias? (',' expression column_alias?)*\n    ;\n\nxml_attributes_clause\n    : XMLATTRIBUTES '(' (ENTITYESCAPING | NOENTITYESCAPING)? (SCHEMACHECK | NOSCHEMACHECK)? xml_multiuse_expression_element (\n        ',' xml_multiuse_expression_element\n    )* ')'\n    ;\n\nxml_namespaces_clause\n    : XMLNAMESPACES '(' (concatenation column_alias)? (',' concatenation column_alias)* xml_general_default_part? ')'\n    ;\n\nxml_table_column\n    : xml_column_name (FOR ORDINALITY | type_spec (PATH concatenation)? xml_general_default_part?)\n    ;\n\nxml_general_default_part\n    : DEFAULT concatenation\n    ;\n\nxml_multiuse_expression_element\n    : expression\n        ( (AS? id_expression)\n        | (AS EVALNAME expression)\n        )?\n    ;\n\nxmlroot_param_version_part\n    : VERSION (NO VALUE | expression)\n    ;\n\nxmlroot_param_standalone_part\n    : STANDALONE (YES | NO VALUE?)\n    ;\n\nxmlserialize_param_enconding_part\n    : ENCODING concatenation\n    ;\n\nxmlserialize_param_version_part\n    : VERSION concatenation\n    ;\n\nxmlserialize_param_ident_part\n    : NO INDENT\n    | INDENT (SIZE '=' concatenation)?\n    ;\n\n// Annotations\n\nannotations_clause\n    : ANNOTATIONS '(' annotations_list ')'\n    ;\n\nannotations_list\n    : (\n        ADD (IF NOT EXISTS | OR REPLACE)?\n        | DROP (IF EXISTS)?\n        | REPLACE\n    )? annotation (',' annotations_list)*\n    ;\n\nannotation\n    : identifier CHAR_STRING?\n    ;\n\n// SqlPlus\n\nsql_plus_command\n    : EXIT\n    | PROMPT_MESSAGE\n    | SHOW (ERR | ERRORS)\n    | whenever_command\n    | timing_command\n    | start_command\n    | set_command\n    | clear_command\n    ;\n\nstart_command\n    : START_CMD id_expression PERIOD (SQL | FILE_EXT)\n    ;\n\nwhenever_command\n    : WHENEVER (SQLERROR | OSERROR) (\n        EXIT (SUCCESS | FAILURE | WARNING | variable_name | numeric) (COMMIT | ROLLBACK)?\n        | CONTINUE (COMMIT | ROLLBACK | NONE)?\n    )\n    ;\n\nset_command\n    : SET (\n        (regular_id (ON | OFF))+\n        | (regular_id (CHAR_STRING | ON | OFF | /*EXACT_NUM_LIT*/ numeric | regular_id))\n     )\n    ;\n\ntiming_command\n    : TIMING (START timing_text = id_expression* | SHOW | STOP)?\n    ;\n\nclear_command\n    : CLEAR (COLUMN? regular_id) | ALL\n    ;\n\n// Common\n\npartition_extension_clause\n    : (SUBPARTITION | PARTITION) FOR? '(' expressions_? ')'\n    ;\n\ncolumn_alias\n    : AS? (identifier | quoted_string)\n    | AS\n    ;\n\ntable_alias\n    : identifier\n    | quoted_string\n    ;\n\nwhere_clause\n    : WHERE (CURRENT OF cursor_name | condition)\n    ;\n\ninto_clause\n    : (BULK COLLECT)? INTO (general_element | bind_variable) (\n        ',' (general_element | bind_variable)\n    )*\n    ;\n\n// Common Named Elements\n\nxml_column_name\n    : identifier\n    | quoted_string\n    ;\n\ncost_class_name\n    : identifier\n    ;\n\nattribute_name\n    : identifier\n    ;\n\nsavepoint_name\n    : identifier\n    ;\n\nrollback_segment_name\n    : identifier\n    ;\n\nschema_name\n    : identifier\n    ;\n\nroutine_name\n    : identifier ('.' id_expression)* ('@' link_name)?\n    ;\n\npackage_name\n    : identifier\n    ;\n\nimplementation_type_name\n    : identifier ('.' id_expression)?\n    ;\n\nparameter_name\n    : identifier\n    ;\n\nreference_model_name\n    : identifier\n    ;\n\nmain_model_name\n    : identifier\n    ;\n\ncontainer_tableview_name\n    : identifier ('.' id_expression)?\n    ;\n\naggregate_function_name\n    : identifier ('.' id_expression)*\n    ;\n\nquery_name\n    : identifier\n    ;\n\ngrantee_name\n    : id_expression identified_by?\n    ;\n\nrole_name\n    : id_expression\n    | CONNECT\n    ;\n\nconstraint_name\n    : identifier ('.' id_expression)* ('@' link_name)?\n    ;\n\nlabel_name\n    : id_expression\n    ;\n\ntype_name\n    : id_expression ('.' id_expression)*\n    ;\n\nsequence_name\n    : id_expression ('.' id_expression)*\n    ;\n\nexception_name\n    : identifier ('.' id_expression)*\n    ;\n\nfunction_name\n    : identifier ('.' id_expression)?\n    ;\n\nprocedure_name\n    : identifier ('.' id_expression)?\n    ;\n\ntrigger_name\n    : identifier ('.' id_expression)?\n    ;\n\nvariable_name\n    : (INTRODUCER char_set_name)? id_expression ('.' id_expression)?\n    | bind_variable\n    ;\n\nindex_name\n    : identifier ('.' id_expression)?\n    ;\n\ncursor_name\n    : general_element\n    | bind_variable\n    ;\n\nrecord_name\n    : identifier\n    | bind_variable\n    ;\n\nlink_name\n    : database ('.' domain)* (AT_SIGN connection_qualifier)?\n    ;\n\nlocal_link_name\n    : identifier\n    ;\n\nconnection_qualifier\n    : identifier\n    ;\n\ncolumn_name\n    : identifier ('.' id_expression)*\n    ;\n\ntableview_name\n    : identifier ('.' id_expression)? (\n        AT_SIGN link_name\n        | /*TODO{!(input.LA(2) == BY)}?*/ partition_extension_clause\n    )?\n    | xmltable outer_join_sign?\n    ;\n\nxmltable\n    : XMLTABLE '(' (xml_namespaces_clause ',')? concatenation xml_passing_clause? (\n        COLUMNS xml_table_column (',' xml_table_column)*\n    )? ')' ('.' general_element_part)?\n    ;\n\nchar_set_name\n    : id_expression ('.' id_expression)*\n    ;\n\nsynonym_name\n    : identifier\n    ;\n\n// Represents a valid DB object name in DDL commands which are valid for several DB (or schema) objects.\n// For instance, create synonym ... for <DB object name>, or rename <old DB object name> to <new DB object name>.\n// Both are valid for sequences, tables, views, etc.\nschema_object_name\n    : id_expression\n    ;\n\ndir_object_name\n    : id_expression\n    ;\n\nuser_object_name\n    : id_expression\n    ;\n\ngrant_object_name\n    : tableview_name\n    | USER user_object_name (',' user_object_name)*\n    | DIRECTORY dir_object_name\n    | EDITION schema_object_name\n    | MINING MODEL schema_object_name\n    | JAVA (SOURCE | RESOURCE) schema_object_name\n    | SQL TRANSLATION PROFILE schema_object_name\n    ;\n\ncolumn_list\n    : column_name (',' column_name)*\n    ;\n\nparen_column_list\n    : LEFT_PAREN column_list RIGHT_PAREN\n    ;\n\n// PL/SQL Specs\n\n// NOTE: In reality this applies to aggregate functions only\nkeep_clause\n    : KEEP '(' DENSE_RANK (FIRST | LAST) (query_partition_clause | order_by_clause) ')' over_clause?\n    ;\n\nfunction_argument\n    : '(' (argument (',' argument)*)? ')' keep_clause?\n    ;\n\nfunction_argument_analytic\n    : '(' (argument respect_or_ignore_nulls? (',' argument respect_or_ignore_nulls?)*)? ')' keep_clause?\n    ;\n\nfunction_argument_modeling\n    : '(' column_name (',' (numeric | NULL_) (',' (numeric | NULL_))?)? USING (\n        tableview_name '.' ASTERISK\n        | ASTERISK\n        | expression column_alias? (',' expression column_alias?)*\n    ) ')' keep_clause?\n    ;\n\nrespect_or_ignore_nulls\n    : (RESPECT | IGNORE) NULLS\n    ;\n\nargument\n    : (identifier '=' '>')? expression\n    ;\n\ntype_spec\n    : datatype\n    | REF? type_name (PERCENT_ROWTYPE | PERCENT_TYPE)?\n    ;\n\ndatatype\n    : native_datatype_element precision_part? (WITH LOCAL? TIME ZONE | CHARACTER SET char_set_name)?\n    | INTERVAL (YEAR | DAY) ('(' expression ')')? TO (MONTH | SECOND) ('(' expression ')')?\n    ;\n\nprecision_part\n    : '(' (numeric | ASTERISK) (',' (numeric | numeric_negative))? (CHAR | BYTE)? ')'\n    ;\n\nnative_datatype_element\n    : BINARY_INTEGER\n    | PLS_INTEGER\n    | NATURAL\n    | BINARY_FLOAT\n    | BINARY_DOUBLE\n    | NATURALN\n    | POSITIVE\n    | POSITIVEN\n    | SIGNTYPE\n    | SIMPLE_INTEGER\n    | NVARCHAR2\n    | DEC\n    | INTEGER\n    | INT\n    | NUMERIC\n    | SMALLINT\n    | NUMBER\n    | DECIMAL\n    | DOUBLE PRECISION?\n    | FLOAT\n    | REAL\n    | NCHAR\n    | LONG RAW?\n    | CHAR\n    | CHARACTER VARYING?\n    | VARCHAR2\n    | VARCHAR\n    | STRING\n    | RAW\n    | BOOLEAN\n    | DATE\n    | ROWID\n    | UROWID\n    | YEAR\n    | MONTH\n    | DAY\n    | HOUR\n    | MINUTE\n    | SECOND\n    | SDO_GEOMETRY\n    | TIMEZONE_HOUR\n    | TIMEZONE_MINUTE\n    | TIMEZONE_REGION\n    | TIMEZONE_ABBR\n    | TIMESTAMP\n    | TIMESTAMP_UNCONSTRAINED\n    | TIMESTAMP_TZ_UNCONSTRAINED\n    | TIMESTAMP_LTZ_UNCONSTRAINED\n    | YMINTERVAL_UNCONSTRAINED\n    | DSINTERVAL_UNCONSTRAINED\n    | BFILE\n    | BLOB\n    | CLOB\n    | NCLOB\n    | MLSLABEL\n    | XMLTYPE\n    ;\n\nbind_variable\n    : (BINDVAR | ':' UNSIGNED_INTEGER)\n    // Pro*C/C++ indicator variables\n    (INDICATOR? (BINDVAR | ':' UNSIGNED_INTEGER))? ('.' general_element_part)*\n    ;\n\ngeneral_element\n    : general_element_part\n    | general_element ('.' general_element_part)+\n    | '(' general_element ')'\n    ;\n\ngeneral_element_part\n    : (INTRODUCER char_set_name)? id_expression ('@' link_name)? function_argument*\n    ;\n\ntable_element\n    : (INTRODUCER char_set_name)? id_expression ('.' id_expression)*\n    ;\n\nobject_privilege\n    : ALL PRIVILEGES?\n    | ALTER\n    | DEBUG\n    | DELETE\n    | EXECUTE\n    | FLASHBACK\n    | FLASHBACK ARCHIVE\n    | INDEX\n    | INHERIT PRIVILEGES\n    | INHERIT REMOTE PRIVILEGES\n    | INSERT\n    | KEEP SEQUENCE\n    | MERGE VIEW\n    | ON COMMIT REFRESH\n    | QUERY REWRITE\n    | READ\n    | REFERENCES\n    | SELECT\n    | TRANSLATE SQL\n    | UNDER\n    | UPDATE\n    | USE\n    | WRITE\n    ;\n\n//Ordered by type rather than alphabetically\nsystem_privilege\n    : ALL PRIVILEGES\n    | ADVISOR\n    | ADMINISTER ANY? SQL TUNING SET\n    | (ALTER | CREATE | DROP) ANY SQL PROFILE\n    | ADMINISTER SQL MANAGEMENT OBJECT\n    | CREATE ANY? CLUSTER\n    | (ALTER | DROP) ANY CLUSTER\n    | (CREATE | DROP) ANY CONTEXT\n    | EXEMPT REDACTION POLICY\n    | ALTER DATABASE\n    | (ALTER | CREATE) PUBLIC? DATABASE LINK\n    | DROP PUBLIC DATABASE LINK\n    | DEBUG CONNECT SESSION\n    | DEBUG ANY PROCEDURE\n    | ANALYZE ANY DICTIONARY\n    | CREATE ANY? DIMENSION\n    | (ALTER | DROP) ANY DIMENSION\n    | (CREATE | DROP) ANY DIRECTORY\n    | (CREATE | DROP) ANY EDITION\n    | FLASHBACK (ARCHIVE ADMINISTER | ANY TABLE)\n    | (ALTER | CREATE | DROP) ANY INDEX\n    | CREATE ANY? INDEXTYPE\n    | (ALTER | DROP | EXECUTE) ANY INDEXTYPE\n    | CREATE (ANY | EXTERNAL)? JOB\n    | EXECUTE ANY (CLASS | PROGRAM)\n    | MANAGE SCHEDULER\n    | ADMINISTER KEY MANAGEMENT\n    | CREATE ANY? LIBRARY\n    | (ALTER | DROP | EXECUTE) ANY LIBRARY\n    | LOGMINING\n    | CREATE ANY? MATERIALIZED VIEW\n    | (ALTER | DROP) ANY MATERIALIZED VIEW\n    | GLOBAL? QUERY REWRITE\n    | ON COMMIT REFRESH\n    | CREATE ANY? MINING MODEL\n    | (ALTER | DROP | SELECT | COMMENT) ANY MINING MODEL\n    | CREATE ANY? CUBE\n    | (ALTER | DROP | SELECT | UPDATE) ANY CUBE\n    | CREATE ANY? MEASURE FOLDER\n    | (DELETE | DROP | INSERT) ANY MEASURE FOLDER\n    | CREATE ANY? CUBE DIMENSION\n    | (ALTER | DELETE | DROP | INSERT | SELECT | UPDATE) ANY CUBE DIMENSION\n    | CREATE ANY? CUBE BUILD PROCESS\n    | (DROP | UPDATE) ANY CUBE BUILD PROCESS\n    | CREATE ANY? OPERATOR\n    | (ALTER | DROP | EXECUTE) ANY OPERATOR\n    | (CREATE | ALTER | DROP) ANY OUTLINE\n    | CREATE PLUGGABLE DATABASE\n    | SET CONTAINER\n    | CREATE ANY? PROCEDURE\n    | (ALTER | DROP | EXECUTE) ANY PROCEDURE\n    | (CREATE | ALTER | DROP) PROFILE\n    | CREATE ROLE\n    | (ALTER | DROP | GRANT) ANY ROLE\n    | (CREATE | ALTER | DROP) ROLLBACK SEGMENT\n    | CREATE ANY? SEQUENCE\n    | (ALTER | DROP | SELECT) ANY SEQUENCE\n    | (ALTER | CREATE | RESTRICTED) SESSION\n    | ALTER RESOURCE COST\n    | CREATE ANY? SQL TRANSLATION PROFILE\n    | (ALTER | DROP | USE) ANY SQL TRANSLATION PROFILE\n    | TRANSLATE ANY SQL\n    | CREATE ANY? SYNONYM\n    | DROP ANY SYNONYM\n    | (CREATE | DROP) PUBLIC SYNONYM\n    | CREATE ANY? TABLE\n    | (ALTER | BACKUP | COMMENT | DELETE | DROP | INSERT | LOCK | READ | SELECT | UPDATE) ANY TABLE\n    | (CREATE | ALTER | DROP | MANAGE | UNLIMITED) TABLESPACE\n    | CREATE ANY? TRIGGER\n    | (ALTER | DROP) ANY TRIGGER\n    | ADMINISTER DATABASE TRIGGER\n    | CREATE ANY? TYPE\n    | (ALTER | DROP | EXECUTE | UNDER) ANY TYPE\n    | (CREATE | ALTER | DROP) USER\n    | CREATE ANY? VIEW\n    | (DROP | UNDER | MERGE) ANY VIEW\n    | (ANALYZE | AUDIT) ANY\n    | BECOME USER\n    | CHANGE NOTIFICATION\n    | EXEMPT ACCESS POLICY\n    | FORCE ANY? TRANSACTION\n    | GRANT ANY OBJECT? PRIVILEGE\n    | INHERIT ANY PRIVILEGES\n    | KEEP DATE TIME\n    | KEEP SYSGUID\n    | PURGE DBA_RECYCLEBIN\n    | RESUMABLE\n    | SELECT ANY (DICTIONARY | TRANSACTION)\n    | SYSBACKUP\n    | SYSDBA\n    | SYSDG\n    | SYSKM\n    | SYSOPER\n    ;\n\n// $>\n\n// $<Lexer Mappings\n\nconstant\n    : TIMESTAMP (quoted_string | bind_variable) (AT TIME ZONE quoted_string)?\n    | INTERVAL (quoted_string | bind_variable | general_element_part) (\n        YEAR\n        | MONTH\n        | DAY\n        | HOUR\n        | MINUTE\n        | SECOND\n    ) ('(' (UNSIGNED_INTEGER | bind_variable) (',' (UNSIGNED_INTEGER | bind_variable))? ')')? (\n        TO (MONTH | DAY | HOUR | MINUTE | SECOND ('(' (UNSIGNED_INTEGER | bind_variable) ')')?)\n    )?\n    | numeric\n    | DATE quoted_string\n    | quoted_string\n    | NULL_\n    | TRUE\n    | FALSE\n    | DBTIMEZONE\n    | SESSIONTIMEZONE\n    | MINVALUE\n    | MAXVALUE\n    | DEFAULT\n    ;\n\nnumeric\n    : UNSIGNED_INTEGER '.'?\n    | APPROXIMATE_NUM_LIT\n    ;\n\nnumeric_negative\n    : MINUS_SIGN numeric\n    ;\n\nquoted_string\n    : CHAR_STRING\n    //| CHAR_STRING_PERL\n    | NATIONAL_CHAR_STRING_LIT\n    ;\n\nidentifier\n    : (INTRODUCER char_set_name)? id_expression\n    ;\n\nid_expression\n    : regular_id\n    | DELIMITED_ID\n    ;\n\ninquiry_directive\n    : INQUIRY_DIRECTIVE\n    ;\n\nouter_join_sign\n    : '(' '+' ')'\n    ;\n\nregular_id\n    : non_reserved_keywords_pre12c\n    | non_reserved_keywords_in_12c\n    | non_reserved_keywords_in_18c\n    | REGULAR_ID\n    | AUDIT\n    | ITEMS\n    | BYTES\n    | LINES\n    | RECORDS\n    | NEWLINE_\n    | FIELD\n    | MASK\n    | ABSENT\n    | A_LETTER\n    | AGENT\n    | AGGREGATE\n    | ANALYZE\n    | AUTONOMOUS_TRANSACTION\n    | BACKINGFILE\n    | BATCH\n    | BINARY_INTEGER\n    | BOOLEAN\n    | C_LETTER\n    | CHAR\n    | CHARSETID\n    | CHARSETFORM\n    | CLUSTER\n    | CONSTRUCTOR\n    | CUSTOMDATUM\n    | CASESENSITIVE\n    | DECIMAL\n    | DELETE\n    | DEPRECATE\n    | DETERMINISTIC\n    | DSINTERVAL_UNCONSTRAINED\n    | DURATION\n    | E_LETTER\n    | ENABLED\n    | ERROR_INDEX\n    | ERROR_CODE\n    | ERR\n    | EXCEPTION\n    | EXCEPTION_INIT\n    | EXCEPTIONS\n    | EXISTS\n    | EXIT\n    | EXTEND\n    | FILESTORE\n    | FLOAT\n    | FORALL\n    | G_LETTER\n    | INDICES\n    | INOUT\n    | INTEGER\n    | JSON_TRANSFORM\n    | K_LETTER\n    | LANGUAGE\n    | LONG\n    | LOOP\n    | MAXLEN\n    | MOUNTPOINT\n    | M_LETTER\n    | MISSING\n    | MISMATCH\n    | NUMBER\n    | ORADATA\n    | OSERROR\n    | OUT\n    | OVERRIDING\n    | P_LETTER\n    | PARALLEL_ENABLE\n    | PIPELINED\n    | PLS_INTEGER\n    | PMEM\n    | POSITIVE\n    | POSITIVEN\n    | PRAGMA\n    | PUBLIC\n    | RAISE\n    | RAW\n    | RECORD\n    | REF\n    | RENAME\n    | RESTRICT_REFERENCES\n    | RESULT\n    | SDO_GEOMETRY\n    | SELF\n    | SERIALLY_REUSABLE\n    | SET\n    | SEQ\n    | SHARDSPACE\n    | SIGNTYPE\n    | SIMPLE_INTEGER\n    | SMALLINT\n    | STRUCT\n    | SQLDATA\n    | SQLERROR\n    | SUBTYPE\n    | T_LETTER\n    | TDO\n    | TIMESTAMP_LTZ_UNCONSTRAINED\n    | TIMESTAMP_TZ_UNCONSTRAINED\n    | TIMESTAMP_UNCONSTRAINED\n    | TIMEZONE\n    | TRIGGER\n    | UDF\n    | VARCHAR\n    | VARCHAR2\n    | VARIABLE\n    | WARNING\n    | WHILE\n    | WM_CONCAT\n    | XMLAGG\n    | YMINTERVAL_UNCONSTRAINED\n    | REGR_\n    | VAR_\n    | VALUE\n    | COVAR_\n    ;\n\nnon_reserved_keywords_in_18c\n    : PERSISTABLE\n    | POLYMORPHIC\n    ;\n\nnon_reserved_keywords_in_12c\n    : ACL\n    | ACCESSIBLE\n    | ACROSS\n    | ACTION\n    | ACTIONS\n    | ACTIVE\n    | ACTIVE_DATA\n    | ACTIVITY\n    | ADAPTIVE_PLAN\n    | ADVANCED\n    | AFD_DISKSTRING\n    | ALTERNATE\n    | ALGORITHM\n    | ANALYTIC\n    | ANCESTOR\n    | ANOMALY\n    | ANSI_REARCH\n    | APPLICATION\n    | APPROX_COUNT_DISTINCT\n    | ARCHIVAL\n    | ARCHIVED\n    | ASIS\n    | ASSIGN\n    | AUTO_LOGIN\n    | AUTO_REOPTIMIZE\n    | AVRO\n    | BACKGROUND\n    | BACKUPS\n    | BATCHSIZE\n    | BATCH_TABLE_ACCESS_BY_ROWID\n    | BEGINNING\n    | BEQUEATH\n    | BITMAP_AND\n    | BLOCKCHAIN\n    | BSON\n    | CACHING\n    | CALCULATED\n    | CALLBACK\n    | CAPACITY\n    | CAPTION\n    | CDBDEFAULT\n    | CLASSIFICATION\n    | CLASSIFIER\n    | CLAUSE\n    | CLEAN\n    | CLEANUP\n    | CLIENT\n    | CLUSTERING\n    | CLUSTER_DETAILS\n    | CLUSTER_DISTANCE\n    | COLLATE\n    | COLLATION\n    | COMMON\n    | COMMON_DATA\n    | COMPONENT\n    | COMPONENTS\n    | CONDITION\n    | CONDITIONAL\n    | CONTAINERS\n    | CONTAINERS_DEFAULT\n    | CONTAINER_DATA\n    | CONTAINER_MAP\n    | CONVERSION\n    | CON_DBID_TO_ID\n    | CON_GUID_TO_ID\n    | CON_ID\n    | CON_NAME_TO_ID\n    | CON_UID_TO_ID\n    | COOKIE\n    | COPY\n    | CREATE_FILE_DEST\n    | CREDENTIAL\n    | CRITICAL\n    | CUBE_AJ\n    | CUBE_SJ\n    | DATAMOVEMENT\n    | DATAOBJ_TO_MAT_PARTITION\n    | DATAPUMP\n    | DATA_SECURITY_REWRITE_LIMIT\n    | DAYS\n    | DB_UNIQUE_NAME\n    | DECORRELATE\n    | DEFAULT_CREDENTIAL\n    | DEFAULT_COLLATION\n    | DEFINE\n    | DEFINITION\n    | DELEGATE\n    | DELETE_ALL\n    | DESCRIPTION\n    | DESTROY\n    | DIMENSIONS\n    | DISABLE_ALL\n    | DISABLE_PARALLEL_DML\n    | DISCARD\n    | DISTRIBUTE\n    | DUPLICATE\n    | DUPLICATED\n    | DV\n    | EDITIONABLE\n    | ELIM_GROUPBY\n    | EM\n    | ENABLE_ALL\n    | ENABLE_PARALLEL_DML\n    | EQUIPART\n    | EVAL\n    | EVALUATE\n    | EXISTING\n    | EXPRESS\n    | EXTENDED\n    | EXTRACTCLOBXML\n    | FACTOR\n    | FAILOVER\n    | FAILURE\n    | FAMILY\n    | FAR\n    | FASTSTART\n    | FEATURE\n    | FEATURE_DETAILS\n    | FETCH\n    | FILE_NAME_CONVERT\n    | FILEGROUP\n    | FIXED_VIEW_DATA\n    | FLEX\n    | FORMAT\n    | FTP\n    | GATHER_OPTIMIZER_STATISTICS\n    | GET\n    | HALF_YEARS\n    | HASHING\n    | HIER_ORDER\n    | HIERARCHICAL\n    | HOURS\n    | HTTP\n    | H_LETTER\n    | IDLE\n    | ILM\n    | IMMUTABLE\n    | INACTIVE\n    | INACTIVE_ACCOUNT_TIME\n    | INDEXING\n    | INHERIT\n    | INMEMORY\n    | INMEMORY_PRUNING\n    | INPLACE\n    | INTERLEAVED\n    | INVALIDATION\n    | ISOLATE\n    | IS_LEAF\n    | JSON\n    | JSONGET\n    | JSONPARSE\n    | JSON_ARRAY\n    | JSON_ARRAYAGG\n    | JSON_EQUAL\n    | JSON_EXISTS\n    | JSON_EXISTS2\n    | JSON_OBJECT\n    | JSON_OBJECTAGG\n    | JSON_QUERY\n    | JSON_SERIALIZE\n    | JSON_TABLE\n    | JSON_TEXTCONTAINS\n    | JSON_TEXTCONTAINS2\n    | JSON_VALUE\n    | KEYSTORE\n    | LABEL\n    | LAX\n    | LEAD_CDB\n    | LEAD_CDB_URI\n    | LEVEL_NAME\n    | LIFECYCLE\n    | LINEAR\n    | LOCKDOWN\n    | LOCKING\n    | LOGMINING\n    | LOST\n    | MANDATORY\n    | MAP\n    | MATCH\n    | MATCHES\n    | MATCH_NUMBER\n    | MATCH_RECOGNIZE\n    | MAX_SHARED_TEMP_SIZE\n    | MEMCOMPRESS\n    | METADATA\n    | MEMBER_CAPTION\n    | MEMBER_DESCRIPTION\n    | MEMBER_NAME\n    | MEMBER_UNIQUE_NAME\n    | MEMOPTIMIZE\n    | MINUTES\n    | MODEL_NB\n    | MODEL_SV\n    | MODIFICATION\n    | MODULE\n    | MONTHS\n    | MULTIDIMENSIONAL\n    | NEG\n    | NOCOPY\n    | NOKEEP\n    | NONEDITIONABLE\n    | NOPARTITION\n    | NORELOCATE\n    | NOREPLAY\n    | NO_ADAPTIVE_PLAN\n    | NO_ANSI_REARCH\n    | NO_AUTO_REOPTIMIZE\n    | NO_BATCH_TABLE_ACCESS_BY_ROWID\n    | NO_CLUSTERING\n    | NO_COMMON_DATA\n    | NO_DATA_SECURITY_REWRITE\n    | NO_DECORRELATE\n    | NO_ELIM_GROUPBY\n    | NO_GATHER_OPTIMIZER_STATISTICS\n    | NO_INMEMORY\n    | NO_INMEMORY_PRUNING\n    | NO_OBJECT_LINK\n    | NO_PARTIAL_JOIN\n    | NO_PARTIAL_ROLLUP_PUSHDOWN\n    | NO_PQ_CONCURRENT_UNION\n    | NO_PQ_REPLICATE\n    | NO_PQ_SKEW\n    | NOPROMPT\n    | NO_PX_FAULT_TOLERANCE\n    | NO_ROOT_SW_FOR_LOCAL\n    | NO_SQL_TRANSLATION\n    | NO_USE_CUBE\n    | NO_USE_VECTOR_AGGREGATION\n    | NO_VECTOR_TRANSFORM\n    | NO_VECTOR_TRANSFORM_DIMS\n    | NO_VECTOR_TRANSFORM_FACT\n    | NO_ZONEMAP\n    | OBJ_ID\n    | OFFSET\n    | OLS\n    | OMIT\n    | ONE\n    | ORACLE_DATAPUMP\n    | ORACLE_HDFS\n    | ORACLE_HIVE\n    | ORACLE_LOADER\n    | ORA_CHECK_ACL\n    | ORA_CHECK_PRIVILEGE\n    | ORA_CLUSTERING\n    | ORA_INVOKING_USER\n    | ORA_INVOKING_USERID\n    | ORA_INVOKING_XS_USER\n    | ORA_INVOKING_XS_USER_GUID\n    | ORA_RAWCOMPARE\n    | ORA_RAWCONCAT\n    | ORA_WRITE_TIME\n    | PARENT_LEVEL_NAME\n    | PARENT_UNIQUE_NAME\n    | PASSWORD_ROLLOVER_TIME\n    | PARTIAL\n    | PARTIAL_JOIN\n    | PARTIAL_ROLLUP_PUSHDOWN\n    | PAST\n    | PATCH\n    | PATH_PREFIX\n    | PATTERN\n    | PER\n    | PERIOD\n    | PERIOD_KEYWORD\n    | PERMUTE\n    | PLUGGABLE\n    | POOL_16K\n    | POOL_2K\n    | POOL_32K\n    | POOL_4K\n    | POOL_8K\n    | PQ_CONCURRENT_UNION\n    | PQ_DISTRIBUTE_WINDOW\n    | PQ_FILTER\n    | PQ_REPLICATE\n    | PQ_SKEW\n    | PRELOAD\n    | PRETTY\n    | PREV\n    | PRINTBLOBTOCLOB\n    | PRIORITY\n    | PRIVILEGED\n    | PROPERTY\n    | PROTOCOL\n    | PROXY\n    | PRUNING\n    | PX_FAULT_TOLERANCE\n    | QUARTERS\n    | QUOTAGROUP\n    | REALM\n    | REDEFINE\n    | RELOCATE\n    | REMOTE\n    | RESTART\n    | ROLESET\n    | ROWID_MAPPING_TABLE\n    | RUNNING\n    | SAVE\n    | SCRUB\n    | SDO_GEOM_MBR\n    | SECONDS\n    | SECRET\n    | SERIAL\n    | SERVICES\n    | SERVICE_NAME_CONVERT\n    | SHARDED\n    | SHARING\n    | SHELFLIFE\n    | SITE\n    | SOURCE_FILE_DIRECTORY\n    | SOURCE_FILE_NAME_CONVERT\n    | SQL_TRANSLATION_PROFILE\n    | STANDARD\n    | STANDARD_HASH\n    | STANDBYS\n    | STATE\n    | STATEMENT\n    | STREAM\n    | SUBSCRIBE\n    | SUBSET\n    | SUCCESS\n    | SYS\n    | SYSBACKUP\n    | SYSDG\n    | SYSGUID\n    | SYSKM\n    | SYSOBJ\n    | SYS_CHECK_PRIVILEGE\n    | SYS_GET_COL_ACLIDS\n    | SYS_MKXTI\n    | SYS_OP_CYCLED_SEQ\n    | SYS_OP_HASH\n    | SYS_OP_KEY_VECTOR_CREATE\n    | SYS_OP_KEY_VECTOR_FILTER\n    | SYS_OP_KEY_VECTOR_FILTER_LIST\n    | SYS_OP_KEY_VECTOR_SUCCEEDED\n    | SYS_OP_KEY_VECTOR_USE\n    | SYS_OP_PART_ID\n    | SYS_OP_ZONE_ID\n    | SYS_RAW_TO_XSID\n    | SYS_XSID_TO_RAW\n    | SYS_ZMAP_FILTER\n    | SYS_ZMAP_REFRESH\n    | TAG\n    | TEXT\n    | TIER\n    | TIES\n    | TO_ACLID\n    | TRANSFORM\n    | TRANSLATION\n    | TRUST\n    | UCS2\n    | UNCONDITIONAL\n    | UNITE\n    | UNMATCHED\n    | UNPLUG\n    | UNSUBSCRIBE\n    | USABLE\n    | USER_DATA\n    | USER_TABLESPACES\n    | USE_CUBE\n    | USE_HIDDEN_PARTITIONS\n    | USE_VECTOR_AGGREGATION\n    | USING_NO_EXPAND\n    | USING_NLS_COMP\n    | UTF16BE\n    | UTF16LE\n    | UTF32\n    | UTF8\n    | V1\n    | V2\n    | VALIDATE_CONVERSION\n    | VALID_TIME_END\n    | VECTOR_TRANSFORM\n    | VECTOR_TRANSFORM_DIMS\n    | VECTOR_TRANSFORM_FACT\n    | VERIFIER\n    | VIOLATION\n    | VISIBILITY\n    | WEEK\n    | WEEKS\n    | WITH_PLSQL\n    | WRAPPER\n    | XS\n    | YEARS\n    | ZONEMAP\n    ;\n\nnon_reserved_keywords_pre12c\n    : ABORT\n    | ABS\n    | ACCESSED\n    | ACCESS\n    | ACCOUNT\n    | ACOS\n    | ACTIVATE\n    | ACTIVE_COMPONENT\n    | ACTIVE_FUNCTION\n    | ACTIVE_TAG\n    | ADD_COLUMN\n    | ADD_GROUP\n    | ADD_MONTHS\n    | ADD\n    | ADJ_DATE\n    | ADMINISTER\n    | ADMINISTRATOR\n    | ADMIN\n    | ADVISE\n    | ADVISOR\n    | AFTER\n    | ALIAS\n    | ALLOCATE\n    | ALLOW\n    | ALL_ROWS\n    | ALWAYS\n    | ANALYZE\n    | ANCILLARY\n    | AND_EQUAL\n    | ANTIJOIN\n    | ANYSCHEMA\n    | APPENDCHILDXML\n    | APPEND\n    | APPEND_VALUES\n    | APPLY\n    | ARCHIVELOG\n    | ARCHIVE\n    | ARRAY\n    | ASCII\n    | ASCIISTR\n    | ASIN\n    | ASSEMBLY\n    | ASSOCIATE\n    | ASYNCHRONOUS\n    | ASYNC\n    | ATAN2\n    | ATAN\n    | AT\n    | ATTRIBUTE\n    | ATTRIBUTES\n    | AUTHENTICATED\n    | AUTHENTICATION\n    | AUTHID\n    | AUTHORIZATION\n    | AUTOALLOCATE\n    | AUTOEXTEND\n    | AUTOMATIC\n    | AUTO\n    | AVAILABILITY\n    | AVG\n    | BACKUP\n    | BASICFILE\n    | BASIC\n    | BATCH\n    | BECOME\n    | BEFORE\n    | BEGIN\n    | BEGIN_OUTLINE_DATA\n    | BEHALF\n    | BFILE\n    | BFILENAME\n    | BIGFILE\n    | BINARY_DOUBLE_INFINITY\n    | BINARY_DOUBLE\n    | BINARY_DOUBLE_NAN\n    | BINARY_FLOAT_INFINITY\n    | BINARY_FLOAT\n    | BINARY_FLOAT_NAN\n    | BINARY\n    | BIND_AWARE\n    | BINDING\n    | BIN_TO_NUM\n    | BITAND\n    | BITMAP\n    | BITMAPS\n    | BITMAP_TREE\n    | BITS\n    | BLOB\n    | BLOCK\n    | BLOCK_RANGE\n    | BLOCKSIZE\n    | BLOCKS\n    | BODY\n    | BOTH\n    | BOUND\n    | BRANCH\n    | BREADTH\n    | BROADCAST\n    | BUFFER_CACHE\n    | BUFFER\n    | BUFFER_POOL\n    | BUILD\n    | BULK\n    | BYPASS_RECURSIVE_CHECK\n    | BYPASS_UJVC\n    | BYTE\n    | CACHE_CB\n    | CACHE_INSTANCES\n    | CACHE\n    | CACHE_TEMP_TABLE\n    | CALL\n    | CANCEL\n    | CARDINALITY\n    | CASCADE\n    | CASE\n    | CAST\n    | CATEGORY\n    | CEIL\n    | CELL_FLASH_CACHE\n    | CERTIFICATE\n    | CFILE\n    | CHAINED\n    | CHANGE_DUPKEY_ERROR_INDEX\n    | CHANGE\n    | CHARACTER\n    | CHAR_CS\n    | CHARTOROWID\n    | CHECK_ACL_REWRITE\n    | CHECKPOINT\n    | CHILD\n    | CHOOSE\n    | CHR\n    | CHUNK\n    | CLASS\n    | CLEAR\n    | CLOB\n    | CLONE\n    | CLOSE_CACHED_OPEN_CURSORS\n    | CLOSE\n    | CLUSTER_BY_ROWID\n    | CLUSTER_ID\n    | CLUSTERING_FACTOR\n    | CLUSTER_PROBABILITY\n    | CLUSTER_SET\n    | COALESCE\n    | COALESCE_SQ\n    | COARSE\n    | CO_AUTH_IND\n    | COLD\n    | COLLECT\n    | COLUMNAR\n    | COLUMN_AUTH_INDICATOR\n    | COLUMN\n    | COLUMNS\n    | COLUMN_STATS\n    | COLUMN_VALUE\n    | COMMENT\n    | COMMIT\n    | COMMITTED\n    | COMPACT\n    | COMPATIBILITY\n    | COMPILE\n    | COMPLETE\n    | COMPLIANCE\n    | COMPOSE\n    | COMPOSITE_LIMIT\n    | COMPOSITE\n    | COMPOUND\n    | COMPUTE\n    | CONCAT\n    | CONFIRM\n    | CONFORMING\n    | CONNECT_BY_CB_WHR_ONLY\n    | CONNECT_BY_COMBINE_SW\n    | CONNECT_BY_COST_BASED\n    | CONNECT_BY_ELIM_DUPS\n    | CONNECT_BY_FILTERING\n    | CONNECT_BY_ISCYCLE\n    | CONNECT_BY_ISLEAF\n    | CONNECT_BY_ROOT\n    | CONNECT_TIME\n    | CONSIDER\n    | CONSISTENT\n    | CONSTANT\n    | CONST\n    | CONSTRAINT\n    | CONSTRAINTS\n    | CONTAINER\n    | CONTENT\n    | CONTENTS\n    | CONTEXT\n    | CONTINUE\n    | CONTROLFILE\n    | CONVERT\n    | CORR_K\n    | CORR\n    | CORR_S\n    | CORRUPTION\n    | CORRUPT_XID_ALL\n    | CORRUPT_XID\n    | COSH\n    | COS\n    | COST\n    | COST_XML_QUERY_REWRITE\n    | COUNT\n    | COVAR_POP\n    | COVAR_SAMP\n    | CPU_COSTING\n    | CPU_PER_CALL\n    | CPU_PER_SESSION\n    | CRASH\n    | CREATE_STORED_OUTLINES\n    | CREATION\n    | CROSSEDITION\n    | CROSS\n    | CSCONVERT\n    | CUBE_GB\n    | CUBE\n    | CUME_DISTM\n    | CUME_DIST\n    | CURRENT_DATE\n    | CURRENT\n    | CURRENT_SCHEMA\n    | CURRENT_TIME\n    | CURRENT_TIMESTAMP\n    | CURRENT_USER\n    | CURRENTV\n    | CURSOR\n    | CURSOR_SHARING_EXACT\n    | CURSOR_SPECIFIC_SEGMENT\n    | CV\n    | CYCLE\n    | DANGLING\n    | DATABASE\n    | DATAFILE\n    | DATAFILES\n    | DATA\n    | DATAOBJNO\n    | DATAOBJ_TO_PARTITION\n    | DATE_MODE\n    | DAY\n    | DBA\n    | DBA_RECYCLEBIN\n    | DBLINK\n    | DBMS_STATS\n    | DB_ROLE_CHANGE\n    | DBTIMEZONE\n    | DB_VERSION\n    | DDL\n    | DEALLOCATE\n    | DEBUGGER\n    | DEBUG\n    | DECLARE\n    | DEC\n    | DECOMPOSE\n    | DECREMENT\n    | DECR\n    | DECRYPT\n    | DEDUPLICATE\n    | DEFAULTS\n    | DEFERRABLE\n    | DEFERRED\n    | DEFINED\n    | DEFINER\n    | DEGREE\n    | DELAY\n    | DELETEXML\n    | DEMAND\n    | DENSE_RANKM\n    | DENSE_RANK\n    | DEPENDENT\n    | DEPTH\n    | DEQUEUE\n    | DEREF\n    | DEREF_NO_REWRITE\n    | DETACHED\n    | DETERMINES\n    | DICTIONARY\n    | DIMENSION\n    | DIRECT_LOAD\n    | DIRECTORY\n    | DIRECT_PATH\n    | DISABLE\n    | DISABLE_PRESET\n    | DISABLE_RPKE\n    | DISALLOW\n    | DISASSOCIATE\n    | DISCONNECT\n    | DISKGROUP\n    | DISK\n    | DISKS\n    | DISMOUNT\n    | DISTINGUISHED\n    | DISTRIBUTED\n    | DML\n    | DML_UPDATE\n    | DOCFIDELITY\n    | DOCUMENT\n    | DOMAIN_INDEX_FILTER\n    | DOMAIN_INDEX_NO_SORT\n    | DOMAIN_INDEX_SORT\n    | DOUBLE\n    | DOWNGRADE\n    | DRIVING_SITE\n    | DROP_COLUMN\n    | DROP_GROUP\n    | DST_UPGRADE_INSERT_CONV\n    | DUMP\n    | DYNAMIC\n    | DYNAMIC_SAMPLING_EST_CDN\n    | DYNAMIC_SAMPLING\n    | EACH\n    | EDITIONING\n    | EDITION\n    | EDITIONS\n    | ELEMENT\n    | ELIMINATE_JOIN\n    | ELIMINATE_OBY\n    | ELIMINATE_OUTER_JOIN\n    | EMPTY_BLOB\n    | EMPTY_CLOB\n    | EMPTY_\n    | ENABLE\n    | ENABLE_PRESET\n    | ENCODING\n    | ENCRYPTION\n    | ENCRYPT\n    | END_OUTLINE_DATA\n    | ENFORCED\n    | ENFORCE\n    | ENQUEUE\n    | ENTERPRISE\n    | ENTITYESCAPING\n    | ENTRY\n    | ERROR_ARGUMENT\n    | ERROR\n    | ERROR_ON_OVERLAP_TIME\n    | ERRORS\n    | ESCAPE\n    | ESTIMATE\n    | EVALNAME\n    | EVALUATION\n    | EVENTS\n    | EVERY\n    | EXCEPTIONS\n    | EXCEPT\n    | EXCHANGE\n    | EXCLUDE\n    | EXCLUDING\n    | EXECUTE\n    | EXEMPT\n    | EXISTSNODE\n    | EXPAND_GSET_TO_UNION\n    | EXPAND_TABLE\n    | EXPIRE\n    | EXPLAIN\n    | EXPLOSION\n    | EXP\n    | EXPORT\n    | EXPR_CORR_CHECK\n    | EXTENDS\n    | EXTENT\n    | EXTENTS\n    | EXTERNALLY\n    | EXTERNAL\n    | EXTRACT\n    | EXTRACTVALUE\n    | EXTRA\n    | FACILITY\n    | FACT\n    | FACTORIZE_JOIN\n    | FAILED_LOGIN_ATTEMPTS\n    | FAILED\n    | FAILGROUP\n    | FALSE\n    | FAST\n    | FBTSCAN\n    | FEATURE_ID\n    | FEATURE_SET\n    | FEATURE_VALUE\n    | FILE\n    | FILESYSTEM_LIKE_LOGGING\n    | FILTER\n    | FINAL\n    | FINE\n    | FINISH\n    | FIRSTM\n    | FIRST\n    | FIRST_ROWS\n    | FIRST_VALUE\n    | FLAGGER\n    | FLASHBACK\n    | FLASH_CACHE\n    | FLOB\n    | FLOOR\n    | FLUSH\n    | FOLDER\n    | FOLLOWING\n    | FOLLOWS\n    | FORCE\n    | FORCE_XML_QUERY_REWRITE\n    | FOREIGN\n    | FOREVER\n    | FORWARD\n    | FRAGMENT_NUMBER\n    | FREELIST\n    | FREELISTS\n    | FREEPOOLS\n    | FRESH\n    | FROM_TZ\n    | FULL\n    | FULL_OUTER_JOIN_TO_OUTER\n    | FUNCTION\n    | FUNCTIONS\n    | GATHER_PLAN_STATISTICS\n    | GBY_CONC_ROLLUP\n    | GBY_PUSHDOWN\n    | GENERATED\n    | GLOBALLY\n    | GLOBAL\n    | GLOBAL_NAME\n    | GLOBAL_TOPIC_ENABLED\n    | GREATEST\n    | GROUP_BY\n    | GROUP_ID\n    | GROUPING_ID\n    | GROUPING\n    | GROUPS\n    | GUARANTEED\n    | GUARANTEE\n    | GUARD\n    | HASH_AJ\n    | HASHKEYS\n    | HASH\n    | HASH_SJ\n    | HEADER\n    | HEAP\n    | HELP\n    | HEXTORAW\n    | HEXTOREF\n    | HIDDEN_KEYWORD\n    | HIDE\n    | HIERARCHY\n    | HIGH\n    | HINTSET_BEGIN\n    | HINTSET_END\n    | HOT\n    | HOUR\n    | HWM_BROKERED\n    | HYBRID\n    | IDENTIFIER\n    | IDENTITY\n    | IDGENERATORS\n    | IDLE_TIME\n    | ID\n    | IF\n    | IGNORE\n    | IGNORE_OPTIM_EMBEDDED_HINTS\n    | IGNORE_ROW_ON_DUPKEY_INDEX\n    | IGNORE_WHERE_CLAUSE\n    | IMMEDIATE\n    | IMPACT\n    | IMPORT\n    | INCLUDE\n    | INCLUDE_VERSION\n    | INCLUDING\n    | INCREMENTAL\n    | INCREMENT\n    | INCR\n    | INDENT\n    | INDEX_ASC\n    | INDEX_COMBINE\n    | INDEX_DESC\n    | INDEXED\n    | INDEXES\n    | INDEX_FFS\n    | INDEX_FILTER\n    | INDEX_JOIN\n    | INDEX_ROWS\n    | INDEX_RRS\n    | INDEX_RS_ASC\n    | INDEX_RS_DESC\n    | INDEX_RS\n    | INDEX_SCAN\n    | INDEX_SKIP_SCAN\n    | INDEX_SS_ASC\n    | INDEX_SS_DESC\n    | INDEX_SS\n    | INDEX_STATS\n    | INDEXTYPE\n    | INDEXTYPES\n    | INDICATOR\n    | INFINITE\n    | INFORMATIONAL\n    | INITCAP\n    | INITIALIZED\n    | INITIALLY\n    | INITIAL\n    | INITRANS\n    | INLINE\n    | INLINE_XMLTYPE_NT\n    | IN_MEMORY_METADATA\n    | INNER\n    | INSERTCHILDXMLAFTER\n    | INSERTCHILDXMLBEFORE\n    | INSERTCHILDXML\n    | INSERTXMLAFTER\n    | INSERTXMLBEFORE\n    | INSTANCE\n    | INSTANCES\n    | INSTANTIABLE\n    | INSTANTLY\n    | INSTEAD\n    | INSTR2\n    | INSTR4\n    | INSTRB\n    | INSTRC\n    | INSTR\n    | INTERMEDIATE\n    | INTERNAL_CONVERT\n    | INTERNAL_USE\n    | INTERPRETED\n    | INTERVAL\n    | INT\n    | INVALIDATE\n    | INVISIBLE\n    | IN_XQUERY\n    | ISOLATION_LEVEL\n    | ISOLATION\n    | ITERATE\n    | ITERATION_NUMBER\n    | JAVA\n    | JOB\n    | JOIN\n    | KEEP_DUPLICATES\n    | KEEP\n    | KERBEROS\n    | KEY_LENGTH\n    | KEY\n    | KEYSIZE\n    | KEYS\n    | KILL\n    | LAG\n    | LAST_DAY\n    | LAST\n    | LAST_VALUE\n    | LATERAL\n    | LAYER\n    | LDAP_REGISTRATION_ENABLED\n    | LDAP_REGISTRATION\n    | LDAP_REG_SYNC_INTERVAL\n    | LEADING\n    | LEAD\n    | LEAF\n    | LEAST\n    | LEFT\n    | LENGTH2\n    | LENGTH4\n    | LENGTHB\n    | LENGTHC\n    | LENGTH\n    | LESS\n    | LEVEL\n    | LEVELS\n    | LIBRARY\n    | LIFE\n    | LIFETIME\n    | LIKE2\n    | LIKE4\n    | LIKEC\n    | LIKE_EXPAND\n    | LIMIT\n    | LINK\n    | LISTAGG\n    | LIST\n    | LN\n    | LNNVL\n    | LOAD\n    | LOB\n    | LOBNVL\n    | LOBS\n    | LOCAL_INDEXES\n    | LOCAL\n    | LOCALTIME\n    | LOCALTIMESTAMP\n    | LOCATION\n    | LOCATOR\n    | LOCKED\n    | LOGFILE\n    | LOGFILES\n    | LOGGING\n    | LOGICAL\n    | LOGICAL_READS_PER_CALL\n    | LOGICAL_READS_PER_SESSION\n    | LOG\n    | LOGOFF\n    | LOGON\n    | LOG_READ_ONLY_VIOLATIONS\n    | LOWER\n    | LOW\n    | LPAD\n    | LTRIM\n    | MAIN\n    | MAKE_REF\n    | MANAGED\n    | MANAGEMENT\n    | MANAGE\n    | MANAGER\n    | MANUAL\n    | MAPPING\n    | MASTER\n    | MATCHED\n    | MATERIALIZED\n    | MATERIALIZE\n    | MAXARCHLOGS\n    | MAXDATAFILES\n    | MAXEXTENTS\n    | MAXIMIZE\n    | MAXINSTANCES\n    | MAXLOGFILES\n    | MAXLOGHISTORY\n    | MAXLOGMEMBERS\n    | MAX\n    | MAXSIZE\n    | MAXTRANS\n    | MAXVALUE\n    | MEASURE\n    | MEASURES\n    | MEDIAN\n    | MEDIUM\n    | MEMBER\n    | MEMOPTIMIZE\n    | MEMORY\n    | MERGEACTIONS\n    | MERGE_AJ\n    | MERGE_CONST_ON\n    | MERGE\n    | MERGE_SJ\n    | METHOD\n    | MIGRATE\n    | MIGRATION\n    | MINEXTENTS\n    | MINIMIZE\n    | MINIMUM\n    | MINING\n    | MIN\n    | MINUS_NULL\n    | MINUTE\n    | MINVALUE\n    | MIRRORCOLD\n    | MIRRORHOT\n    | MIRROR\n    | MLSLABEL\n    | MODEL_COMPILE_SUBQUERY\n    | MODEL_DONTVERIFY_UNIQUENESS\n    | MODEL_DYNAMIC_SUBQUERY\n    | MODEL_MIN_ANALYSIS\n    | MODEL\n    | MODEL_NO_ANALYSIS\n    | MODEL_PBY\n    | MODEL_PUSH_REF\n    | MODIFY_COLUMN_TYPE\n    | MODIFY\n    | MOD\n    | MONITORING\n    | MONITOR\n    | MONTH\n    | MONTHS_BETWEEN\n    | MOUNT\n    | MOUNTPATH\n    | MOVEMENT\n    | MOVE\n    | MULTISET\n    | MV_MERGE\n    | NAMED\n    | NAME\n    | NAMESPACE\n    | NAN_\n    | NANVL\n    | NATIONAL\n    | NATIVE_FULL_OUTER_JOIN\n    | NATIVE\n    | NATURAL\n    | NAV\n    | NCHAR_CS\n    | NCHAR\n    | NCHR\n    | NCLOB\n    | NEEDED\n    | NESTED\n    | NESTED_TABLE_FAST_INSERT\n    | NESTED_TABLE_GET_REFS\n    | NESTED_TABLE_ID\n    | NESTED_TABLE_SET_REFS\n    | NESTED_TABLE_SET_SETID\n    | NETWORK\n    | NEVER\n    | NEW\n    | NEW_TIME\n    | NEXT_DAY\n    | NEXT\n    | NL_AJ\n    | NLJ_BATCHING\n    | NLJ_INDEX_FILTER\n    | NLJ_INDEX_SCAN\n    | NLJ_PREFETCH\n    | NLS_CALENDAR\n    | NLS_CHARACTERSET\n    | NLS_CHARSET_DECL_LEN\n    | NLS_CHARSET_ID\n    | NLS_CHARSET_NAME\n    | NLS_COMP\n    | NLS_CURRENCY\n    | NLS_DATE_FORMAT\n    | NLS_DATE_LANGUAGE\n    | NLS_INITCAP\n    | NLS_ISO_CURRENCY\n    | NL_SJ\n    | NLS_LANG\n    | NLS_LANGUAGE\n    | NLS_LENGTH_SEMANTICS\n    | NLS_LOWER\n    | NLS_NCHAR_CONV_EXCP\n    | NLS_NUMERIC_CHARACTERS\n    | NLS_SORT\n    | NLSSORT\n    | NLS_SPECIAL_CHARS\n    | NLS_TERRITORY\n    | NLS_UPPER\n    | NO_ACCESS\n    | NOAPPEND\n    | NOARCHIVELOG\n    | NOAUDIT\n    | NO_BASETABLE_MULTIMV_REWRITE\n    | NO_BIND_AWARE\n    | NO_BUFFER\n    | NOCACHE\n    | NO_CARTESIAN\n    | NO_CHECK_ACL_REWRITE\n    | NO_CLUSTER_BY_ROWID\n    | NO_COALESCE_SQ\n    | NO_CONNECT_BY_CB_WHR_ONLY\n    | NO_CONNECT_BY_COMBINE_SW\n    | NO_CONNECT_BY_COST_BASED\n    | NO_CONNECT_BY_ELIM_DUPS\n    | NO_CONNECT_BY_FILTERING\n    | NO_COST_XML_QUERY_REWRITE\n    | NO_CPU_COSTING\n    | NOCPU_COSTING\n    | NOCYCLE\n    | NODELAY\n    | NO_DOMAIN_INDEX_FILTER\n    | NO_DST_UPGRADE_INSERT_CONV\n    | NO_ELIMINATE_JOIN\n    | NO_ELIMINATE_OBY\n    | NO_ELIMINATE_OUTER_JOIN\n    | NOENTITYESCAPING\n    | NO_EXPAND_GSET_TO_UNION\n    | NO_EXPAND\n    | NO_EXPAND_TABLE\n    | NO_FACT\n    | NO_FACTORIZE_JOIN\n    | NO_FILTERING\n    | NOFORCE\n    | NO_FULL_OUTER_JOIN_TO_OUTER\n    | NO_GBY_PUSHDOWN\n    | NOGUARANTEE\n    | NO_INDEX_FFS\n    | NO_INDEX\n    | NO_INDEX_SS\n    | NO_LOAD\n    | NOLOCAL\n    | NOLOGGING\n    | NOMAPPING\n    | NOMAXVALUE\n    | NO_MERGE\n    | NOMINIMIZE\n    | NOMINVALUE\n    | NO_MODEL_PUSH_REF\n    | NO_MONITORING\n    | NOMONITORING\n    | NO_MONITOR\n    | NO_MULTIMV_REWRITE\n    | NO\n    | NO_NATIVE_FULL_OUTER_JOIN\n    | NONBLOCKING\n    | NONE\n    | NO_NLJ_BATCHING\n    | NO_NLJ_PREFETCH\n    | NONSCHEMA\n    | NOORDER\n    | NO_ORDER_ROLLUPS\n    | NO_OUTER_JOIN_TO_ANTI\n    | NO_OUTER_JOIN_TO_INNER\n    | NOOVERRIDE\n    | NO_PARALLEL_INDEX\n    | NOPARALLEL_INDEX\n    | NO_PARALLEL\n    | NOPARALLEL\n    | NO_PARTIAL_COMMIT\n    | NO_PLACE_DISTINCT\n    | NO_PLACE_GROUP_BY\n    | NO_PQ_MAP\n    | NO_PRUNE_GSETS\n    | NO_PULL_PRED\n    | NO_PUSH_PRED\n    | NO_PUSH_SUBQ\n    | NO_PX_JOIN_FILTER\n    | NO_QKN_BUFF\n    | NO_QUERY_TRANSFORMATION\n    | NO_REF_CASCADE\n    | NORELY\n    | NOREPAIR\n    | NORESETLOGS\n    | NO_RESULT_CACHE\n    | NOREVERSE\n    | NO_REWRITE\n    | NOREWRITE\n    | NORMAL\n    | NOROWDEPENDENCIES\n    | NOSCHEMACHECK\n    | NOSEGMENT\n    | NO_SEMIJOIN\n    | NO_SEMI_TO_INNER\n    | NO_SET_TO_JOIN\n    | NOSORT\n    | NO_SQL_TUNE\n    | NO_STAR_TRANSFORMATION\n    | NO_STATEMENT_QUEUING\n    | NO_STATS_GSETS\n    | NOSTRICT\n    | NO_SUBQUERY_PRUNING\n    | NO_SUBSTRB_PAD\n    | NO_SWAP_JOIN_INPUTS\n    | NOSWITCH\n    | NO_TABLE_LOOKUP_BY_NL\n    | NO_TEMP_TABLE\n    | NOTHING\n    | NOTIFICATION\n    | NO_TRANSFORM_DISTINCT_AGG\n    | NO_UNNEST\n    | NO_USE_HASH_AGGREGATION\n    | NO_USE_HASH_GBY_FOR_PUSHDOWN\n    | NO_USE_HASH\n    | NO_USE_INVISIBLE_INDEXES\n    | NO_USE_MERGE\n    | NO_USE_NL\n    | NOVALIDATE\n    | NO_XDB_FASTPATH_INSERT\n    | NO_XML_DML_REWRITE\n    | NO_XMLINDEX_REWRITE_IN_SELECT\n    | NO_XMLINDEX_REWRITE\n    | NO_XML_QUERY_REWRITE\n    | NTH_VALUE\n    | NTILE\n    | NULLIF\n    | NULLS\n    | NUMERIC\n    | NUM_INDEX_KEYS\n    | NUMTODSINTERVAL\n    | NUMTOYMINTERVAL\n    | NVARCHAR2\n    | NVL2\n    | NVL\n    | OBJECT2XML\n    | OBJECT\n    | OBJNO\n    | OBJNO_REUSE\n    | OCCURENCES\n    | OFFLINE\n    | OFF\n    | OIDINDEX\n    | OID\n    | OLAP\n    | OLD\n    | OLD_PUSH_PRED\n    | OLTP\n    | ONLINE\n    | ONLY\n    | OPAQUE\n    | OPAQUE_TRANSFORM\n    | OPAQUE_XCANONICAL\n    | OPCODE\n    | OPEN\n    | OPERATIONS\n    | OPERATOR\n    | OPT_ESTIMATE\n    | OPTIMAL\n    | OPTIMIZE\n    | OPTIMIZER_FEATURES_ENABLE\n    | OPTIMIZER_GOAL\n    | OPT_PARAM\n    | ORA_BRANCH\n    | ORADEBUG\n    | ORA_DST_AFFECTED\n    | ORA_DST_CONVERT\n    | ORA_DST_ERROR\n    | ORA_GET_ACLIDS\n    | ORA_GET_PRIVILEGES\n    | ORA_HASH\n    | ORA_ROWSCN\n    | ORA_ROWSCN_RAW\n    | ORA_ROWVERSION\n    | ORA_TABVERSION\n    | ORDERED\n    | ORDERED_PREDICATES\n    | ORDINALITY\n    | OR_EXPAND\n    | ORGANIZATION\n    | OR_PREDICATES\n    | OTHER\n    | OUTER_JOIN_TO_ANTI\n    | OUTER_JOIN_TO_INNER\n    | OUTER\n    | OUTLINE_LEAF\n    | OUTLINE\n    | OUT_OF_LINE\n    | OVERFLOW_\n    | OVERFLOW_NOMOVE\n    | OVERLAPS\n    | OVER\n    | OVERRIDE\n    | OWNER\n    | OWNERSHIP\n    | OWN\n    | PACKAGE\n    | PACKAGES\n    | PARALLEL_INDEX\n    | PARALLEL\n    | PARAMETERS\n    | PARAM\n    | PARENT\n    | PARITY\n    | PARTIALLY\n    | PARTITION_HASH\n    | PARTITION_LIST\n    | PARTITION\n    | PARTITION_RANGE\n    | PARTITIONS\n    | PARTNUMINST\n    | PASSING\n    | PASSWORD_GRACE_TIME\n    | PASSWORD_LIFE_TIME\n    | PASSWORD_LOCK_TIME\n    | PASSWORD\n    | PASSWORD_REUSE_MAX\n    | PASSWORD_REUSE_TIME\n    | PASSWORD_VERIFY_FUNCTION\n    | PATH\n    | PATHS\n    | PBL_HS_BEGIN\n    | PBL_HS_END\n    | PCTINCREASE\n    | PCTTHRESHOLD\n    | PCTUSED\n    | PCTVERSION\n    | PENDING\n    | PERCENTILE_CONT\n    | PERCENTILE_DISC\n    | PERCENT_KEYWORD\n    | PERCENT_RANKM\n    | PERCENT_RANK\n    | PERFORMANCE\n    | PERMANENT\n    | PERMISSION\n    | PFILE\n    | PHYSICAL\n    | PIKEY\n    | PIV_GB\n    | PIVOT\n    | PIV_SSF\n    | PLACE_DISTINCT\n    | PLACE_GROUP_BY\n    | PLAN\n    | PLSCOPE_SETTINGS\n    | PLSQL_CCFLAGS\n    | PLSQL_CODE_TYPE\n    | PLSQL_DEBUG\n    | PLSQL_OPTIMIZE_LEVEL\n    | PLSQL_WARNINGS\n    | POINT\n    | POLICY\n    | POST_TRANSACTION\n    | POWERMULTISET_BY_CARDINALITY\n    | POWERMULTISET\n    | POWER\n    | POSITION\n    | PQ_DISTRIBUTE\n    | PQ_MAP\n    | PQ_NOMAP\n    | PREBUILT\n    | PRECEDES\n    | PRECEDING\n    | PRECISION\n    | PRECOMPUTE_SUBQUERY\n    | PREDICATE_REORDERS\n    | PREDICTION_BOUNDS\n    | PREDICTION_COST\n    | PREDICTION_DETAILS\n    | PREDICTION\n    | PREDICTION_PROBABILITY\n    | PREDICTION_SET\n    | PREPARE\n    | PRESENT\n    | PRESENTNNV\n    | PRESENTV\n    | PRESERVE\n    | PRESERVE_OID\n    | PREVIOUS\n    | PRIMARY\n    | PRIVATE\n    | PRIVATE_SGA\n    | PRIVILEGE\n    | PRIVILEGES\n    | PROCEDURAL\n    | PROCEDURE\n    | PROCESS\n    | PROFILE\n    | PROGRAM\n    | PROJECT\n    | PROPAGATE\n    | PROTECTED\n    | PROTECTION\n    | PULL_PRED\n    | PURGE\n    | PUSH_PRED\n    | PUSH_SUBQ\n    | PX_GRANULE\n    | PX_JOIN_FILTER\n    | QB_NAME\n    | QUERY_BLOCK\n    | QUERY\n    | QUEUE_CURR\n    | QUEUE\n    | QUEUE_ROWP\n    | QUIESCE\n    | QUORUM\n    | QUOTA\n    | RANDOM_LOCAL\n    | RANDOM\n    | RANGE\n    | RANKM\n    | RANK\n    | RAPIDLY\n    | RATIO_TO_REPORT\n    | RAWTOHEX\n    | RAWTONHEX\n    | RBA\n    | RBO_OUTLINE\n    | RDBA\n    | READ\n    | READS\n    | REAL\n    | REBALANCE\n    | REBUILD\n    | RECORDS_PER_BLOCK\n    | RECOVERABLE\n    | RECOVER\n    | RECOVERY\n    | RECYCLEBIN\n    | RECYCLE\n    | REDACTION\n    | REDO\n    | REDUCED\n    | REDUNDANCY\n    | REF_CASCADE_CURSOR\n    | REFERENCED\n    | REFERENCE\n    | REFERENCES\n    | REFERENCING\n    | REF\n    | REFRESH\n    | REFTOHEX\n    | REGEXP_COUNT\n    | REGEXP_INSTR\n    | REGEXP_LIKE\n    | REGEXP_REPLACE\n    | REGEXP_SUBSTR\n    | REGISTER\n    | REGR_AVGX\n    | REGR_AVGY\n    | REGR_COUNT\n    | REGR_INTERCEPT\n    | REGR_R2\n    | REGR_SLOPE\n    | REGR_SXX\n    | REGR_SXY\n    | REGR_SYY\n    | REGULAR\n    | REJECT\n    | REKEY\n    | RELATIONAL\n    | RELY\n    | REMAINDER\n    | REMOTE_MAPPED\n    | REMOVE\n    | REPAIR\n    | REPEAT\n    | REPLACE\n    | REPLICATION\n    | REQUIRED\n    | RESETLOGS\n    | RESET\n    | RESIZE\n    | RESOLVE\n    | RESOLVER\n    | RESPECT\n    | RESTORE_AS_INTERVALS\n    | RESTORE\n    | RESTRICT_ALL_REF_CONS\n    | RESTRICTED\n    | RESTRICT\n    | RESULT_CACHE\n    | RESUMABLE\n    | RESUME\n    | RETENTION\n    | RETRY_ON_ROW_CHANGE\n    | RETURNING\n    | RETURN\n    | REUSE\n    | REVERSE\n    | REWRITE\n    | REWRITE_OR_ERROR\n    | RIGHT\n    | ROLE\n    | ROLES\n    | ROLLBACK\n    | ROLLING\n    | ROLLUP\n    | ROOT\n    | ROUND\n    | ROWDEPENDENCIES\n    | ROWID\n    | ROWIDTOCHAR\n    | ROWIDTONCHAR\n    | ROW_LENGTH\n    | ROW\n    | ROW_NUMBER\n    | ROWNUM\n    | ROWS\n    | RPAD\n    | RTRIM\n    | RULE\n    | RULES\n    | SALT\n    | SAMPLE\n    | SAVE_AS_INTERVALS\n    | SAVEPOINT\n    | SB4\n    | SCALE\n    | SCALE_ROWS\n    | SCAN_INSTANCES\n    | SCAN\n    | SCHEDULER\n    | SCHEMACHECK\n    | SCHEMA\n    | SCN_ASCENDING\n    | SCN\n    | SCOPE\n    | SD_ALL\n    | SD_INHIBIT\n    | SD_SHOW\n    | SEARCH\n    | SECOND\n    | SECUREFILE_DBA\n    | SECUREFILE\n    | SECURITY\n    | SEED\n    | SEG_BLOCK\n    | SEG_FILE\n    | SEGMENT\n    | SELECTIVITY\n    | SEMIJOIN_DRIVER\n    | SEMIJOIN\n    | SEMI_TO_INNER\n    | SEQUENCED\n    | SEQUENCE\n    | SEQUENTIAL\n    | SERIALIZABLE\n    | SERVERERROR\n    | SERVICE\n    | SESSION_CACHED_CURSORS\n    | SESSION\n    | SESSIONS_PER_USER\n    | SESSIONTIMEZONE\n    | SESSIONTZNAME\n    | SETS\n    | SETTINGS\n    | SET_TO_JOIN\n    | SEVERE\n    | SHARED\n    | SHARED_POOL\n    | SHOW\n    | SHRINK\n    | SHUTDOWN\n    | SIBLINGS\n    | SID\n    | SIGNAL_COMPONENT\n    | SIGNAL_FUNCTION\n    | SIGN\n    | SIMPLE\n    | SINGLE\n    | SINGLETASK\n    | SINH\n    | SIN\n    | SKIP_EXT_OPTIMIZER\n    | SKIP_\n    | SKIP_UNQ_UNUSABLE_IDX\n    | SKIP_UNUSABLE_INDEXES\n    | SMALLFILE\n    | SNAPSHOT\n    | SOME\n    | SORT\n    | SOUNDEX\n    | SOURCE\n    | SPACE_KEYWORD\n    | SPECIFICATION\n    | SPFILE\n    | SPLIT\n    | SPREADSHEET\n    | SQLLDR\n    | SQL\n    | SQL_TRACE\n    | SQL_MACRO\n    | SQRT\n    | STALE\n    | STANDALONE\n    | STANDBY_MAX_DATA_DELAY\n    | STANDBY\n    | STAR\n    | STAR_TRANSFORMATION\n    | STARTUP\n    | STATEMENT_ID\n    | STATEMENT_QUEUING\n    | STATEMENTS\n    | STATIC\n    | STATISTICS\n    | STATS_BINOMIAL_TEST\n    | STATS_CROSSTAB\n    | STATS_F_TEST\n    | STATS_KS_TEST\n    | STATS_MODE\n    | STATS_MW_TEST\n    | STATS_ONE_WAY_ANOVA\n    | STATS_T_TEST_INDEP\n    | STATS_T_TEST_INDEPU\n    | STATS_T_TEST_ONE\n    | STATS_T_TEST_PAIRED\n    | STATS_WSR_TEST\n    | STDDEV\n    | STDDEV_POP\n    | STDDEV_SAMP\n    | STOP\n    | STORAGE\n    | STORE\n    | STREAMS\n    | STRICT\n    | STRING\n    | STRIPE_COLUMNS\n    | STRIPE_WIDTH\n    | STRIP\n    | STRUCTURE\n    | SUBMULTISET\n    | SUBPARTITION\n    | SUBPARTITION_REL\n    | SUBPARTITIONS\n    | SUBQUERIES\n    | SUBQUERY_PRUNING\n    | SUBSTITUTABLE\n    | SUBSTR2\n    | SUBSTR4\n    | SUBSTRB\n    | SUBSTRC\n    | SUBSTR\n    | SUCCESSFUL\n    | SUMMARY\n    | SUM\n    | SUPPLEMENTAL\n    | SUSPEND\n    | SWAP_JOIN_INPUTS\n    | SWITCH\n    | SWITCHOVER\n    | SYNCHRONOUS\n    | SYNC\n    | SYS\n    | SYSASM\n    | SYS_AUDIT\n    | SYSAUX\n    | SYS_CHECKACL\n    | SYS_CONNECT_BY_PATH\n    | SYS_CONTEXT\n    | SYSDATE\n    | SYSDBA\n    | SYS_DBURIGEN\n    | SYS_DL_CURSOR\n    | SYS_DM_RXFORM_CHR\n    | SYS_DM_RXFORM_NUM\n    | SYS_DOM_COMPARE\n    | SYS_DST_PRIM2SEC\n    | SYS_DST_SEC2PRIM\n    | SYS_ET_BFILE_TO_RAW\n    | SYS_ET_BLOB_TO_IMAGE\n    | SYS_ET_IMAGE_TO_BLOB\n    | SYS_ET_RAW_TO_BFILE\n    | SYS_EXTPDTXT\n    | SYS_EXTRACT_UTC\n    | SYS_FBT_INSDEL\n    | SYS_FILTER_ACLS\n    | SYS_FNMATCHES\n    | SYS_FNREPLACE\n    | SYS_GET_ACLIDS\n    | SYS_GET_PRIVILEGES\n    | SYS_GETTOKENID\n    | SYS_GETXTIVAL\n    | SYS_GUID\n    | SYS_MAKEXML\n    | SYS_MAKE_XMLNODEID\n    | SYS_MKXMLATTR\n    | SYS_OP_ADT2BIN\n    | SYS_OP_ADTCONS\n    | SYS_OP_ALSCRVAL\n    | SYS_OP_ATG\n    | SYS_OP_BIN2ADT\n    | SYS_OP_BITVEC\n    | SYS_OP_BL2R\n    | SYS_OP_BLOOM_FILTER_LIST\n    | SYS_OP_BLOOM_FILTER\n    | SYS_OP_C2C\n    | SYS_OP_CAST\n    | SYS_OP_CEG\n    | SYS_OP_CL2C\n    | SYS_OP_COMBINED_HASH\n    | SYS_OP_COMP\n    | SYS_OP_CONVERT\n    | SYS_OP_COUNTCHG\n    | SYS_OP_CSCONV\n    | SYS_OP_CSCONVTEST\n    | SYS_OP_CSR\n    | SYS_OP_CSX_PATCH\n    | SYS_OP_DECOMP\n    | SYS_OP_DESCEND\n    | SYS_OP_DISTINCT\n    | SYS_OP_DRA\n    | SYS_OP_DUMP\n    | SYS_OP_DV_CHECK\n    | SYS_OP_ENFORCE_NOT_NULL\n    | SYSOPER\n    | SYS_OP_EXTRACT\n    | SYS_OP_GROUPING\n    | SYS_OP_GUID\n    | SYS_OP_IIX\n    | SYS_OP_ITR\n    | SYS_OP_LBID\n    | SYS_OP_LOBLOC2BLOB\n    | SYS_OP_LOBLOC2CLOB\n    | SYS_OP_LOBLOC2ID\n    | SYS_OP_LOBLOC2NCLOB\n    | SYS_OP_LOBLOC2TYP\n    | SYS_OP_LSVI\n    | SYS_OP_LVL\n    | SYS_OP_MAKEOID\n    | SYS_OP_MAP_NONNULL\n    | SYS_OP_MSR\n    | SYS_OP_NICOMBINE\n    | SYS_OP_NIEXTRACT\n    | SYS_OP_NII\n    | SYS_OP_NIX\n    | SYS_OP_NOEXPAND\n    | SYS_OP_NTCIMG\n    | SYS_OP_NUMTORAW\n    | SYS_OP_OIDVALUE\n    | SYS_OP_OPNSIZE\n    | SYS_OP_PAR_1\n    | SYS_OP_PARGID_1\n    | SYS_OP_PARGID\n    | SYS_OP_PAR\n    | SYS_OP_PIVOT\n    | SYS_OP_R2O\n    | SYS_OP_RAWTONUM\n    | SYS_OP_RDTM\n    | SYS_OP_REF\n    | SYS_OP_RMTD\n    | SYS_OP_ROWIDTOOBJ\n    | SYS_OP_RPB\n    | SYS_OPTLOBPRBSC\n    | SYS_OP_TOSETID\n    | SYS_OP_TPR\n    | SYS_OP_TRTB\n    | SYS_OPTXICMP\n    | SYS_OPTXQCASTASNQ\n    | SYS_OP_UNDESCEND\n    | SYS_OP_VECAND\n    | SYS_OP_VECBIT\n    | SYS_OP_VECOR\n    | SYS_OP_VECXOR\n    | SYS_OP_VERSION\n    | SYS_OP_VREF\n    | SYS_OP_VVD\n    | SYS_OP_XMLCONS_FOR_CSX\n    | SYS_OP_XPTHATG\n    | SYS_OP_XPTHIDX\n    | SYS_OP_XPTHOP\n    | SYS_OP_XTXT2SQLT\n    | SYS_ORDERKEY_DEPTH\n    | SYS_ORDERKEY_MAXCHILD\n    | SYS_ORDERKEY_PARENT\n    | SYS_PARALLEL_TXN\n    | SYS_PATHID_IS_ATTR\n    | SYS_PATHID_IS_NMSPC\n    | SYS_PATHID_LASTNAME\n    | SYS_PATHID_LASTNMSPC\n    | SYS_PATH_REVERSE\n    | SYS_PXQEXTRACT\n    | SYS_RID_ORDER\n    | SYS_ROW_DELTA\n    | SYS_SC_2_XMLT\n    | SYS_SYNRCIREDO\n    | SYSTEM_DEFINED\n    | SYSTEM\n    | SYSTIMESTAMP\n    | SYS_TYPEID\n    | SYS_UMAKEXML\n    | SYS_XMLANALYZE\n    | SYS_XMLCONTAINS\n    | SYS_XMLCONV\n    | SYS_XMLEXNSURI\n    | SYS_XMLGEN\n    | SYS_XMLI_LOC_ISNODE\n    | SYS_XMLI_LOC_ISTEXT\n    | SYS_XMLINSTR\n    | SYS_XMLLOCATOR_GETSVAL\n    | SYS_XMLNODEID_GETCID\n    | SYS_XMLNODEID_GETLOCATOR\n    | SYS_XMLNODEID_GETOKEY\n    | SYS_XMLNODEID_GETPATHID\n    | SYS_XMLNODEID_GETPTRID\n    | SYS_XMLNODEID_GETRID\n    | SYS_XMLNODEID_GETSVAL\n    | SYS_XMLNODEID_GETTID\n    | SYS_XMLNODEID\n    | SYS_XMLT_2_SC\n    | SYS_XMLTRANSLATE\n    | SYS_XMLTYPE2SQL\n    | SYS_XQ_ASQLCNV\n    | SYS_XQ_ATOMCNVCHK\n    | SYS_XQBASEURI\n    | SYS_XQCASTABLEERRH\n    | SYS_XQCODEP2STR\n    | SYS_XQCODEPEQ\n    | SYS_XQCON2SEQ\n    | SYS_XQCONCAT\n    | SYS_XQDELETE\n    | SYS_XQDFLTCOLATION\n    | SYS_XQDOC\n    | SYS_XQDOCURI\n    | SYS_XQDURDIV\n    | SYS_XQED4URI\n    | SYS_XQENDSWITH\n    | SYS_XQERRH\n    | SYS_XQERR\n    | SYS_XQESHTMLURI\n    | SYS_XQEXLOBVAL\n    | SYS_XQEXSTWRP\n    | SYS_XQEXTRACT\n    | SYS_XQEXTRREF\n    | SYS_XQEXVAL\n    | SYS_XQFB2STR\n    | SYS_XQFNBOOL\n    | SYS_XQFNCMP\n    | SYS_XQFNDATIM\n    | SYS_XQFNLNAME\n    | SYS_XQFNNM\n    | SYS_XQFNNSURI\n    | SYS_XQFNPREDTRUTH\n    | SYS_XQFNQNM\n    | SYS_XQFNROOT\n    | SYS_XQFORMATNUM\n    | SYS_XQFTCONTAIN\n    | SYS_XQFUNCR\n    | SYS_XQGETCONTENT\n    | SYS_XQINDXOF\n    | SYS_XQINSERT\n    | SYS_XQINSPFX\n    | SYS_XQIRI2URI\n    | SYS_XQLANG\n    | SYS_XQLLNMFRMQNM\n    | SYS_XQMKNODEREF\n    | SYS_XQNILLED\n    | SYS_XQNODENAME\n    | SYS_XQNORMSPACE\n    | SYS_XQNORMUCODE\n    | SYS_XQ_NRNG\n    | SYS_XQNSP4PFX\n    | SYS_XQNSPFRMQNM\n    | SYS_XQPFXFRMQNM\n    | SYS_XQ_PKSQL2XML\n    | SYS_XQPOLYABS\n    | SYS_XQPOLYADD\n    | SYS_XQPOLYCEL\n    | SYS_XQPOLYCSTBL\n    | SYS_XQPOLYCST\n    | SYS_XQPOLYDIV\n    | SYS_XQPOLYFLR\n    | SYS_XQPOLYMOD\n    | SYS_XQPOLYMUL\n    | SYS_XQPOLYRND\n    | SYS_XQPOLYSQRT\n    | SYS_XQPOLYSUB\n    | SYS_XQPOLYUMUS\n    | SYS_XQPOLYUPLS\n    | SYS_XQPOLYVEQ\n    | SYS_XQPOLYVGE\n    | SYS_XQPOLYVGT\n    | SYS_XQPOLYVLE\n    | SYS_XQPOLYVLT\n    | SYS_XQPOLYVNE\n    | SYS_XQREF2VAL\n    | SYS_XQRENAME\n    | SYS_XQREPLACE\n    | SYS_XQRESVURI\n    | SYS_XQRNDHALF2EVN\n    | SYS_XQRSLVQNM\n    | SYS_XQRYENVPGET\n    | SYS_XQRYVARGET\n    | SYS_XQRYWRP\n    | SYS_XQSEQ2CON4XC\n    | SYS_XQSEQ2CON\n    | SYS_XQSEQDEEPEQ\n    | SYS_XQSEQINSB\n    | SYS_XQSEQRM\n    | SYS_XQSEQRVS\n    | SYS_XQSEQSUB\n    | SYS_XQSEQTYPMATCH\n    | SYS_XQSTARTSWITH\n    | SYS_XQSTATBURI\n    | SYS_XQSTR2CODEP\n    | SYS_XQSTRJOIN\n    | SYS_XQSUBSTRAFT\n    | SYS_XQSUBSTRBEF\n    | SYS_XQTOKENIZE\n    | SYS_XQTREATAS\n    | SYS_XQ_UPKXML2SQL\n    | SYS_XQXFORM\n    | TABLE\n    | TABLE_LOOKUP_BY_NL\n    | TABLES\n    | TABLESPACE\n    | TABLESPACE_NO\n    | TABLE_STATS\n    | TABNO\n    | TANH\n    | TAN\n    | TBLORIDXPARTNUM\n    | TEMPFILE\n    | TEMPLATE\n    | TEMPLATE_TABLE\n    | TEMPORARY\n    | TEMP_TABLE\n    | TEST\n    | THAN\n    | THE\n    | THEN\n    | THREAD\n    | THROUGH\n    | TIME\n    | TIMING\n    | TIMEOUT\n    | TIMES\n    | TIMESTAMP\n    | TIMEZONE\n    | TIMEZONE_ABBR\n    | TIMEZONE_HOUR\n    | TIMEZONE_MINUTE\n    | TIME_ZONE\n    | TIMEZONE_OFFSET\n    | TIMEZONE_REGION\n    | TIV_GB\n    | TIV_SSF\n    | TO_BINARY_DOUBLE\n    | TO_BINARY_FLOAT\n    | TO_BLOB\n    | TO_CHAR\n    | TO_CLOB\n    | TO_DATE\n    | TO_DSINTERVAL\n    | TO_LOB\n    | TO_MULTI_BYTE\n    | TO_NCHAR\n    | TO_NCLOB\n    | TO_NUMBER\n    | TOPLEVEL\n    | TO_SINGLE_BYTE\n    | TO_TIME\n    | TO_TIMESTAMP\n    | TO_TIMESTAMP_TZ\n    | TO_TIME_TZ\n    | TO_YMINTERVAL\n    | TRACE\n    | TRACING\n    | TRACKING\n    | TRAILING\n    | TRANSACTION\n    | TRANSFORM_DISTINCT_AGG\n    | TRANSITIONAL\n    | TRANSITION\n    | TRANSLATE\n    | TREAT\n    | TRIGGERS\n    | TRIM\n    | TRUE\n    | TRUNCATE\n    | TRUNC\n    | TRUSTED\n    | TUNING\n    | TX\n    | TYPE\n    | TYPES\n    | TZ_OFFSET\n    | UB2\n    | UBA\n    | UID\n    | UNARCHIVED\n    | UNBOUNDED\n    | UNBOUND\n    | UNDER\n    | UNDO\n    | UNDROP\n    | UNIFORM\n    | UNISTR\n    | UNLIMITED\n    | UNLOAD\n    | UNLOCK\n    | UNNEST_INNERJ_DISTINCT_VIEW\n    | UNNEST\n    | UNNEST_NOSEMIJ_NODISTINCTVIEW\n    | UNNEST_SEMIJ_VIEW\n    | UNPACKED\n    | UNPIVOT\n    | UNPROTECTED\n    | UNQUIESCE\n    | UNRECOVERABLE\n    | UNRESTRICTED\n    | UNTIL\n    | UNUSABLE\n    | UNUSED\n    | UPDATABLE\n    | UPDATED\n    | UPDATEXML\n    | UPD_INDEXES\n    | UPD_JOININDEX\n    | UPGRADE\n    | UPPER\n    | UPSERT\n    | UROWID\n    | USAGE\n    | USE_ANTI\n    | USE_CONCAT\n    | USE_HASH_AGGREGATION\n    | USE_HASH_GBY_FOR_PUSHDOWN\n    | USE_HASH\n    | USE_INVISIBLE_INDEXES\n    | USE_MERGE_CARTESIAN\n    | USE_MERGE\n    | USE\n    | USE_NL\n    | USE_NL_WITH_INDEX\n    | USE_PRIVATE_OUTLINES\n    | USER_DEFINED\n    | USERENV\n    | USERGROUP\n    | USER\n    | USER_RECYCLEBIN\n    | USERS\n    | USE_SEMI\n    | USE_STORED_OUTLINES\n    | USE_TTT_FOR_GSETS\n    | USE_WEAK_NAME_RESL\n    | USING\n    | VALIDATE\n    | VALIDATION\n    | VALUE\n    | VARIANCE\n    | VAR_POP\n    | VARRAY\n    | VARRAYS\n    | VAR_SAMP\n    | VARYING\n    | VECTOR_READ\n    | VECTOR_READ_TRACE\n    | VERIFY\n    | VERSIONING\n    | VERSION\n    | VERSIONS_ENDSCN\n    | VERSIONS_ENDTIME\n    | VERSIONS\n    | VERSIONS_OPERATION\n    | VERSIONS_STARTSCN\n    | VERSIONS_STARTTIME\n    | VERSIONS_XID\n    | VIRTUAL\n    | VISIBLE\n    | VOLUME\n    | VSIZE\n    | WAIT\n    | WALLET\n    | WELLFORMED\n    | WHENEVER\n    | WHEN\n    | WHITESPACE\n    | WIDTH_BUCKET\n    | WITHIN\n    | WITHOUT\n    | WORK\n    | WRAPPED\n    | WRITE\n    | XDB_FASTPATH_INSERT\n    | X_DYN_PRUNE\n    | XID\n    | XML2OBJECT\n    | XMLATTRIBUTES\n    | XMLCAST\n    | XMLCDATA\n    | XMLCOLATTVAL\n    | XMLCOMMENT\n    | XMLCONCAT\n    | XMLDIFF\n    | XML_DML_RWT_STMT\n    | XMLELEMENT\n    | XMLEXISTS2\n    | XMLEXISTS\n    | XMLFOREST\n    | XMLINDEX_REWRITE_IN_SELECT\n    | XMLINDEX_REWRITE\n    | XMLINDEX_SEL_IDX_TBL\n    | XMLISNODE\n    | XMLISVALID\n    | XML\n    | XMLNAMESPACES\n    | XMLPARSE\n    | XMLPATCH\n    | XMLPI\n    | XMLQUERY\n    | XMLQUERYVAL\n    | XMLROOT\n    | XMLSCHEMA\n    | XMLSERIALIZE\n    | XMLTABLE\n    | XMLTRANSFORMBLOB\n    | XMLTRANSFORM\n    | XMLTYPE\n    | XPATHTABLE\n    | XS_SYS_CONTEXT\n    | YEAR\n    | YES\n    | ZONE\n    ;\n"
  },
  {
    "path": "superior-oracle-parser/src/main/java/io/github/melin/superior/parser/oracle/antlr4/OracleLexerBase.java",
    "content": "package io.github.melin.superior.parser.oracle.antlr4;\n\nimport org.antlr.v4.runtime.CharStream;\nimport org.antlr.v4.runtime.Lexer;\n\npublic abstract class OracleLexerBase extends Lexer {\n    public OracleLexerBase self;\n\n    public OracleLexerBase(CharStream input) {\n        super(input);\n        self = this;\n    }\n\n    protected boolean IsNewlineAtPos(int pos) {\n        int la = _input.LA(pos);\n        return la == -1 || la == '\\n';\n    }\n}\n"
  },
  {
    "path": "superior-oracle-parser/src/main/java/io/github/melin/superior/parser/oracle/antlr4/OracleParserBase.java",
    "content": "package io.github.melin.superior.parser.oracle.antlr4;\n\nimport org.antlr.v4.runtime.*;\n\npublic abstract class OracleParserBase extends Parser {\n    private boolean _isVersion12 = true;\n    private boolean _isVersion11 = true;\n    private boolean _isVersion10 = true;\n\n    public OracleParserBase(TokenStream input) {\n        super(input);\n    }\n\n    public boolean isVersion12() {\n        return _isVersion12;\n    }\n\n    public void setVersion12(boolean value) {\n        _isVersion12 = value;\n    }\n\n    public boolean isVersion11() {\n        return _isVersion11;\n    }\n\n    public void setVersion11(boolean value) {\n        _isVersion11 = value;\n    }\n\n    public boolean isVersion10() {\n        return _isVersion10;\n    }\n\n    public void setVersion10(boolean value) {\n        _isVersion10 = value;\n    }\n}\n"
  },
  {
    "path": "superior-oracle-parser/src/main/kotlin/io/github/melin/superior/parser/oracle/AbstractSqlParser.kt",
    "content": "package io.github.melin.superior.parser.oracle\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.oracle.antlr4.OracleParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(OracleParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: OracleParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(OracleParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-oracle-parser/src/main/kotlin/io/github/melin/superior/parser/oracle/OracleSqlAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.oracle\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.*\nimport io.github.melin.superior.common.relational.alter.AlterTable\nimport io.github.melin.superior.common.relational.alter.AlterTableAction\nimport io.github.melin.superior.common.relational.common.CallProcedure\nimport io.github.melin.superior.common.relational.common.CommentStatement\nimport io.github.melin.superior.common.relational.common.ShowStatement\nimport io.github.melin.superior.common.relational.create.*\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.drop.DropDatabase\nimport io.github.melin.superior.common.relational.drop.DropFunction\nimport io.github.melin.superior.common.relational.drop.DropProcedure\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport io.github.melin.superior.common.relational.table.ColumnRel\nimport io.github.melin.superior.parser.oracle.antlr4.OracleParser\nimport io.github.melin.superior.parser.oracle.antlr4.OracleParser.Cursor_declarationContext\nimport io.github.melin.superior.parser.oracle.antlr4.OracleParser.Function_nameContext\nimport io.github.melin.superior.parser.oracle.antlr4.OracleParser.Multi_table_elementContext\nimport io.github.melin.superior.parser.oracle.antlr4.OracleParser.Procedure_nameContext\nimport io.github.melin.superior.parser.oracle.antlr4.OracleParser.Select_list_elementsContext\nimport io.github.melin.superior.parser.oracle.antlr4.OracleParser.Seq_of_statementsContext\nimport io.github.melin.superior.parser.oracle.antlr4.OracleParserBaseVisitor\nimport org.antlr.v4.runtime.tree.RuleNode\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2020/6/30 9:57 上午 */\nclass OracleSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) :\n    OracleParserBaseVisitor<Statement>() {\n\n    private var currentOptType: StatementType = StatementType.UNKOWN\n    private var limit: Int? = null\n    private var offset: Int? = null\n\n    private var queryStmt: QueryStmt? = null\n    private var inputTables: ArrayList<TableId> = arrayListOf()\n    private var outputTables: ArrayList<TableId> = arrayListOf()\n    private var cteTempTables: ArrayList<TableId> = arrayListOf()\n\n    // 多语句解析结果\n    private var statements: ArrayList<Statement> = arrayListOf()\n    // 存储过程和函数中包含的子语句\n    private var childStatements: ArrayList<Statement> = arrayListOf()\n    private val sqls: ArrayList<String> = arrayListOf()\n\n    fun getSqlStatements(): List<Statement> {\n        return statements\n    }\n\n    fun getSplitSqls(): List<String> {\n        return sqls\n    }\n\n    override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {\n        if (currentResult != null) {\n            if (node is Cursor_declarationContext || node is Seq_of_statementsContext) {\n\n                childStatements.add(currentResult)\n                clean()\n            }\n        }\n\n        if (node is OracleParser.Unit_statementContext) {\n            clean()\n        }\n\n        return true\n    }\n\n    override fun visitSql_script(ctx: OracleParser.Sql_scriptContext): Statement? {\n        ctx.sql_plus_command().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else {\n                        var statement = this.visitSql_plus_command(it)\n                        if (statement == null) {\n                            statement = DefaultStatement(StatementType.UNKOWN)\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n                currentOptType = StatementType.UNKOWN\n            }\n        }\n\n        ctx.unit_statement().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else {\n                        var statement = this.visitUnit_statement(it)\n                        if (statement == null) {\n                            statement = DefaultStatement(StatementType.UNKOWN)\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n                currentOptType = StatementType.UNKOWN\n            }\n        }\n        return null\n    }\n\n    private fun clean() {\n        limit = null\n        offset = null\n        queryStmt = null\n        inputTables = arrayListOf()\n        outputTables = arrayListOf()\n        cteTempTables = arrayListOf()\n    }\n\n    private fun addOutputTableId(tableId: TableId) {\n        if (!outputTables.contains(tableId)) {\n            outputTables.add(tableId)\n        }\n    }\n\n    override fun visitCreate_database(ctx: OracleParser.Create_databaseContext): Statement {\n        val databaseName = CommonUtils.cleanQuote(ctx.database_name().text)\n        return CreateDatabase(databaseName)\n    }\n\n    override fun visitCreate_table(ctx: OracleParser.Create_tableContext): Statement {\n        currentOptType = StatementType.CREATE_TABLE\n        val schemaName = if (ctx.schema_name() != null) ctx.schema_name().text else null\n        val tableName = ctx.table_name().text\n        val tableId = TableId(schemaName, tableName)\n\n        val pks: ArrayList<String> = arrayListOf()\n        val columnRels =\n            ctx.relational_table()\n                .relational_property()\n                .filter {\n                    val constraint = it.out_of_line_constraint()\n                    if (constraint != null && constraint.PRIMARY() != null) {\n                        constraint.column_name().forEach { pks.add(it.text) }\n                    }\n\n                    it.column_definition() != null\n                }\n                .map {\n                    val colDef = it.column_definition()\n                    val columnName = colDef.column_name().text\n                    val dataType = colDef.datatype().text\n                    val defaultExpr: String? = if (colDef.expression() != null) colDef.expression().text else null\n\n                    var isPk = if (pks.contains(columnName)) true else false\n                    var nullable = true\n                    if (colDef.inline_constraint() != null) {\n                        colDef.inline_constraint().forEach { constraint ->\n                            if (constraint.NOT() != null) {\n                                nullable = false\n                            }\n\n                            if (constraint.PRIMARY() != null) {\n                                isPk = true\n                            }\n                        }\n                    }\n\n                    ColumnRel(columnName, dataType, defaultExpr = defaultExpr, nullable = nullable, primaryKey = isPk)\n                }\n\n        return CreateTable(tableId, TableType.ORACLE, columnRels = columnRels)\n    }\n\n    override fun visitCreate_view(ctx: OracleParser.Create_viewContext): Statement {\n        currentOptType = StatementType.CREATE_VIEW\n        val schemaName = if (ctx.schema_name() != null) ctx.schema_name().text else null\n        val tableName = ctx.v.text\n        val tableId = TableId(schemaName, tableName)\n        val replace = if (ctx.REPLACE() != null) true else false\n        val queryStmt = this.parseSelect_only_statement(ctx.select_only_statement()) as QueryStmt\n        val createView = CreateView(tableId, queryStmt)\n        createView.replace = replace\n        return createView\n    }\n\n    override fun visitCreate_materialized_view(ctx: OracleParser.Create_materialized_viewContext): Statement {\n        currentOptType = StatementType.CREATE_MATERIALIZED_VIEW\n        val tableId = parseTableViewName(ctx.tableview_name())\n        // val ifNotExists = if (ctx.IF_P() != null) true else false\n        val queryStmt = this.parseSelect_only_statement(ctx.select_only_statement()) as QueryStmt\n        val createView = CreateMaterializedView(tableId, queryStmt)\n\n        super.visitSelect_only_statement(ctx.select_only_statement())\n        return createView\n    }\n\n    override fun visitCreate_procedure_body(ctx: OracleParser.Create_procedure_bodyContext): Statement {\n        childStatements = arrayListOf()\n        super.visitCreate_procedure_body(ctx)\n        val procedureName = ctx.procedure_name()\n        val procedureId = parseProcedureName(procedureName)\n        return CreateProcedure(procedureId, childStatements)\n    }\n\n    override fun visitCreate_function_body(ctx: OracleParser.Create_function_bodyContext): Statement {\n        childStatements = arrayListOf()\n        super.visitCreate_function_body(ctx)\n        val funcName = ctx.function_name()\n        val functionId = parseFunctionName(funcName)\n        val function = CreateFunction(functionId, childStatements)\n        return function\n    }\n\n    override fun visitDrop_database(ctx: OracleParser.Drop_databaseContext): Statement? {\n        return DropDatabase(\"\")\n    }\n\n    override fun visitDrop_table(ctx: OracleParser.Drop_tableContext): Statement? {\n        val tableId = parseTableViewName(ctx.tableview_name().get(0))\n        val ifExists = ctx.EXISTS() != null\n        val purge = ctx.PURGE() != null\n        val dropTable = DropTable(tableId, ifExists)\n        dropTable.purge = purge\n        return dropTable\n    }\n\n    override fun visitDrop_function(ctx: OracleParser.Drop_functionContext): Statement {\n        val funcName = ctx.function_name()\n        val functionId = parseFunctionName(funcName)\n        return DropFunction(functionId)\n    }\n\n    override fun visitDrop_procedure(ctx: OracleParser.Drop_procedureContext): Statement {\n        val procedureName = ctx.procedure_name()\n        val procedureId = parseProcedureName(procedureName)\n        return DropProcedure(procedureId)\n    }\n\n    override fun visitAnonymous_block(ctx: OracleParser.Anonymous_blockContext?): Statement {\n        childStatements = arrayListOf()\n        super.visitAnonymous_block(ctx)\n        return CreateProcedure(childStatements)\n    }\n\n    override fun visitCall_statement(ctx: OracleParser.Call_statementContext): Statement {\n        val procedureId = ProcedureId(ctx.routine_name().get(0).text)\n        val callProcedure = CallProcedure(procedureId)\n        callProcedure.setSql(source(ctx))\n        return callProcedure\n    }\n\n    override fun visitAlter_table(ctx: OracleParser.Alter_tableContext): Statement {\n        val tableId = parseTableViewName(ctx.tableview_name())\n        return AlterTable(tableId)\n    }\n\n    override fun visitAlter_view(ctx: OracleParser.Alter_viewContext): Statement {\n        val tableId = parseTableViewName(ctx.tableview_name())\n        val action = AlterTableAction(AlterActionType.ALTER_VIEW_QUERY)\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitSelect_statement(ctx: OracleParser.Select_statementContext): Statement? {\n        currentOptType = StatementType.SELECT\n        super.visitSelect_statement(ctx)\n        if (queryStmt == null) {\n            queryStmt = QueryStmt(inputTables, limit, offset)\n        }\n\n        queryStmt?.setSql(source(ctx))\n\n        return queryStmt\n    }\n\n    private fun parseSelect_only_statement(ctx: OracleParser.Select_only_statementContext): Statement? {\n        currentOptType = StatementType.SELECT\n        super.visitSelect_only_statement(ctx)\n        if (queryStmt == null) {\n            queryStmt = QueryStmt(inputTables, limit, offset)\n        }\n        return queryStmt\n    }\n\n    override fun visitDelete_statement(ctx: OracleParser.Delete_statementContext): Statement {\n        currentOptType = StatementType.DELETE\n        val tableId = parseTableViewName(ctx.general_table_ref().dml_table_expression_clause().tableview_name())\n        addOutputTableId(tableId)\n        super.visitWhere_clause(ctx.where_clause())\n\n        return DeleteTable(tableId, inputTables)\n    }\n\n    override fun visitUpdate_statement(ctx: OracleParser.Update_statementContext): Statement {\n        currentOptType = StatementType.UPDATE\n        val tableId = parseTableViewName(ctx.general_table_ref().dml_table_expression_clause().tableview_name())\n        addOutputTableId(tableId)\n        super.visitWhere_clause(ctx.where_clause())\n\n        return UpdateTable(tableId, inputTables)\n    }\n\n    override fun visitInsert_statement(ctx: OracleParser.Insert_statementContext): Statement {\n        currentOptType = StatementType.INSERT\n\n        val insertTable =\n            if (ctx.single_table_insert() != null) {\n                val tableInsert = ctx.single_table_insert()\n                val tableId =\n                    parseTableViewName(\n                        tableInsert\n                            .insert_into_clause()\n                            .general_table_ref()\n                            .dml_table_expression_clause()\n                            .tableview_name()\n                    )\n                addOutputTableId(tableId)\n\n                if (tableInsert.select_statement() != null) {\n                    val queryStmt = this.visitSelect_statement(tableInsert.select_statement()) as QueryStmt\n                    InsertTable(InsertMode.INTO, queryStmt, tableId)\n                } else {\n                    InsertTable(InsertMode.INTO, QueryStmt(), tableId)\n                }\n            } else {\n                if (ctx.multi_table_insert().conditional_insert_clause() == null) {\n                    val tableInserts = ctx.multi_table_insert().multi_table_element()\n                    addOutputTableId(tableInserts)\n                } else {\n                    ctx.multi_table_insert().conditional_insert_clause().conditional_insert_when_part().map {\n                        addOutputTableId(it.multi_table_element())\n                    }\n\n                    val elseElem = ctx.multi_table_insert().conditional_insert_clause().conditional_insert_else_part()\n                    if (elseElem != null) {\n                        addOutputTableId(elseElem.multi_table_element())\n                    }\n                }\n\n                if (ctx.multi_table_insert().select_statement() != null) {\n                    val queryStmt = this.visitSelect_statement(ctx.multi_table_insert().select_statement()) as QueryStmt\n                    InsertTable(InsertMode.INTO, queryStmt, outputTables.first())\n                } else {\n                    InsertTable(InsertMode.INTO, QueryStmt(), outputTables.first())\n                }\n            }\n\n        insertTable.outputTables.addAll(outputTables.subList(1, outputTables.size))\n        //insertTable?.setSql(CommonUtils.subsql(command, ctx))\n        insertTable?.setSql(source(ctx))\n        return insertTable\n    }\n\n    override fun visitExecute_immediate(ctx: OracleParser.Execute_immediateContext): Statement? {\n        var execSql = CommonUtils.cleanQuote(ctx.expression().text)\n        execSql = StringUtils.replace(execSql, \"''\", \"'\")\n\n        val statements = OracleSqlHelper.parseMultiStatement(execSql)\n        childStatements.addAll(statements)\n        return null\n    }\n\n    private fun parseFunctionName(funcName: Function_nameContext): FunctionId {\n        return if (funcName.id_expression() != null) {\n            FunctionId(funcName.identifier().text, funcName.id_expression().text)\n        } else {\n            FunctionId(funcName.identifier().text)\n        }\n    }\n\n    private fun parseProcedureName(procedureName: Procedure_nameContext): ProcedureId {\n        return if (procedureName.id_expression() != null) {\n            ProcedureId(procedureName.identifier().text, procedureName.id_expression().text)\n        } else {\n            ProcedureId(procedureName.identifier().text)\n        }\n    }\n\n    private fun addOutputTableId(list: List<Multi_table_elementContext>) {\n        list.forEach {\n            val tableId =\n                parseTableViewName(\n                    it.insert_into_clause().general_table_ref().dml_table_expression_clause().tableview_name()\n                )\n            addOutputTableId(tableId)\n        }\n    }\n\n    override fun visitMerge_statement(ctx: OracleParser.Merge_statementContext): Statement {\n        currentOptType = StatementType.MERGE\n\n        val mergeTableId = parseTableViewName(ctx.tableview_name())\n        cteTempTables.add(mergeTableId)\n        val mergeTable = MergeTable(mergeTableId)\n        mergeTable.inputTables = inputTables\n        super.visitMerge_statement(ctx)\n        return mergeTable\n    }\n\n    override fun visitComment_on_column(ctx: OracleParser.Comment_on_columnContext): Statement {\n        val objValue = ctx.column_name().text\n        val isNull = false\n        val text: String = CommonUtils.cleanQuote(ctx.quoted_string().text)\n        return CommentStatement(text, isNull, \"COLUMN\", objValue)\n    }\n\n    override fun visitComment_on_table(ctx: OracleParser.Comment_on_tableContext): Statement {\n        val objValue = ctx.tableview_name().text\n        val isNull = false\n        val text: String = CommonUtils.cleanQuote(ctx.quoted_string().text)\n        return CommentStatement(text, isNull, \"TABLE\", objValue)\n    }\n\n    override fun visitComment_on_materialized(ctx: OracleParser.Comment_on_materializedContext): Statement {\n        val objValue = ctx.tableview_name().text\n        val isNull = false\n        val text: String = CommonUtils.cleanQuote(ctx.quoted_string().text)\n        return CommentStatement(text, isNull, \"MATERIALIZED VIEW\", objValue)\n    }\n\n    override fun visitSubquery_factoring_clause(ctx: OracleParser.Subquery_factoring_clauseContext): Statement? {\n        cteTempTables.add(TableId(ctx.query_name().text))\n        return super.visitSubquery_factoring_clause(ctx)\n    }\n\n    override fun visitOffset_clause(ctx: OracleParser.Offset_clauseContext): Statement? {\n        try {\n            offset = ctx.expression().text.toInt()\n        } catch (e: Exception) {}\n        return super.visitOffset_clause(ctx)\n    }\n\n    override fun visitFetch_clause(ctx: OracleParser.Fetch_clauseContext): Statement? {\n        try {\n            limit = ctx.expression().text.toInt()\n        } catch (e: Exception) {}\n        return super.visitFetch_clause(ctx)\n    }\n\n    override fun visitCursor_declaration(ctx: OracleParser.Cursor_declarationContext): Statement? {\n        super.visitCursor_declaration(ctx)\n        return null\n    }\n\n    override fun visitTableview_name(ctx: OracleParser.Tableview_nameContext): Statement? {\n        if (\n            currentOptType == StatementType.SELECT ||\n                currentOptType == StatementType.CREATE_VIEW ||\n                currentOptType == StatementType.CREATE_MATERIALIZED_VIEW ||\n                currentOptType == StatementType.UPDATE ||\n                currentOptType == StatementType.DELETE ||\n                currentOptType == StatementType.MERGE ||\n                currentOptType == StatementType.INSERT ||\n                currentOptType == StatementType.CREATE_FUNCTION ||\n                currentOptType == StatementType.CREATE_PROCEDURE\n        ) {\n\n            if (ctx.parent is Select_list_elementsContext) {\n                return null\n            }\n\n            val tableId = parseTableViewName(ctx)\n            if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {\n                inputTables.add(tableId)\n            }\n        }\n\n        return null\n    }\n\n    private fun parseTableViewName(ctx: OracleParser.Tableview_nameContext): TableId {\n        if (ctx.childCount == 1) {\n            return TableId(null, null, ctx.getChild(0).text)\n        } else if (ctx.childCount == 3) {\n            return TableId(null, ctx.getChild(0).text, ctx.getChild(2).text)\n        } else {\n            throw SQLParserException(\"not suuport tablename\")\n        }\n    }\n}\n"
  },
  {
    "path": "superior-oracle-parser/src/main/kotlin/io/github/melin/superior/parser/oracle/OracleSqlHelper.kt",
    "content": "package io.github.melin.superior.parser.oracle\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.oracle.antlr4.OracleLexer\nimport io.github.melin.superior.parser.oracle.antlr4.OracleParser\nimport io.github.melin.superior.parser.oracle.antlr4.OracleParserBaseVisitor\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2020/6/30 9:58 上午 */\nobject OracleSqlHelper {\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until OracleLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = OracleLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement {\n        var sql = StringUtils.trim(command)\n        if (!StringUtils.endsWith(sql, \";\")) {\n            sql += \";\"\n        }\n        val statements = this.parseMultiStatement(sql)\n        if (statements.size != 1) {\n            throw IllegalStateException(\"only parser one sql, sql count: \" + statements.size)\n        } else {\n            return statements.get(0)\n        }\n    }\n\n    @JvmStatic\n    fun parseMultiStatement(command: String): List<Statement> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = OracleSqlAntlr4Visitor(false, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSqlStatements()\n    }\n\n    @JvmStatic\n    fun splitSql(command: String): List<String> {\n        var trimCmd = StringUtils.trim(command)\n        if (!StringUtils.endsWith(trimCmd, \";\")) {\n            trimCmd += \";\"\n        }\n\n        val sqlVisitor = OracleSqlAntlr4Visitor(true, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSplitSqls()\n    }\n\n    @JvmStatic\n    fun checkSqlSyntax(command: String) {\n        var trimCmd = StringUtils.trim(command)\n        if (!StringUtils.endsWith(trimCmd, \";\")) {\n            trimCmd += \";\"\n        }\n\n        val sqlVisitor = OracleParserBaseVisitor<Statement>()\n        innerParseStatement(trimCmd, sqlVisitor)\n    }\n\n    private fun innerParseStatement(command: String, sqlVisitor: OracleParserBaseVisitor<Statement>) {\n        val charStream = UpperCaseCharStream(CharStreams.fromString(command))\n        val lexer = OracleLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = OracleParser(tokenStream)\n        AbstractSqlParser.installCaches(parser)\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n        // parser.interpreter.predictionMode = PredictionMode.SLL\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visit(parser.sql_script())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                sqlVisitor.visit(parser.sql_script())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(command)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-oracle-parser/src/test/java/io/github/melin/superior/parser/oracle/OracleProcessParserTest.kt",
    "content": "package io.github.melin.superior.parser.oracle\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.ProcedureId\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.common.CallProcedure\nimport io.github.melin.superior.common.relational.create.CreateFunction\nimport io.github.melin.superior.common.relational.create.CreateProcedure\nimport io.github.melin.superior.common.relational.drop.DropFunction\nimport io.github.melin.superior.common.relational.drop.DropProcedure\nimport org.junit.Assert\nimport org.junit.Test\n\nclass OracleProcessParserTest {\n    @Test\n    fun processTest0() {\n        val sql = \"\"\"\n            DECLARE\n                CURSOR C_ORDERS IS\n                    SELECT CUSTOMER_NAME, PRICE FROM ORDERS;\n            BEGIN\n                FOR ORD IN C_ORDERS\n                    LOOP\n                        SELECT CUSTOMER_NAME, PRICE FROM ORDERS_TEST;\n                        SELECT CUSTOMER_NAME, PRICE FROM ORDERS_TEST_1;\n                        dbms_output.put_line(ORD.CUSTOMER_NAME || ORD.PRICE);\n                    END LOOP;\n            END;\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(4, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFunctionTest() {\n        val sql = \"\"\"\n            CREATE FUNCTION test.get_bal(acc_no IN NUMBER) \n               RETURN NUMBER \n               IS acc_bal NUMBER(11,2);\n            BEGIN \n               SELECT order_total \n               INTO acc_bal \n               FROM orders \n               WHERE customer_id = acc_no; \n               RETURN(acc_bal); \n             END;\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateFunction) {\n            Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId(\"test\", \"get_bal\"), statement.functionId)\n            Assert.assertEquals(1, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFunctionTest1() {\n        val sql = \"\"\"\n            CREATE FUNCTION get_bal(acc_no IN NUMBER) \n               RETURN NUMBER \n               IS acc_bal NUMBER(11,2);\n            BEGIN \n               SELECT order_total \n               INTO acc_bal \n               FROM orders \n               WHERE customer_id = acc_no; \n               RETURN(acc_bal); \n             END;\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateFunction) {\n            Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId( \"get_bal\"), statement.functionId)\n            Assert.assertEquals(1, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createProcedureTest0() {\n        val sql = \"\"\"\n            CREATE OR REPLACE Procedure UpdateCourse( name_in IN varchar2 )\n            IS\n               cnumber number;\n               cursor c1 is\n               SELECT course_number\n                FROM courses_tbl\n                WHERE course_name = name_in;\n            BEGIN\n               open c1;\n               fetch c1 into cnumber;\n            \n               if c1%notfound then\n                  cnumber := 9999;\n               end if;\n            \n               INSERT INTO student_courses( course_name,course_number )\n               VALUES ( name_in, cnumber );\n            \n               commit;\n               close c1;\n            EXCEPTION\n            WHEN OTHERS THEN\n               raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);\n            END;\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(ProcedureId(\"UpdateCourse\"), statement.procedureId)\n            Assert.assertEquals(3, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropTest() {\n        val sql = \"\"\"\n            DROP FUNCTION get_bal;\n            DROP PROCEDURE demos.UpdateCourse;\n        \"\"\".trimIndent()\n\n        val statements = OracleSqlHelper.parseMultiStatement(sql)\n\n        val dropFunction = statements.get(0)\n        val dropProcess = statements.get(1)\n\n        if (dropFunction is DropFunction) {\n            Assert.assertEquals(\"get_bal\", dropFunction.functionId.functionName)\n        } else {\n            Assert.fail()\n        }\n\n        if (dropProcess is DropProcedure) {\n            Assert.assertEquals(\"demos\", dropProcess.procedureId.schemaName)\n            Assert.assertEquals(\"UpdateCourse\", dropProcess.procedureId.procedureName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun callProcessTest() {\n        val sql = \"\"\"\n            Call UpdateCourse('tes');\n            begin\n                UpdateCourse('tes');\n            end;\n        \"\"\".trimIndent()\n\n        val statements = OracleSqlHelper.parseMultiStatement(sql)\n\n        val procedure1 = statements.get(0)\n        val procedure2 = statements.get(1)\n\n        if (procedure1 is CallProcedure) {\n            Assert.assertEquals(\"UpdateCourse\", procedure1.procedureIds.first().procedureName)\n        } else {\n            Assert.fail()\n        }\n\n        if (procedure2 is CreateProcedure) {\n            Assert.assertEquals(1, procedure2.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun processTest4() {\n        val sql = \"\"\"\n            DECLARE\n                CURSOR C_ORDERS IS\n                    SELECT CUSTOMER_NAME, PRICE FROM ORDERS;\n            BEGIN\n                FOR ORD IN C_ORDERS\n                    LOOP\n                        SELECT CUSTOMER_NAME, PRICE FROM ORDERS_TEST;\n                        SELECT CUSTOMER_NAME, PRICE FROM ORDERS_TEST_1;\n                        dbms_output.put_line(ORD.CUSTOMER_NAME || ORD.PRICE);\n                    END LOOP;\n            END;\n            \n            CREATE FUNCTION test.get_bal(acc_no IN NUMBER) \n               RETURN NUMBER \n               IS acc_bal NUMBER(11,2);\n            BEGIN \n               SELECT order_total \n               INTO acc_bal \n               FROM orders \n               WHERE customer_id = acc_no; \n               RETURN(acc_bal); \n             END;\n        \"\"\".trimIndent()\n\n        val statements = OracleSqlHelper.parseMultiStatement(sql)\n        Assert.assertEquals(2, statements.size)\n        var statement = statements.get(0)\n\n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(4, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n\n        statement = statements.get(1)\n\n        if (statement is CreateFunction) {\n            Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(1, statement.childStatements.size)\n            Assert.assertEquals(\"SELECT order_total \\n\" +\n                    \"   INTO acc_bal \\n\" +\n                    \"   FROM orders \\n\" +\n                    \"   WHERE customer_id = acc_no\", statement.childStatements.get(0).getSql())\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun processTest5() {\n        val sql = \"\"\"\n           CREATE OR REPLACE PROCEDURE create_and_manipulate_tables AS\n            BEGIN\n                EXECUTE IMMEDIATE '\n                    CREATE TABLE schema1.test_table_s1 (\n                        id NUMBER PRIMARY KEY,\n                        name VARCHAR2(100)\n                    )\n                ';\n\n                EXECUTE IMMEDIATE 'INSERT INTO schema1.test_table_s1 (id, name) VALUES (1, ''Alice'')';                \n            END;\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n\n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(ProcedureId(\"create_and_manipulate_tables\"), statement.procedureId)\n            Assert.assertEquals(2, statement.childStatements.size)\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.childStatements.get(0).statementType)\n            Assert.assertEquals(StatementType.INSERT, statement.childStatements.get(1).statementType)\n            Assert.assertEquals(\"INSERT INTO schema1.test_table_s1 (id, name) VALUES (1, 'Alice')\", statement.childStatements.get(1).getSql())\n        } else {\n            Assert.fail()\n        }\n\n    }\n}"
  },
  {
    "path": "superior-oracle-parser/src/test/java/io/github/melin/superior/parser/oracle/OracleSqlParserDdlTest.kt",
    "content": "package io.github.melin.superior.parser.oracle\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.DefaultStatement\nimport io.github.melin.superior.common.relational.common.CommentStatement\nimport io.github.melin.superior.common.relational.create.CreateDatabase\nimport io.github.melin.superior.common.relational.create.CreateMaterializedView\nimport io.github.melin.superior.common.relational.create.CreateTable\nimport io.github.melin.superior.common.relational.create.CreateView\nimport io.github.melin.superior.common.relational.drop.DropDatabase\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport org.junit.Assert\nimport org.junit.Test\n\nclass OracleSqlParserDdlTest {\n    @Test\n    fun createDatabaseTest() {\n        val sql = \"\"\"\n            CREATE DATABASE bigdata1 USER SYSTEM IDENTIFIED BY 123213;\n            DROP DATABASE INCLUDING BACKUPS NOPROMPT\n        \"\"\".trimIndent()\n\n        val statements = OracleSqlHelper.parseMultiStatement(sql)\n\n        val createDatabse = statements.get(0)\n        val dropDatabase = statements.get(1)\n        if (createDatabse is CreateDatabase) {\n            Assert.assertEquals(\"bigdata1\", createDatabse.databaseName)\n        } else {\n            Assert.fail()\n        }\n\n        if (dropDatabase is DropDatabase) {\n            Assert.assertTrue(true)\n            Assert.assertEquals(StatementType.DROP_DATABASE, dropDatabase.statementType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest0() {\n        val sql = \"\"\"\n            CREATE TABLE employees(\n                employee_id number(10) NOT NULL,\n                employee_name varchar2(50) NOT NULL,\n                city varchar2(50),\n                CONSTRAINT employees_pk PRIMARY KEY (employee_id)\n            )\n        \"\"\".trimIndent()\n\n        OracleSqlHelper.splitSql(sql)\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId.tableName)\n            Assert.assertEquals(3, statement.columnRels?.size)\n            Assert.assertTrue(statement.columnRels?.get(0)?.primaryKey!!)\n            Assert.assertFalse(statement.columnRels?.get(1)?.primaryKey!!)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createView0() {\n        val sql = \"\"\"\n            CREATE OR REPLACE VIEW comedies AS\n            SELECT f.*,\n                   country_code_to_name(f.country_code) AS country,\n                   (SELECT avg(r.rating)\n                    FROM user_ratings r\n                    WHERE r.film_id = f.id) AS avg_rating\n            FROM films f\n            WHERE f.kind = 'Comedy'\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateView) {\n            Assert.assertEquals(StatementType.CREATE_VIEW, statement.statementType)\n            Assert.assertEquals(\"comedies\", statement.tableId.tableName)\n\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createMatView0() {\n        val sql = \"\"\"\n            CREATE MATERIALIZED VIEW sales_summary AS\n              SELECT\n                  seller_no,\n                  invoice_date,\n                  sum(invoice_amt) as sales_amt\n                FROM invoice\n                WHERE invoice_date < CURRENT_DATE\n                GROUP BY\n                  seller_no,\n                  invoice_date;\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateMaterializedView) {\n            Assert.assertEquals(StatementType.CREATE_MATERIALIZED_VIEW, statement.statementType)\n            Assert.assertEquals(\"sales_summary\", statement.tableId.tableName)\n\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun commentTest0() {\n        val sql = \"\"\"\n            COMMENT ON COLUMN employees.job_id IS 'abbreviated job title';\n            COMMENT ON COLUMN employees1.job_id IS 'abbreviated job title'\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseMultiStatement(sql)\n        val st1 = statement.get(0)\n        val st2 = statement.get(1)\n        \n        if (st1 is CommentStatement) {\n            Assert.assertEquals(StatementType.COMMENT, st1.statementType)\n            Assert.assertEquals(\"employees.job_id\", st1.objValue)\n            Assert.assertEquals(\"abbreviated job title\", st1.comment)\n            Assert.assertFalse(st1.isNull)\n        }\n\n        if (st2 is CommentStatement) {\n            Assert.assertEquals(StatementType.COMMENT, st2.statementType)\n            Assert.assertEquals(\"employees1.job_id\", st2.objValue)\n            Assert.assertEquals(\"abbreviated job title\", st2.comment)\n            Assert.assertFalse(st2.isNull)\n        }\n    }\n\n    @Test\n    fun dropTableTest() {\n        val sql = \"\"\"\n            drop table employees purge;\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n\n        if (statement is DropTable) {\n            Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId.tableName)\n\n            Assert.assertTrue(statement.purge)\n        } else {\n            Assert.fail()\n        }\n    }\n}"
  },
  {
    "path": "superior-oracle-parser/src/test/java/io/github/melin/superior/parser/oracle/OracleSqlParserDmlTest.kt",
    "content": "package io.github.melin.superior.parser.oracle\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.dml.*\nimport org.apache.commons.io.FileUtils\nimport org.junit.Assert\nimport org.junit.Test\nimport java.io.File\n\nclass OracleSqlParserDmlTest {\n    @Test\n    fun querySqlTest0() {\n        val sql1 = FileUtils.readFileToString(File(\"./src/test/resources/insert.sql\"), \"UTF-8\")\n        val statement = OracleSqlHelper.parseStatement(sql1)\n        \n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(27, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(TableId(\"dwd\", \"dwd_d03_contract_det_s\"), statement.outputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun querySqlTest1() {\n        val sql = \"\"\"\n            select 1;\n        \"\"\".trimIndent()\n\n        try {\n            OracleSqlHelper.parseStatement(sql)\n            Assert.fail()\n        } catch (e: Exception) {\n            Assert.assertTrue(true)\n        }\n    }\n\n    @Test\n    fun cteSqlTest0() {\n        val sql = \"\"\"\n            WITH\n              cte1 AS (SELECT a, b FROM table1),\n              cte2 AS (SELECT c, d FROM table2)\n            SELECT b, d FROM cte1 JOIN cte2\n            WHERE cte1.a = cte2.c\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(2, statement.inputTables.size)\n            Assert.assertEquals(TableId(\"table1\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest() {\n        val sql = \"\"\"\n            DELETE FROM films\n            WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest0() {\n        val sql = \"\"\"\n            UPDATE employees SET sales_count = sales_count + 1 WHERE id =\n            (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest0() {\n        val sql = \"\"\"\n            INSERT ALL\n              INTO pivot_dest (id, day, val) VALUES (id, 'mon', mon_val)\n              INTO pivot_dest (id, day, val) VALUES (id, 'tue', tue_val)\n              INTO pivot_dest (id, day, val) VALUES (id, 'wed', wed_val)\n              INTO pivot_dest (id, day, val) VALUES (id, 'thu', thu_val)\n              INTO pivot_dest (id, day, val) VALUES (id, 'fri', fri_val)\n            SELECT *\n            FROM   pivot_source;\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"pivot_dest\", statement.outputTables.get(0).tableName)\n            Assert.assertEquals(1, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest1() {\n        val sql = \"\"\"\n            INSERT ALL\n              INTO dest_tab1 (id, description) VALUES (id, description)\n              INTO dest_tab2 (id, description) VALUES (id, description)\n              INTO dest_tab3 (id, description) VALUES (id, description)\n            SELECT id, description\n            FROM   source_tab;\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"dest_tab1\", statement.outputTables.get(0).tableName)\n            Assert.assertEquals(3, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest2() {\n        val sql = \"\"\"\n            INSERT ALL\n              WHEN id <= 3 THEN\n                INTO dest_tab1 (id, description) VALUES (id, description)\n              WHEN id BETWEEN 4 AND 7 THEN\n                INTO dest_tab2 (id, description) VALUES (id, description)\n              WHEN id >= 8 THEN\n                INTO dest_tab3 (id, description) VALUES (id, description)\n            SELECT id, description\n            FROM   source_tab;\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"dest_tab1\", statement.outputTables.get(0).tableName)\n            Assert.assertEquals(3, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest3() {\n        val sql = \"\"\"\n            INSERT FIRST\n              WHEN id <= 3 THEN\n                INTO dest_tab1 (id, description) VALUES (id, description)\n              WHEN id <= 5 THEN\n                INTO dest_tab2 (id, description) VALUES (id, description)\n              ELSE\n                INTO dest_tab3 (id, description) VALUES (id, description)\n            SELECT id, description\n            FROM   source_tab;\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"dest_tab1\", statement.outputTables.get(0).tableName)\n            Assert.assertEquals(3, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest4() {\n        val sql = \"\"\"\n            INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deltaMergeTest() {\n        val sql = \"\"\"\n            MERGE INTO bonuses D\n            USING (SELECT employee_id, salary, department_id FROM hr.employees\n            WHERE department_id = 80) S\n            ON (D.employee_id = S.employee_id)\n            WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01\n                DELETE WHERE (S.salary > 8000)\n            WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus)\n                VALUES (S.employee_id, S.salary*.01)\n                WHERE (S.salary <= 8000);\n        \"\"\".trimIndent()\n\n        val statement = OracleSqlHelper.parseStatement(sql)\n        \n        if (statement is MergeTable) {\n            Assert.assertEquals(StatementType.MERGE, statement.statementType)\n            Assert.assertEquals(\"bonuses\", statement.targetTable.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}"
  },
  {
    "path": "superior-oracle-parser/src/test/resources/insert.sql",
    "content": "insert into dwd.dwd_d03_contract_det_s\nselect to_date('${yyyy-mm-dd}', 'yyyy-mm-dd')                                    stt_date\n     ,to_date('${yyyy-mm-dd}', 'yyyy-mm-dd')                                    end_date\n     ,'01'        cont_source_cd                                                 -- 合同来源编码: 01-通用核心； 02-商用车\n     ,'通用核心'  cont_source_nm                                                 -- 合同来源：通用核心/商用车\n     ,cc.pk_contract                                                             -- 合同主键\n     ,cc.cont_code                                                               -- 合同编码\n     ,cc.cont_name                                                               -- 合同名称\n     ,cc.cont_type                                         cont_type_cd          -- 合同类型编码\n     ,pt2.param_name                                       cont_type_nm          -- 合同类型名称\n     ,cc.cont_status                                       cont_status_cd        -- 合同状态编码\n     ,pt1.param_name                                       cont_status_nm        -- 合同状态名称\n     ,pt3.param_value                                      economic_style_cd     -- 控股类型编码\n     ,replace(replace(pt3.param_name ,'绝对',''),'相对','') economic_style_nm     -- 控股类型\n     ,cc.cont_amount                                                             -- 合同金额\n     ,cc.lease_date_fact                                                         -- 起租日\n     ,cc.cont_end_date                                                           -- 到期日\n     ,lc.lease_times                                        lease_times          -- 租赁期（月数）\n     ,round(lc.lease_times/12,2)                            lease_year           -- 租赁期（年数）\n     ,case when cc.cont_amount >= 100000000 then '大型'\n           when cc.cont_amount >= 10000000 and cc.cont_amount < 100000000\n               then '中型'\n           else '小型'\n    end cont_scala                                                            -- 合同规模\n     ,case when cc.if_adjust = 0 then '是'\n           when cc.if_adjust = 1 then '否'\n           else null\n    end if_adjust                                                             -- 是否调息\n     ,sjtf.fact_cash_loan                                                        -- 已投放金额\n     ,sjtf.pay_date                                                              -- 首次投放日期\n     ,ba1.name                                             pay_province          -- 投放地区省\n     ,ba2.name                                             pay_city              -- 投放地区市\n     ,ba3.name                                             pay_area              -- 客户所属区\n     ,coalesce(nn.assets_classify, cc.assets_classify, 0)     assets_classify_cd    -- 五级分类代码\n     ,case coalesce(nn.assets_classify, cc.assets_classify, 0)\n          when 0 then '正常'\n          when 1 then '关注'\n          when 2 then '次级'\n          when 3 then '可疑'\n          when 4 then '损失'\n          else '正常'\n    end                                                 assets_classify_nm    -- 五级分类名称\n\n     ,pi.pk_project_info                                                         -- 项目编号\n\n     ,pi.project_name                                                            -- 项目名称\n\n     ,pi.lease_categry                                     lease_categry_cd      -- 租赁类型代码\n\n     ,case when pi.lease_categry = 0 then '融资租赁'\n\n           when pi.lease_categry = 1 then '经营性租赁'\n\n           else null\n\n    end                                                 lease_categry_nm      -- 租赁类型名称\n\n     ,case when pbl.if_group_company = 0 then '是'\n\n           else '否'\n\n    end                                                 if_group_company      -- 是否集团客户\n\n     ,pbl.vesting_group                                                          -- 集团客户名称\n\n     ,lc.lease_method                                      lease_method_cd       -- 业务类型代码\n\n     ,case when lc.lease_method = 0 then '直租'\n\n           when lc.lease_method = 1 then '回租'\n\n           when lc.lease_method = 4 then '转租赁'\n\n           else null\n\n    end                                                 lease_method_nm       -- 业务类型名称\n\n     ,main_thing.fixed_assets                                                    -- 固定资产门类\n\n     ,main_thing.fixed_assets_lag                                                -- 固定资产门类-大类\n\n     ,main_thing.fixed_assets_mid                                                -- 固定资产门类--中类\n\n     ,main_thing.fixed_assets_sml                                                -- 固定资产门类--小类\n\n     ,main_thing.thing_name                                                      -- 租赁物名称\n\n     -- 主办人相关信息\n\n     ,su.user_code               main_user_code                                  -- 主办项目经理编号\n\n     ,su.user_name               main_user_name                                  -- 主办项目经理\n\n     ,su.dept_code               main_dept_code                                  -- 主办业务部门编号\n\n     ,su.dept_name               main_dept_name                                  -- 主办业务部门名称\n\n\n\n     -- 协办人相关信息\n\n     ,su2.user_code              help_user_code                                  -- 协办项目经理编号\n\n     ,su2.user_name              help_user_name                                  -- 协办项目经理\n\n     ,su2.dept_code              help_dept_code                                  -- 协办业务部门编号\n\n     ,su2.dept_name              help_dept_name                                  -- 协办业务部门名称\n\n\n\n     ,coalesce(pa.sponsor_performance, pa.sponsor_performance_sh * 100) sponsor_performance    -- 主办分成比例（两位整数）\n\n     ,coalesce(pa.help_performance, pa.help_performance_one * 100)      help_performance       -- 协办分成比例（两位整数）\n\n     ,pn.investment                                        investment_cd         -- 城建类分类\n\n     ,case when coalesce(pn.investment, cu.investment) = 0\n\n               then '是'\n\n           else '否'\n\n    end investment_nm                                                         -- 是否城建类\n\n     ,vc.customer_name                                                           -- 承租人名称\n\n     ,case when vc.identity_type = 4 then vc.identity_no\n\n           else null\n\n    end                                                 identity_no           -- 统一社会信用代码\n\n     ,vc.risk_level                                        risk_level_cd         -- 客户洗钱风险评级代码\n\n     ,case when vc.risk_level = '1001' then '低风险'\n\n           when vc.risk_level = '1002' then '较低风险'\n\n           when vc.risk_level = '1003' then '中风险'\n\n           when vc.risk_level = '1004' then '较高风险'\n\n           when vc.risk_level = '1005' then '高风险'\n\n           when vc.risk_level = '1006' then '无结果'\n\n           when vc.risk_level = '1007' then '查询失败'\n\n           else null\n\n    end                                                 risk_level_nm         -- 客户洗钱风险评级名称\n\n     ,cu.organization_code                                 organization_code     -- 组织机构代码\n\n\n\n     ,hy.param_name                                        industry              -- 国标行业门类\n\n     ,hy1.param_name                                       industry_lag          -- 国标行业大类\n\n     ,hy2.param_name                                       industry_mid          -- 国标行业中类\n\n     ,hy3.param_name                                       industry_sml          -- 国标行业小类\n\n     ,coalesce(cc.business_module, dm1.business_mode_nm, '其他')                                  industry_mod          -- 业务板块——9大分类\n\n\n\n     ,case when cc.cont_status = 8 or\n\n                (cc.cont_status = 2 and '${yyyy-mm-dd}' <= cc.lease_date_fact) or\n\n                (cc.cont_status = 2 and '${yyyy-mm-dd}' >= cc.lease_date_fact and coalesce(sjtf.fact_cash_loan,0) < coalesce(ipc.lease_corpus,0) and planc.plan_count >= 2 )\n\n               then coalesce(sjtf.fact_cash_loan,0) - coalesce(gather.gather_corpus,0) - coalesce(sfk.inner_deduct_cash,0)\n\n           else coalesce(ipc.lease_corpus,0) - coalesce(gather.gather_corpus,0) - coalesce(sfk.inner_deduct_cash,0)\n\n    end                                                                                     corpus_balance   -- 剩余本金\n\n     ,coalesce(history.lease_interest,ipc.lease_interest) - coalesce(gather.gather_interest,0) interest_balance -- 剩余利息\n\n     ,case when yoc.pk_contract is not null then coalesce(lpb.deposit_balance,0)\n\n           else 0\n\n    end                                                                                     deposit_balance  -- 剩余保证金\n\n     -- 调整剩余保证金逻辑， 保持和源端取值一样 11.22(剩余风险抵押金 按照逻辑把字段衍生出来)\n\n     -- ,coalesce(lpb.deposit_balance,0)                                                          deposit_balance  -- 剩余保证金\n\n     ,case when yoc.pk_contract is null then coalesce(lpb.deposit_balance,0)\n\n           else 0\n\n    end                                                                                     mortgage_balance -- 剩余风险抵押金\n\n     ,COALESCE(adj.INTERRATE_FACT_AFTER,lc.FINAL_RATE, 0)                                      contract_rate    -- 合同利率\n\n     ,COALESCE(adj.PROJECT_IRR,lc.PROJECT_IRR, 0) * 100.0                                      PROJECT_IRR      -- IRR（现行）\n\n     ,COALESCE(adj.CONTRACT_XIRR,lc.CONTRACT_XIRR, 0)  * 100.0                                 CONTRACT_XIRR    -- XIRR（含税）\n\n     -- 增加字段\n\n     ,case when yoc.pk_contract is null then '是'\n\n           else '否'\n\n    end                                                                                     is_mortgage      -- 是否风险抵押金\n\n     ,case when cc.cont_status = 8 and coalesce(ipo.overdue_days_zqx, 0) >= 1\n\n               then '是'\n\n           when cc.cont_status <> 8 and coalesce(ipo.overdue_days, 0) >= 1\n\n               then '是'\n\n           else '否'\n\n    end                                                                                     if_overdue       -- 是否逾期\n\n     ,yq.OVERDUE_DATE                                                                          overdue_days     -- 最大逾期天数（含历史）\n\n     ,magum.param_name                                                                         pledge_name      -- 担保方式\n\n     ,case when lc.interrate_type = 0\n\n               then '浮动利率' else '固定利率'\n\n    end                                                                                      interrate_type   -- 利率类型\n\n     ,ipc.lease_cash1      handling_fee       -- 手续费/咨询费\n\n     ,ipc.lease_cash11     fixed_rent         -- 固定租金\n\n     ,ipc.lease_cash2      deposit_amt        -- 保证金金额\n\n     ,ipc.lease_cash22     margin_bal         -- 保证金余额\n\n     ,ipc.lease_cash3      margin_off_amt     -- 保证金冲抵金额\n\n     ,ipc.lease_cash33     refund_deposit     -- 退还保证金\n\n     ,nn.accrue_cash                          -- 拨备余额\n\n     ,vc.customer_code                        -- 承租人编号\n\nfrom dwd.dg1_yls_contract_c_c cc    -- 合同表\n\n\n\n-- 补全9大分类\n\n         left join dim.dim_d99_business_mode_cd dm1\n\n                   on cc.industry3 = dm1.pk_parameter\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between dm1.stt_date and dm1.end_date\n\n\n\n    -- 合同状态\n\n         left join dwd.dg1_yls_parameter_c pt1\n\n                   on cc.cont_status = pt1.param_value\n\n                       and pt1.pk_param_type = upper('0001AA1000000001RC3C')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt1.stt_date and pt1.end_date\n\n    -- 合同类型\n\n         left join dwd.dg1_yls_parameter_c pt2\n\n                   on cc.cont_type = pt2.param_value\n\n                       and pt2.pk_param_type = upper('0001AA1000000001VJBS')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt2.stt_date and pt2.end_date\n\n    -- 控股类型\n\n         left join dwd.dg1_yls_parameter_c pt3\n\n                   on cc.economic_style1 = pt3.pk_parameter\n\n                       and pt3.pk_param_type = upper('0001AA10000000041633')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt3.stt_date and pt3.end_date\n\n    -- 担保方式\n\n         left join dwd.dg1_yls_parameter_c magum\n\n                   on cc.major_guarantee_method = magum.pk_parameter\n\n                       and magum.pk_param_type = upper('0001AA1000000002K3MQ')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt3.stt_date and pt3.end_date\n\n    -- 逾期情况\n\n         left join (\n\n    select ipc.pk_contract\n\n         ,coalesce(max(case\n\n                           when ipc.trans_type = upper('0001AA100000000AUBPA') and\n\n                                ipc.charge_off_status = 2 and\n\n                                gab.check_date > '${yyyy-mm-dd}' then\n\n                               to_date(gab.check_date, 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')\n\n                           when ipc.trans_type = upper('0001AA100000000AUBPA') and\n\n                                ipc.charge_off_status <> 2 and\n\n                                ipc.plan_date <= '${yyyy-mm-dd}' then\n\n                               to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')\n\n        end),\n\n                   0) as overdue_days_zqx\n\n         ,coalesce(max(case\n\n                           when ipc.charge_off_status = 2 and\n\n                                gab.check_date > '${yyyy-mm-dd}' then\n\n                               to_date(gab.check_date, 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')\n\n                           when ipc.charge_off_status <> 2 and\n\n                                ipc.plan_date <= '${yyyy-mm-dd}' then\n\n                               to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')\n\n        end),\n\n                   0) as overdue_days /*租金逾期天数*/\n\n    from dwd.dg1_yls_inout_plan_c_c ipc\n\n             left join (select gab.pk_inout_plan\n\n                             ,coalesce(max(gap.trade_date), '${yyyy-mm-dd}') as check_date\n\n                        from dwd.dg1_yls_gather_account_b_c gab\n\n                                 inner join dwd.dg1_yls_gather_account_c ga\n\n                                            on ga.pk_gather_account = gab.pk_gather_account\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date\n\n                                 inner join dwd.dg1_yls_gather_audit_plan_c gap\n\n                                            on gap.pk_gather_account_b = gab.pk_gather_account_b\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gap.stt_date and gap.end_date\n\n                        where ga.billstatus = 9\n\n                          and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date\n\n                        group by gab.pk_inout_plan) gab\n\n                       on gab.pk_inout_plan = ipc.pk_inout_plan\n\n    where ipc.trans_type in (upper('0001AA10000000007NGV'),\n\n                             upper('0001AA100000000AUBPA'),\n\n                             upper('0001AA10000000007NH3')) /* 现金流类型 租金 收租（租前息） 首付款*/\n\n      and ipc.rent_type = 1 /* 租金表类型 会计表*/\n\n      and ipc.plan_date <= '${yyyy-mm-dd}'\n\n      and ipc.lease_cash >= 0.01\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    group by ipc.pk_contract\n\n) ipo\n\n                   on cc.pk_contract = ipo.pk_contract\n\n         left join (\n\n    select plan.PK_CONTRACT,max(rec.OVERDUE_DATE) OVERDUE_DATE\n\n    from dwd.dg1_yls_overdue_record_c rec\n\n             join dwd.dg1_yls_inout_plan_c_c plan on plan.PK_INOUT_PLAN = rec.PK_INOUT_PLAN\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between plan.stt_date and plan.end_date\n\n    where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between rec.stt_date and rec.end_date\n\n    group by plan.PK_CONTRACT\n\n) yq on yq.PK_CONTRACT = cc.PK_CONTRACT\n\n    -- 实际投放金额\n\n         left join (\n\n    select ipc.pk_contract  -- 主键\n\n         ,sum(coalesce(lp.real_pay_cash, 0.00))              fact_cash_loan      -- 已投放金额\n\n         ,min(coalesce(ld.real_pay_date, '${yyyy-mm-dd}'))      pay_date            -- 首次投放日\n\n    from dwd.dg1_yls_inout_plan_c_c ipc\n\n             left join dwd.dg1_yls_loan_plan_c lp\n\n                       on ipc.pk_inout_plan = lp.pk_inout_plan\n\n                           and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date\n\n             left join dwd.dg1_yls_loan_deal_c ld\n\n                       on lp.pk_loan_deal = ld.pk_loan_deal\n\n                           and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date\n\n    where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n      and ipc.trans_type in (upper('0001AA10000000005GRC'), upper('0001AA10000000007NGO'), upper('0001AA1000000005AB31'), upper('0001AA1000000005AB32'))\n\n      and ipc.rent_type = 1          -- 租金表类型-会计表\n\n      and lp.if_account = 0          -- 是否核销为是\n\n      and lp.if_approve_cancel = 1   -- 是否审核撤销为否时\n\n      and lp.if_cancel = 1           -- 是否核销撤销为否时\n\n      and ld.billstatus = 9\n\n      and ld.real_pay_date <= '${yyyy-mm-dd}'\n\n    group by ipc.pk_contract\n\n) sjtf\n\n                   on cc.pk_contract = sjtf.pk_contract\n\n\n\n    -- 首付款\n\n         left join (\n\n    select ipc.pk_contract\n\n         ,sum(coalesce(ipc.lease_cash, 0.00)) as inner_deduct_cash\n\n         ,min(coalesce(ld.real_pay_date, '${yyyy-mm-dd}')) as pay_date\n\n    from dwd.dg1_yls_inout_plan_c_c ipc\n\n             left join dwd.dg1_yls_loan_plan_c lp\n\n                       on lp.pk_inout_plan = ipc.pk_inout_plan\n\n                           and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date\n\n             left join dwd.dg1_yls_loan_deal_c ld\n\n                       on ld.pk_loan_deal = lp.pk_loan_deal\n\n                           and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date\n\n    where ipc.trans_type = '0001AA10000000007NH3' /* 现金流类型 设备款*/\n\n      and ipc.rent_type = 1 /* 租金表类型 会计表*/\n\n      and lp.if_inner_deduct = 2 /* 是否内扣为是 */\n\n      and lp.if_cancel = 1 /* 是否核销撤销为否时 */\n\n      and ld.billstatus = 9\n\n      and ld.real_pay_date <= '${yyyy-mm-dd}'\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    group by ipc.pk_contract\n\n) sfk\n\n                   on cc.pk_contract = sfk.pk_contract\n\n\n\n    -- 五级分类\n\n         left join (\n\n    select i1.pk_contract             -- 合同PK\n\n         ,i1.assets_classify         -- 五级分类\n\n         ,i1.accrue_cash\n\n    from dwd.dg1_assets_classify_history_c i1                -- yls_assets_classify_history\n\n             join (\n\n        select ic.pk_contract\n\n             ,max(ic.pk_assets_classify_history) pk_assets_classify_history\n\n        from dwd.dg1_assets_classify_history_c ic\n\n        where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ic.stt_date and ic.end_date\n\n          and (\n\n                  case when ic.if_new = 0 then ic.period\n\n                       else coalesce(substr(replace(ic.change_date, '-', ''), 1, 6), ic.period)\n\n                      end\n\n                  )  <= substr(replace('${yyyy-mm-dd}', '-', ''), 1, 6)\n\n        group by ic.pk_contract\n\n    ) i2\n\n                  on i1.pk_assets_classify_history = i2.pk_assets_classify_history\n\n    where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between i1.stt_date and i1.end_date\n\n) nn\n\n                   on cc.pk_contract = nn.pk_contract\n\n\n\n    -- 项目信息\n\n         left join dwd.dg1_yls_project_info_c pi\n\n                   on cc.pk_project = pi.pk_project_info\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pi.stt_date and pi.end_date\n\n    -- 集团客户\n\n         left join (\n\n    select distinct source_bill, if_group_company, vesting_group\n\n    from dwd.dg1_yls_project_both_lessee_c\n\n    where lessee_type = 0\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between stt_date and end_date\n\n) pbl\n\n                   on pi.pk_project_info = pbl.source_bill\n\n    -- 主办/协办信息\n\n         left join dwd.dg1_yls_project_approval_c pa\n\n                   on pi.pk_project_approval = pa.pk_project_approval\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pa.stt_date and pa.end_date\n\n    -- 城建类\n\n         left join (\n\n    select row_number() over(partition by pk_project_info order by ts) rcnt\n\n          ,i3.pk_project_info\n\n         ,i3.investment                  -- 城建类判断\n\n    from dwd.dg1_yls_prj_nodecollect_c i3\n\n    where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between i3.stt_date and i3.end_date\n\n) pn\n\n                   on pi.pk_project_info = pn.pk_project_info\n\n                       and pn.rcnt = 1\n\n\n\n    -- 用户信息相关\n\n         left join dwd.dg1_yls_customer_c vc\n\n                   on cc.pk_customer_lessee = vc.pk_customer\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between vc.stt_date and vc.end_date\n\n    -- 企业客户基本信息\n\n         left join dwd.dg1_yls_customer_corp_c cu\n\n                   on vc.pk_customer = cu.pk_customer\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between cu.stt_date and cu.end_date\n\n    -- 投放地区\n\n         left join dwd.dg1_bd_areacl_c ba1 on ba1.pk_areacl = cu.PROVINCE\n\n    and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba1.stt_date and ba1.end_date\n\n         left join dwd.dg1_bd_areacl_c ba2 on ba2.pk_areacl = cu.CITY\n\n    and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba2.stt_date and ba2.end_date\n\n         left join dwd.dg1_bd_areacl_c ba3 on ba3.pk_areacl = cu.DISTRICT\n\n    and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba3.stt_date and ba3.end_date\n\n    -- 行业分类\n\n         left join dwd.dg1_yls_parameter_c hy\n\n                   on cc.industry = hy.pk_parameter\n\n                       and hy.pk_param_type  = upper('0001AA1000000000OY5C')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy.stt_date and hy.end_date\n\n         left join dwd.dg1_yls_parameter_c hy1\n\n                   on cc.industry1 = hy1.pk_parameter\n\n                       and hy1.pk_param_type = upper('0001AA1000000000OY5C')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy1.stt_date and hy1.end_date\n\n         left join dwd.dg1_yls_parameter_c hy2\n\n                   on cc.industry2 = hy2.pk_parameter\n\n                       and hy2.pk_param_type = upper('0001AA1000000000OY5C')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy2.stt_date and hy2.end_date\n\n         left join dwd.dg1_yls_parameter_c hy3\n\n                   on cc.industry3 = hy3.pk_parameter\n\n                       and hy3.pk_param_type = upper('0001AA1000000000OY5C')\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy3.stt_date and hy3.end_date\n\n\n\n    -- 剩余保证金计算\n\n         left join (\n\n    select ipc.pk_contract\n\n         ,sum(case\n\n                  when ipc.trans_type = '0001AA10000000007NHR' then\n\n                      (case when lp.pay_cash > ipc.lease_cash then coalesce(ipc.lease_cash, 0.00)\n\n                            else coalesce(lp.pay_cash, 0.00)\n\n                          end) + coalesce(gac.gather_cash, 0)\n\n                  when ipc.trans_type = '0001AA10000000007NHT' then\n\n                      -coalesce(gab.gather_cash, 0)\n\n                  when ipc.trans_type = '0001AA10000000007NI5' then\n\n                      coalesce(gac.gather_cash, 0)\n\n                  when ipc.trans_type = '0001AA10000000007NHX' then\n\n                      -coalesce(lp.pay_cash, 0)\n\n                  else 0\n\n        end) as deposit_balance\n\n    from dwd.dg1_yls_inout_plan_c_c ipc\n\n             left join (select ipc.pk_inout_plan\n\n                             ,coalesce(ga.charge_off_cash, 0) as gather_cash\n\n                        from dwd.dg1_yls_inout_plan_c_c ipc\n\n                                 inner join dwd.dg1_yls_gather_account_c ga\n\n                                            on ipc.pk_inout_plan = ga.pk_account_bill\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date\n\n                        where ga.billstatus = 9 /*单据状态 审核通过*/\n\n                          and ga.check_date <= '${yyyy-mm-dd}'\n\n                          and ipc.trans_type = '0001AA10000000007NHT'\n\n                          and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    ) gab\n\n                       on gab.pk_inout_plan = ipc.pk_inout_plan\n\n             left join (select ipc.pk_inout_plan\n\n                             ,coalesce(gab.gather_cash, 0) as gather_cash\n\n                        from dwd.dg1_yls_inout_plan_c_c ipc\n\n                                 inner join dwd.dg1_yls_gather_account_b_c gab\n\n                                            on ipc.pk_inout_plan = gab.pk_inout_plan\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date\n\n                                 inner join dwd.dg1_yls_gather_account_c ga\n\n                                            on ga.pk_gather_account = gab.pk_gather_account\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date\n\n                        where ga.billstatus = 9 /*单据状态 审核通过*/\n\n                          and ga.check_date <= '${yyyy-mm-dd}'\n\n                          and ipc.trans_type in\n\n                              ('0001AA10000000007NHR', '0001AA10000000007NI5')\n\n                          and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    ) gac\n\n                       on gac.pk_inout_plan = ipc.pk_inout_plan\n\n             left join (select lp.pk_inout_plan\n\n                             ,(case when coalesce(ld.real_pay_cash, 0.00) = 0\n\n                                        then coalesce(ld.inner_deduct_cash, 0.00)\n\n                                    else coalesce(ld.real_pay_cash, 0.00)\n\n            end) as pay_cash\n\n                        from dwd.dg1_yls_loan_plan_c lp\n\n                                 inner join dwd.dg1_yls_loan_deal_c ld\n\n                                            on ld.pk_loan_deal = lp.pk_loan_deal\n\n                                                and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date\n\n                        where lp.if_approve_cancel = 1 /* 是否审核撤销为否时 */\n\n                          and lp.if_cancel = 1         /* 是否核销撤销为否时 */\n\n                          and ld.billstatus = 9\n\n                          and ld.real_pay_date <= '${yyyy-mm-dd}'\n\n                          and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date\n\n    ) lp\n\n                       on lp.pk_inout_plan = ipc.pk_inout_plan\n\n    where ipc.trans_type in ('0001AA10000000007NHR',\n\n                             '0001AA10000000007NHT',\n\n                             '0001AA10000000007NI5',\n\n                             '0001AA10000000007NHX') /* 现金流类型 收取保证金,保证金冲抵,补足保证金,退还保证金*/\n\n      and ipc.rent_type = 1 /* 租金表类型 会计表*/\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    group by ipc.pk_contract\n\n) lpb\n\n                   on cc.pk_contract = lpb.pk_contract\n\n\n\n         left join dwd.dg1_yls_old_contract_c yoc\n\n                   on cc.pk_contract = yoc.pk_contract\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between yoc.stt_date and yoc.end_date\n\n\n\n    -- 实收数据\n\n         left join (\n\n    select sum(case when et.event_code in ('10201', '10203', '10216') and gab.trade_date <= '${yyyy-mm-dd}'\n\n                        then coalesce(gab.gather_cash, 0)\n\n                    else 0\n\n        end) gather_cash\n\n         ,sum(case when et.event_code in ('10201', '10203') and gab.trade_date <= '${yyyy-mm-dd}'\n\n                       then coalesce(gab.gather_corpus, 0)\n\n                   else 0\n\n        end) gather_corpus\n\n         ,sum(case when et.event_code in ('10201', '10216') and gab.trade_date <= '${yyyy-mm-dd}'\n\n                       then coalesce(gab.gather_interest, 0)\n\n                   else 0\n\n        end) gather_interest\n\n         ,sum(case when et.event_code in ('10213') and gab.trade_date <= '${yyyy-mm-dd}'\n\n                       then coalesce(gab.gather_cash, 0)\n\n                   else 0\n\n        end) gather_penal_cash\n\n         ,sum(case when et.event_code in ('10201', '10203') and gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and\n\n                        gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')\n\n                       then coalesce(gab.gather_cash, 0)\n\n                   else 0\n\n        end) gather_cash1\n\n         ,sum(case when et.event_code in ('10201', '10203') and\n\n                        gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and\n\n                        gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')\n\n                       then coalesce(gab.gather_corpus, 0)\n\n                   else 0\n\n        end) gather_corpus1\n\n         ,sum(case when et.event_code in ('10201', '10203', '10216') and\n\n                        gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and\n\n                        gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')\n\n                       then coalesce(gab.gather_interest, 0)\n\n                   else 0\n\n        end) gather_interest1\n\n         ,sum(case when et.event_code in ('10213') and\n\n                        gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and\n\n                        gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')\n\n                       then coalesce(gab.gather_cash, 0)\n\n                   else 0\n\n        end) gather_penal_cash1\n\n         ,sum(case when gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and\n\n                        gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')\n\n                       then\n\n                       1\n\n                   else\n\n                       0\n\n        end) cur_year_time\n\n         ,sum(case when gab.trade_date >= '${yyyy-mm-dd}' and\n\n                        gab.trade_date <= to_char(add_months(date'${yyyy-mm-dd}', 12), 'yyyy-mm-dd') then\n\n                       1\n\n                   else\n\n                       0\n\n        end) future_time\n\n         ,ipc.pk_contract\n\n    from dwd.dg1_yls_gather_account_b_c gab\n\n             join dwd.dg1_yls_gather_account_c ga\n\n                  on ga.pk_gather_account = gab.pk_gather_account\n\n                      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date\n\n             join dwd.dg1_yls_inout_plan_c_c ipc\n\n                  on ipc.pk_inout_plan = gab.pk_inout_plan\n\n                      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n             join dwd.dg1_yls_event_type_c et\n\n                  on et.pk_event_type = ipc.trans_type\n\n                      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date\n\n    where ga.billstatus = 9\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date\n\n    group by ipc.pk_contract\n\n) gather\n\n                   on cc.pk_contract = gather.pk_contract\n\n\n\n         left join dwd.dg1_yls_lease_calculator_c_c lc\n\n                   on cc.pk_lease_calculator = lc.pk_lease_calculator\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lc.stt_date and lc.end_date\n\n    -- 实时数据\n\n         left join (\n\n    select sum(case when et.event_code in ('10201','10202','10203','10216') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash, /* 总租金 */\n\n           sum(case when et.event_code in ('10401'/*,'10402','10403'*/,'10606') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash1,/* 手续费/咨询费 */\n\n           sum(case when et.event_code in ('10405') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash11,/* 固定租金 */\n\n           sum(case when et.event_code in ('10301') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash2, /* 保证金收取 */\n\n           sum(case when et.event_code in ('10308') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash22, /* 补住保证金 */\n\n           sum(case when et.event_code in ('10302') then coalesce(ipc.fact_cash,0) else 0 end) lease_cash3, /* 保证金冲抵 */\n\n           sum(case when et.event_code in ('10304') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash33, /* 退还保证金 */\n\n           sum(case when et.event_code in ('10201','10203') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash4, /* 收取总租金 */\n\n           sum(case when et.event_code in ('10201','10202','10216') then coalesce(ipc.lease_interest,0) else 0 end) lease_interest, /* 收取总利息 */\n\n           sum(case when et.event_code in ('10101','10102') and ycc.cont_status = 8 then coalesce(ipc.fact_cash,0)\n\n                    when et.event_code in ('10201','10203') and ycc.cont_status != 8 then coalesce(ipc.lease_corpus,0) else 0 end) lease_corpus, /* 总本金 */\n\n           sum(case when et.event_code in ('10301','10308') then coalesce(ipc.fact_cash,0) else 0 end) fact_cash2, /* 实收:保证金收取、补足 */\n\n           sum(case when et.event_code in ('10302','10304') then coalesce(ipc.fact_cash,0) else 0 end) fact_cash3, /* 实际：保证金冲抵、退还保证金 */\n\n           ipc.source_bill\n\n    from dwd.dg1_yls_inout_plan_c_c ipc\n\n             join dwd.dg1_yls_event_type_c et on et.pk_event_type = ipc.trans_type\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date\n\n             join dwd.dg1_yls_contract_c_c ycc on ycc.pk_contract = ipc.pk_contract\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ycc.stt_date and ycc.end_date\n\n    where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date\n\n    group by ipc.source_bill\n\n) ipc on lc.pk_lease_calculator = ipc.source_bill\n\n    -- 历史数据\n\n         left join (\n\n\n\n    select ch.CONT_CODE,rc.interrate,rc.new_final_rate ,rc.NEW_PROJECT_IRR,rc.NEW_CONTRACT_XIRR,h.lease_cash,h.lease_cash1,h.lease_cash2,\n\n           h.lease_cash3,lease_cash22,h.lease_cash33,h.LEASE_INTEREST,\n\n           h.fact_cash2,h.fact_cash3\n\n    from dwd.dg1_yls_contract_h_c ch\n\n             join dwd.dg1_yls_rent_calculator_c rc on rc.PK_CONTRACT = ch.PK_CONTRACT\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between rc.stt_date and rc.end_date\n\n             join (\n\n        select iph.SOURCE_BILL,\n\n               sum(case when et.EVENT_CODE in ('10201','10202','10203','10216') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash, /* 收租总租金 */\n\n               sum(case when et.EVENT_CODE in ('10401'/*,'10402','10403'*/,'10405','10606') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash1, /* 手续费/咨询费/固定租金 */\n\n               sum(case when et.EVENT_CODE in ('10201','10202','10216') then coalesce(iph.LEASE_INTEREST,0) else 0 end) LEASE_INTEREST, /* 收租总租息 */\n\n               sum(case when et.EVENT_CODE in ('10301') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash2, /* 保证金收取 */\n\n               sum(case when et.EVENT_CODE in ('10308') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash22, /* 保证金补住 */\n\n               sum(case when et.EVENT_CODE in ('10302') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash3, /* 保证金冲抵*/\n\n               sum(case when et.EVENT_CODE in ('10304') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash33, /* 保证金退还 */\n\n               sum(case when et.EVENT_CODE in ('10301','10308') then coalesce(iph.FACT_CASH,0) else 0 end) fact_cash2, /* 实收:保证金收取、补足 */\n\n               sum(case when et.EVENT_CODE in ('10302','10304') then coalesce(iph.FACT_CASH,0) else 0 end) fact_cash3 /* 实际：保证金冲抵、退还保证金 */\n\n        from dwd.dg1_yls_inout_plan_h_c iph\n\n                 join dwd.dg1_yls_event_type_c et on et.PK_EVENT_TYPE = iph.TRANS_TYPE\n\n            and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date\n\n        where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between iph.stt_date and iph.end_date\n\n        group by iph.SOURCE_BILL\n\n    ) h on h.SOURCE_BILL = rc.PK_RENT_CALCULATOR\n\n    where ch.SOURCE_BILL_VERSIONPK in (\n\n        select chh.PK_CONTRACT\n\n        from dwd.dg1_yls_contract_h_c chh\n\n                 join (\n\n            select max(CHECK_DATE)CHECK_DATE,ch.cont_code\n\n            from dwd.dg1_yls_contract_h_c ch\n\n            where upper(ch.SOURCE_BILLTYPE) = upper('lease/ContractChange')\n\n              and ch.SOURCE_BILL_VERSIONPK is null\n\n              and ch.CHECK_DATE > '${yyyy-mm-dd}'\n\n              and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ch.stt_date and ch.end_date\n\n            group by ch.CONT_CODE\n\n        )zj_change on zj_change.CHECK_DATE = chh.check_date and zj_change.cont_code = chh.cont_code\n\n            and upper(chh.SOURCE_BILLTYPE) = upper('lease/ContractChange')\n\n            and chh.SOURCE_BILL_VERSIONPK is null\n\n        where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between chh.stt_date and chh.end_date\n\n\n\n    )\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ch.stt_date and ch.end_date\n\n) history\n\n                   on history.cont_code = cc.cont_code\n\n    -- 计划投放数量\n\n         left join (\n\n    select i5.pk_contract\n\n         ,count(*) plan_count\n\n    from dwd.dg1_yls_inout_plan_c_c i5\n\n    where i5.trans_type in ('0001AA10000000005GRC','0001AA10000000007NGO','0001AA1000000005AB31', '0001AA1000000005AB32')\n\n      and i5.rent_type = 1\n\n    group by i5.pk_contract\n\n) planc\n\n                   on cc.pk_contract = planc.pk_contract\n\n\n\n    -- 租赁物信息\n\n         left join (\n\n    select ypfa1.param_name fixed_assets\n\n         ,ypfa2.param_name fixed_assets_lag\n\n         ,ypfa3.param_name fixed_assets_mid\n\n         ,ypfa4.param_name fixed_assets_sml\n\n         ,prtc.thing_name\n\n         ,prtc.source_bill\n\n    from dwd.dg1_yls_project_rent_thing_c_c prtc\n\n             left join dwd.dg1_yls_parameter_c ypfa1 on ypfa1.pk_parameter = prtc.fixed_assets        and  ypfa1.is_enable = upper('Y') and ypfa1.param_type = 293\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa1.stt_date and ypfa1.end_date\n\n             left join dwd.dg1_yls_parameter_c ypfa2 on ypfa2.pk_parameter = prtc.fixed_assets_large  and  ypfa2.is_enable = upper('Y') and ypfa2.param_type = 293\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa2.stt_date and ypfa2.end_date\n\n             left join dwd.dg1_yls_parameter_c ypfa3 on ypfa3.pk_parameter = prtc.fixed_assets_middle and  ypfa3.is_enable = upper('Y') and ypfa3.param_type = 293\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa3.stt_date and ypfa3.end_date\n\n             left join dwd.dg1_yls_parameter_c ypfa4 on ypfa4.pk_parameter = prtc.fixed_assets_small  and  ypfa4.is_enable = upper('Y') and ypfa4.param_type = 293\n\n        and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa4.stt_date and ypfa4.end_date\n\n    where prtc.is_ref_main = 0\n\n      and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between prtc.stt_date and prtc.end_date\n\n) main_thing\n\n                   on cc.pk_contract = main_thing.source_bill\n\n    -- 主办\n\n         left join dwd.dwd_d01_party_c su\n\n                   on cc.pk_prj_manager = su.cuserid\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between su.stt_date and su.end_date\n\n    -- 协办\n\n         left join dwd.dwd_d01_party_c su2\n\n                   on cc.pk_cust_help = su2.cuserid\n\n                       and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between su2.stt_date and su2.end_date\n\n         left join (\n\n    select adj3.cont_code,\n\n           max(case when (adj3.response_day <= '${yyyy-mm-dd}' and  '${yyyy-mm-dd}' < adj3.response_day_end) or '${yyyy-mm-dd}' <= adj3.response_day then adj3.interrate_after end) as interrate_after,\n\n           max(case when (adj3.response_day <= '${yyyy-mm-dd}' and  '${yyyy-mm-dd}' < adj3.response_day_end) or '${yyyy-mm-dd}' <= adj3.response_day then adj3.interrate_fact_after end) as interrate_fact_after,\n\n           max(case when (adj3.response_day <= '${yyyy-mm-dd}' and  '${yyyy-mm-dd}' < adj3.response_day_end) or '${yyyy-mm-dd}' <= adj3.response_day then adj3.project_irr end) as project_irr,\n\n           max(case when (adj3.response_day <= '${yyyy-mm-dd}' and  '${yyyy-mm-dd}' < adj3.response_day_end) or '${yyyy-mm-dd}' <= adj3.response_day then adj3.contract_xirr end) as contract_xirr\n\n    from(\n\n            select adj.cont_code,\n\n                   adj.response_day,\n\n                   coalesce(min(case when adj.response_day < adj2.response_day then adj2.response_day end),'${yyyy-mm-dd}') response_day_end,\n\n                   min(adj.interrate_after) interrate_after, -- /*调息后基准利率*/\n\n                   min(adj.interrate_fact_after) interrate_fact_after, -- /*调息后实际利率*/\n\n                   min(adj.project_irr) project_irr, -- /*调息后合同irr*/\n\n                   min(adj.contract_xirr) contract_xirr -- /*合同收益xirr*/\n\n            from (select ch.cont_code,\n\n                         ch.check_date as response_day,\n\n                         rc.interrate as interrate_after,\n\n                         rc.new_final_rate as interrate_fact_after,\n\n                         rc.new_project_irr as project_irr,\n\n                         rc.new_contract_xirr as contract_xirr\n\n                  from dwd.dg1_yls_contract_h_c ch\n\n                           join dwd.dg1_yls_rent_calculator_c rc on rc.pk_contract = ch.pk_contract\n\n                  where upper(ch.source_billtype) = upper('lease/contractchange')\n\n                    and ch.source_bill_versionpk is null\n\n                    and ch.billstatus = 9\n\n                    and date'${yyyy-mm-dd}' between ch.stt_date and ch.end_date\n\n                    and date'${yyyy-mm-dd}' between rc.stt_date and rc.end_date\n\n                  union all  -- /*实际调息*/\n\n                  select distinct cc.cont_code,aa.response_day,\n\n                                  aa.interrate_after, -- /*调息后基准利率*/\n\n                                  aa.interrate_fact_after, -- /*调息后实际利率*/\n\n                                  aa.project_irr, -- /*调息后合同irr*/\n\n                                  aa.contract_xirr -- /*合同收益xirr*/\n\n                  from dwd.dg1_yls_adjust_apply_c aa\n\n                           left join dwd.dg1_yls_contract_c_c cc on cc.pk_contract = aa.pk_contract\n\n                      and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date\n\n                  where aa.billstatus = 9\n\n                    and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date\n\n                  union all    -- /*首次调息时，调息前信息*/\n\n                  select distinct cc.cont_code,to_char(to_date(aa.response_day, 'yyyy-mm-dd') - 1, 'yyyy-mm-dd') as response_day,\n\n                                  aa.interrate_before as interrate_after, -- /*调息前基准利率*/\n\n                                  aa.interrate_fact_before as interrate_fact_after, -- /*调息前实际利率*/\n\n                                  aa.cont_irr_befor as project_irr, -- /*调息前合同irr*/\n\n                                  aa.contract_xirr_before as contract_xirr -- /*调息前合同收益xirr*/\n\n                  from dwd.dg1_yls_adjust_apply_c aa\n\n                           join (select min(a.response_day) as response_day,a.pk_contract\n\n                                 from dwd.dg1_yls_adjust_apply_c a\n\n                                 where a.billstatus = 9\n\n                                   and date'${yyyy-mm-dd}' between a.stt_date and a.end_date\n\n                                 group by a.pk_contract) minday\n\n                                on minday.pk_contract = aa.pk_contract and minday.response_day = aa.response_day\n\n                                    and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date\n\n                           left join dwd.dg1_yls_contract_c_c cc\n\n                                     on cc.pk_contract = aa.pk_contract\n\n                                         and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date) adj\n\n                     left join (\n\n                select ch.cont_code,\n\n                       ch.check_date as response_day,\n\n                       rc.interrate as interrate_after,\n\n                       rc.new_final_rate as interrate_fact_after,\n\n                       rc.new_project_irr as project_irr,\n\n                       rc.new_contract_xirr as contract_xirr\n\n                from dwd.dg1_yls_contract_h_c ch\n\n                         join dwd.dg1_yls_rent_calculator_c rc on rc.pk_contract = ch.pk_contract\n\n                where upper(ch.source_billtype) = upper('lease/contractchange')\n\n                  and ch.source_bill_versionpk is null\n\n                  and ch.billstatus = 9\n\n                  and date'${yyyy-mm-dd}' between ch.stt_date and ch.end_date\n\n                  and date'${yyyy-mm-dd}' between rc.stt_date and rc.end_date\n\n                union all\n\n                select distinct cc.cont_code,aa.response_day,\n\n                                aa.interrate_after, -- /*调息后基准利率*/\n\n                                aa.interrate_fact_after, -- /*调息后实际利率*/\n\n                                aa.project_irr, -- /*调息后合同irr*/\n\n                                aa.contract_xirr -- /*合同收益xirr*/\n\n                from dwd.dg1_yls_adjust_apply_c aa\n\n                         left join dwd.dg1_yls_contract_c_c cc on cc.pk_contract = aa.pk_contract\n\n                where aa.billstatus = 9\n\n                  and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date\n\n                  and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date\n\n                union all\n\n                select distinct cc.cont_code,to_char(to_date(aa.response_day, 'yyyy-mm-dd') - 1, 'yyyy-mm-dd') as response_day,\n\n                                aa.interrate_before as interrate_after, -- /*调息前基准利率*/\n\n                                aa.interrate_fact_before as interrate_fact_after, -- /*调息前实际利率*/\n\n                                aa.cont_irr_befor as project_irr, -- /*调息前合同irr*/\n\n                                aa.contract_xirr_before as contract_xirr -- /*调息前合同收益xirr*/\n\n                from dwd.dg1_yls_adjust_apply_c aa\n\n                         join (select min(a.response_day) as response_day,a.pk_contract\n\n                               from dwd.dg1_yls_adjust_apply_c a\n\n                               where a.billstatus = 9\n\n                                 and date'${yyyy-mm-dd}' between a.stt_date and a.end_date\n\n                               group by a.pk_contract) minday\n\n                              on minday.pk_contract = aa.pk_contract and minday.response_day = aa.response_day\n\n                         left join dwd.dg1_yls_contract_c_c cc\n\n                                   on cc.pk_contract = aa.pk_contract\n\n                                       and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date\n\n                where date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date\n\n            ) adj2  on adj2.cont_code = adj.cont_code\n\n            group by adj.cont_code,adj.response_day\n\n        ) adj3\n\n    group by adj3.cont_code\n\n) adj on adj.cont_code = cc.cont_code\n\nwhere to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between cc.stt_date and cc.end_date\n\n  -- PK_PARAM_TYPE = '0001AA1000000001RC3C' 合同状态\n\n  and cc.cont_status > '1'\n\n  and cc.cont_status not in ('5' ,'7')\n"
  },
  {
    "path": "superior-oracle-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-postgres-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-postgres-parser</artifactId>\n    <name>superior-postgres-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "superior-postgres-parser/src/main/antlr4/io/github/melin/superior/parser/postgre/antlr4/PostgreSqlLexer.g4",
    "content": "/*\nbased on\nhttps://github.com/tunnelvisionlabs/antlr4-grammar-postgresql/blob/master/src/com/tunnelvisionlabs/postgresql/PostgreSqlLexer.g4\n*/\n\n/*\n * [The \"MIT license\"]\n * Copyright (C) 2014 Sam Harwell, Tunnel Vision Laboratories, LLC\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * 1. The above copyright notice and this permission notice shall be included in\n *    all copies or substantial portions of the Software.\n * 2. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n *    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n *    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n *    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n *    DEALINGS IN THE SOFTWARE.\n * 3. Except as contained in this notice, the name of Tunnel Vision\n *    Laboratories, LLC. shall not be used in advertising or otherwise to\n *    promote the sale, use or other dealings in this Software without prior\n *    written authorization from Tunnel Vision Laboratories, LLC.\n */\nlexer grammar PostgreSqlLexer;\n/* Reference:\n * http://www.postgresql.org/docs/9.3/static/sql-syntax-lexical.html\n */\n\noptions {\n   superClass = PostgreSqlLexerBase;\n}\n\n@ header\n{\n}\n@ members\n{\n/* This field stores the tags which are used to detect the end of a dollar-quoted string literal.\n */\n}\n//\n\n// SPECIAL CHARACTERS (4.1.4)\n\n//\n\n// Note that Asterisk is a valid operator, but does not have the type Operator due to its syntactic use in locations\n\n// that are not expressions.\n\nDollar\n   : '$'\n   ;\n\nOPEN_PAREN\n   : '('\n   ;\n\nCLOSE_PAREN\n   : ')'\n   ;\n\nOPEN_BRACKET\n   : '['\n   ;\n\nCLOSE_BRACKET\n   : ']'\n   ;\n\nCOMMA\n   : ','\n   ;\n\nSEMI\n   : ';'\n   ;\n\nCOLON\n   : ':'\n   ;\n\nSTAR\n   : '*'\n   ;\n\nEQUAL\n   : '='\n   ;\n\nDOT\n   : '.'\n   ;\n   //NamedArgument\t: ':=';\n\nPLUS\n   : '+'\n   ;\n\nMINUS\n   : '-'\n   ;\n\nSLASH\n   : '/'\n   ;\n\nCARET\n   : '^'\n   ;\n\nLT\n   : '<'\n   ;\n\nGT\n   : '>'\n   ;\n\nLESS_LESS\n   : '<<'\n   ;\n\nGREATER_GREATER\n   : '>>'\n   ;\n\nCOLON_EQUALS\n   : ':='\n   ;\n\nLESS_EQUALS\n   : '<='\n   ;\n\nEQUALS_GREATER\n   : '=>'\n   ;\n\nGREATER_EQUALS\n   : '>='\n   ;\n\nDOT_DOT\n   : '..'\n   ;\n\nNOT_EQUALS\n   : '<>'\n   ;\n\nTYPECAST\n   : '::'\n   ;\n\nPERCENT\n   : '%'\n   ;\n\nPARAM\n   : '$' ([0-9])+\n   ;\n   //\n\n   // OPERATORS (4.1.3)\n\n   //\n\n   // this rule does not allow + or - at the end of a multi-character operator\n\nOperator\n   : ((OperatorCharacter | ('+' | '-'\n   {checkLA('-')}?)+ (OperatorCharacter | '/'\n   {checkLA('*')}?) | '/'\n   {checkLA('*')}?)+ | // special handling for the single-character operators + and -\n   [+-])\n   //TODO somehow rewrite this part without using Actions\n\n   {\n    HandleLessLessGreaterGreater();\n   }\n   ;\n/* This rule handles operators which end with + or -, and sets the token type to Operator. It is comprised of four\n * parts, in order:\n *\n *   1. A prefix, which does not contain a character from the required set which allows + or - to appear at the end of\n *      the operator.\n *   2. A character from the required set which allows + or - to appear at the end of the operator.\n *   3. An optional sub-token which takes the form of an operator which does not include a + or - at the end of the\n *      sub-token.\n *   4. A suffix sequence of + and - characters.\n */\n\n\nOperatorEndingWithPlusMinus\n   : (OperatorCharacterNotAllowPlusMinusAtEnd | '-'\n   {checkLA('-')}? | '/'\n   {checkLA('*')}?)* OperatorCharacterAllowPlusMinusAtEnd Operator? ('+' | '-'\n   {checkLA('-')}?)+ -> type (Operator)\n   ;\n   // Each of the following fragment rules omits the +, -, and / characters, which must always be handled in a special way\n\n   // by the operator rules above.\n\nfragment OperatorCharacter\n   : [*<>=~!@%^&|`?#]\n   ;\n   // these are the operator characters that don't count towards one ending with + or -\n\nfragment OperatorCharacterNotAllowPlusMinusAtEnd\n   : [*<>=+]\n   ;\n   // an operator may end with + or - if it contains one of these characters\n\nfragment OperatorCharacterAllowPlusMinusAtEnd\n   : [~!@%^&|`?#]\n   ;\n   //\n\n   // KEYWORDS (Appendix C)\n\n   //\n\n   //\n\n   // reserved keywords\n\n   //\n\nALL\n   : 'ALL'\n   ;\n\nANALYSE\n   : 'ANALYSE'\n   ;\n\nANALYZE\n   : 'ANALYZE'\n   ;\n\nAND\n   : 'AND'\n   ;\n\nANY\n   : 'ANY'\n   ;\n\nARRAY\n   : 'ARRAY'\n   ;\n\nAS\n   : 'AS'\n   ;\n\nASC\n   : 'ASC'\n   ;\n\nASYMMETRIC\n   : 'ASYMMETRIC'\n   ;\n\nBOTH\n   : 'BOTH'\n   ;\n\nCASE\n   : 'CASE'\n   ;\n\nCAST\n   : 'CAST'\n   ;\n\nCHECK\n   : 'CHECK'\n   ;\n\nCOLLATE\n   : 'COLLATE'\n   ;\n\nCOLUMN\n   : 'COLUMN'\n   ;\n\n CONSTRAINT\n   : 'CONSTRAINT'\n   ;\n\nCREATE\n   : 'CREATE'\n   ;\n\nCURRENT_CATALOG\n   : 'CURRENT_CATALOG'\n   ;\n\nCURRENT_DATE\n   : 'CURRENT_DATE'\n   ;\n\nCURRENT_ROLE\n   : 'CURRENT_ROLE'\n   ;\n\nCURRENT_TIME\n   : 'CURRENT_TIME'\n   ;\n\nCURRENT_TIMESTAMP\n   : 'CURRENT_TIMESTAMP'\n   ;\n\nCURRENT_USER\n   : 'CURRENT_USER'\n   ;\n\nDEFAULT\n   : 'DEFAULT'\n   ;\n\nDEFERRABLE\n   : 'DEFERRABLE'\n   ;\n\nDESC\n   : 'DESC'\n   ;\n\nDISTINCT\n   : 'DISTINCT'\n   ;\n\nDO\n   : 'DO'\n   ;\n\nELSE\n   : 'ELSE'\n   ;\n\nEXCEPT\n   : 'EXCEPT'\n   ;\n\nFALSE_P\n   : 'FALSE'\n   ;\n\nFETCH\n   : 'FETCH'\n   ;\n\nFOR\n   : 'FOR'\n   ;\n\nFOREIGN\n   : 'FOREIGN'\n   ;\n\nFROM\n   : 'FROM'\n   ;\n\nGRANT\n   : 'GRANT'\n   ;\n\nGROUP_P\n   : 'GROUP'\n   ;\n\nHAVING\n   : 'HAVING'\n   ;\n\nIN_P\n   : 'IN'\n   ;\n\nINITIALLY\n   : 'INITIALLY'\n   ;\n\nINTERSECT\n   : 'INTERSECT'\n   ;\n\nINTO\n   : 'INTO'\n   ;\n\nLATERAL_P\n   : 'LATERAL'\n   ;\n\nLEADING\n   : 'LEADING'\n   ;\n\nLIMIT\n   : 'LIMIT'\n   ;\n\nLOCALTIME\n   : 'LOCALTIME'\n   ;\n\nLOCALTIMESTAMP\n   : 'LOCALTIMESTAMP'\n   ;\n\nNOT\n   : 'NOT'\n   ;\n\nNULL_P\n   : 'NULL'\n   ;\n\nOFFSET\n   : 'OFFSET'\n   ;\n\nON\n   : 'ON'\n   ;\n\nONLY\n   : 'ONLY'\n   ;\n\nOR\n   : 'OR'\n   ;\n\nORDER\n   : 'ORDER'\n   ;\n\nPLACING\n   : 'PLACING'\n   ;\n\nPRIMARY\n   : 'PRIMARY'\n   ;\n\nREFERENCES\n   : 'REFERENCES'\n   ;\n\nRETURNING\n   : 'RETURNING'\n   ;\n\nSELECT\n   : 'SELECT'\n   ;\n\nSESSION_USER\n   : 'SESSION_USER'\n   ;\n\nSOME\n   : 'SOME'\n   ;\n\nSYMMETRIC\n   : 'SYMMETRIC'\n   ;\n\nTABLE\n   : 'TABLE'\n   ;\n\nTHEN\n   : 'THEN'\n   ;\n\nTO\n   : 'TO'\n   ;\n\nTRAILING\n   : 'TRAILING'\n   ;\n\nTRUE_P\n   : 'TRUE'\n   ;\n\nUNION\n   : 'UNION'\n   ;\n\nUNIQUE\n   : 'UNIQUE'\n   ;\n\nUSER\n   : 'USER'\n   ;\n\nUSING\n   : 'USING'\n   ;\n\nVARIADIC\n   : 'VARIADIC'\n   ;\n\nWHEN\n   : 'WHEN'\n   ;\n\nWHERE\n   : 'WHERE'\n   ;\n\nWINDOW\n   : 'WINDOW'\n   ;\n\nWITH\n   : 'WITH'\n   ;\n\n   //\n\n   // reserved keywords (can be function or type)\n\n   //\n\nAUTHORIZATION\n   : 'AUTHORIZATION'\n   ;\n\nBINARY\n   : 'BINARY'\n   ;\n\nCOLLATION\n   : 'COLLATION'\n   ;\n\nCONCURRENTLY\n   : 'CONCURRENTLY'\n   ;\n\nCROSS\n   : 'CROSS'\n   ;\n\nCURRENT_SCHEMA\n   : 'CURRENT_SCHEMA'\n   ;\n\nFREEZE\n   : 'FREEZE'\n   ;\n\nFULL\n   : 'FULL'\n   ;\n\nILIKE\n   : 'ILIKE'\n   ;\n\nINNER_P\n   : 'INNER'\n   ;\n\nIS\n   : 'IS'\n   ;\n\nISNULL\n   : 'ISNULL'\n   ;\n\nJOIN\n   : 'JOIN'\n   ;\n\nLEFT\n   : 'LEFT'\n   ;\n\nLIKE\n   : 'LIKE'\n   ;\n\nNATURAL\n   : 'NATURAL'\n   ;\n\nNOTNULL\n   : 'NOTNULL'\n   ;\n\nOUTER_P\n   : 'OUTER'\n   ;\n\nOVER\n   : 'OVER'\n   ;\n\nOVERLAPS\n   : 'OVERLAPS'\n   ;\n\nRIGHT\n   : 'RIGHT'\n   ;\n\nSIMILAR\n   : 'SIMILAR'\n   ;\n\nVERBOSE\n   : 'VERBOSE'\n   ;\n   //\n\n   // non-reserved keywords\n\n   //\n\nABORT_P\n   : 'ABORT'\n   ;\n\nABSOLUTE_P\n   : 'ABSOLUTE'\n   ;\n\nACCESS\n   : 'ACCESS'\n   ;\n\nACTION\n   : 'ACTION'\n   ;\n\nADD_P\n   : 'ADD'\n   ;\n\nADMIN\n   : 'ADMIN'\n   ;\n\nAFTER\n   : 'AFTER'\n   ;\n\nAGGREGATE\n   : 'AGGREGATE'\n   ;\n\nALSO\n   : 'ALSO'\n   ;\n\nALTER\n   : 'ALTER'\n   ;\n\nALWAYS\n   : 'ALWAYS'\n   ;\n\nASSERTION\n   : 'ASSERTION'\n   ;\n\nASSIGNMENT\n   : 'ASSIGNMENT'\n   ;\n\nAT\n   : 'AT'\n   ;\n\nATTRIBUTE\n   : 'ATTRIBUTE'\n   ;\n\nBACKWARD\n   : 'BACKWARD'\n   ;\n\nBEFORE\n   : 'BEFORE'\n   ;\n\nBEGIN_P\n   : 'BEGIN'\n   ;\n\nBY\n   : 'BY'\n   ;\n\nCACHE\n   : 'CACHE'\n   ;\n\nCALLED\n   : 'CALLED'\n   ;\n\nCASCADE\n   : 'CASCADE'\n   ;\n\nCASCADED\n   : 'CASCADED'\n   ;\n\nCATALOG\n   : 'CATALOG'\n   ;\n\nCHAIN\n   : 'CHAIN'\n   ;\n\nCHARACTERISTICS\n   : 'CHARACTERISTICS'\n   ;\n\nCHECKPOINT\n   : 'CHECKPOINT'\n   ;\n\nCLASS\n   : 'CLASS'\n   ;\n\nCLOSE\n   : 'CLOSE'\n   ;\n\nCLUSTER\n   : 'CLUSTER'\n   ;\n\nCOMMENT\n   : 'COMMENT'\n   ;\n\nCOMMENTS\n   : 'COMMENTS'\n   ;\n\nCOMMIT\n   : 'COMMIT'\n   ;\n\nCOMMITTED\n   : 'COMMITTED'\n   ;\n\nCONFIGURATION\n   : 'CONFIGURATION'\n   ;\n\nCONNECTION\n   : 'CONNECTION'\n   ;\n\nCONSTRAINTS\n   : 'CONSTRAINTS'\n   ;\n\nCONTENT_P\n   : 'CONTENT'\n   ;\n\nCONTINUE_P\n   : 'CONTINUE'\n   ;\n\nCONVERSION_P\n   : 'CONVERSION'\n   ;\n\nCOPY\n   : 'COPY'\n   ;\n\nCOST\n   : 'COST'\n   ;\n\nCSV\n   : 'CSV'\n   ;\n\nCURSOR\n   : 'CURSOR'\n   ;\n\nCYCLE\n   : 'CYCLE'\n   ;\n\nDATA_P\n   : 'DATA'\n   ;\n\nDATABASE\n   : 'DATABASE'\n   ;\n\nDAY_P\n   : 'DAY'\n   ;\n\nDEALLOCATE\n   : 'DEALLOCATE'\n   ;\n\nDECLARE\n   : 'DECLARE'\n   ;\n\nDEFAULTS\n   : 'DEFAULTS'\n   ;\n\nDEFERRED\n   : 'DEFERRED'\n   ;\n\nDEFINER\n   : 'DEFINER'\n   ;\n\nDELETE_P\n   : 'DELETE'\n   ;\n\nDELIMITER\n   : 'DELIMITER'\n   ;\n\nDELIMITERS\n   : 'DELIMITERS'\n   ;\n\nDICTIONARY\n   : 'DICTIONARY'\n   ;\n\nDISABLE_P\n   : 'DISABLE'\n   ;\n\nDISCARD\n   : 'DISCARD'\n   ;\n\nDOCUMENT_P\n   : 'DOCUMENT'\n   ;\n\nDOMAIN_P\n   : 'DOMAIN'\n   ;\n\nDOUBLE_P\n   : 'DOUBLE'\n   ;\n\nDROP\n   : 'DROP'\n   ;\n\nEACH\n   : 'EACH'\n   ;\n\nENABLE_P\n   : 'ENABLE'\n   ;\n\nENCODING\n   : 'ENCODING'\n   ;\n\nENCRYPTED\n   : 'ENCRYPTED'\n   ;\n\nENUM_P\n   : 'ENUM'\n   ;\n\nESCAPE\n   : 'ESCAPE'\n   ;\n\nEVENT\n   : 'EVENT'\n   ;\n\nEXCLUDE\n   : 'EXCLUDE'\n   ;\n\nEXCLUDING\n   : 'EXCLUDING'\n   ;\n\nEXCLUSIVE\n   : 'EXCLUSIVE'\n   ;\n\nEXECUTE\n   : 'EXECUTE'\n   ;\n\nEXPLAIN\n   : 'EXPLAIN'\n   ;\n\nEXTENSION\n   : 'EXTENSION'\n   ;\n\nEXTERNAL\n   : 'EXTERNAL'\n   ;\n\nFAMILY\n   : 'FAMILY'\n   ;\n\nFIRST_P\n   : 'FIRST'\n   ;\n\nFOLLOWING\n   : 'FOLLOWING'\n   ;\n\nFORCE\n   : 'FORCE'\n   ;\n\nFORWARD\n   : 'FORWARD'\n   ;\n\nFUNCTION\n   : 'FUNCTION'\n   ;\n\nFUNCTIONS\n   : 'FUNCTIONS'\n   ;\n\nGLOBAL\n   : 'GLOBAL'\n   ;\n\nGRANTED\n   : 'GRANTED'\n   ;\n\nHANDLER\n   : 'HANDLER'\n   ;\n\nHEADER_P\n   : 'HEADER'\n   ;\n\nHOLD\n   : 'HOLD'\n   ;\n\nHOUR_P\n   : 'HOUR'\n   ;\n\nIDENTITY_P\n   : 'IDENTITY'\n   ;\n\nIF_P\n   : 'IF'\n   ;\n\nIMMEDIATE\n   : 'IMMEDIATE'\n   ;\n\nIMMUTABLE\n   : 'IMMUTABLE'\n   ;\n\nIMPLICIT_P\n   : 'IMPLICIT'\n   ;\n\nINCLUDING\n   : 'INCLUDING'\n   ;\n\nINCREMENT\n   : 'INCREMENT'\n   ;\n\nINDEX\n   : 'INDEX'\n   ;\n\nINDEXES\n   : 'INDEXES'\n   ;\n\nINHERIT\n   : 'INHERIT'\n   ;\n\nINHERITS\n   : 'INHERITS'\n   ;\n\nINLINE_P\n   : 'INLINE'\n   ;\n\nINSENSITIVE\n   : 'INSENSITIVE'\n   ;\n\nINSERT\n   : 'INSERT'\n   ;\n\nINSTEAD\n   : 'INSTEAD'\n   ;\n\nINVOKER\n   : 'INVOKER'\n   ;\n\nISOLATION\n   : 'ISOLATION'\n   ;\n\nKEY\n   : 'KEY'\n   ;\n\nLABEL\n   : 'LABEL'\n   ;\n\nLANGUAGE\n   : 'LANGUAGE'\n   ;\n\nLARGE_P\n   : 'LARGE'\n   ;\n\nLAST_P\n   : 'LAST'\n   ;\n   //LC_COLLATE\t\t\t: 'LC'_'COLLATE;\n\n   //LC_CTYPE\t\t\t: 'LC'_'CTYPE;\n\nLEAKPROOF\n   : 'LEAKPROOF'\n   ;\n\nSHIPPABLE\n   : 'SHIPPABLE'\n   ;\n\nFENCED\n   : 'FENCED'\n   ;\n\nPACKAGE\n   : 'PACKAGE'\n   ;\n\nLEVEL\n   : 'LEVEL'\n   ;\n\nLISTEN\n   : 'LISTEN'\n   ;\n\nLOAD\n   : 'LOAD'\n   ;\n\nLOCAL\n   : 'LOCAL'\n   ;\n\nLOCATION\n   : 'LOCATION'\n   ;\n\nLOCK_P\n   : 'LOCK'\n   ;\n\nMAPPING\n   : 'MAPPING'\n   ;\n\nMATCH\n   : 'MATCH'\n   ;\n\nMATCHED\n   : 'MATCHED'\n   ;\n\nMATERIALIZED\n   : 'MATERIALIZED'\n   ;\n\nMAXVALUE\n   : 'MAXVALUE'\n   ;\n\nMERGE\n   : 'MERGE'\n   ;\n\nMINUTE_P\n   : 'MINUTE'\n   ;\n\nMINVALUE\n   : 'MINVALUE'\n   ;\n\nMODE\n   : 'MODE'\n   ;\n\nMONTH_P\n   : 'MONTH'\n   ;\n\nMOVE\n   : 'MOVE'\n   ;\n\nNAME_P\n   : 'NAME'\n   ;\n\nNAMES\n   : 'NAMES'\n   ;\n\nNEXT\n   : 'NEXT'\n   ;\n\nNO\n   : 'NO'\n   ;\n\nNOTHING\n   : 'NOTHING'\n   ;\n\nNOTIFY\n   : 'NOTIFY'\n   ;\n\nNOWAIT\n   : 'NOWAIT'\n   ;\n\nNULLS_P\n   : 'NULLS'\n   ;\n\nOBJECT_P\n   : 'OBJECT'\n   ;\n\nOF\n   : 'OF'\n   ;\n\nOFF\n   : 'OFF'\n   ;\n\nOIDS\n   : 'OIDS'\n   ;\n\nOPERATOR\n   : 'OPERATOR'\n   ;\n\nOPTION\n   : 'OPTION'\n   ;\n\nOPTIONS\n   : 'OPTIONS'\n   ;\n\nOWNED\n   : 'OWNED'\n   ;\n\nOWNER\n   : 'OWNER'\n   ;\n\nPARSER\n   : 'PARSER'\n   ;\n\nPARTIAL\n   : 'PARTIAL'\n   ;\n\nPARTITION\n   : 'PARTITION'\n   ;\n\nPASSING\n   : 'PASSING'\n   ;\n\nPASSWORD\n   : 'PASSWORD'\n   ;\n\nPLANS\n   : 'PLANS'\n   ;\n\nPRECEDING\n   : 'PRECEDING'\n   ;\n\nPREPARE\n   : 'PREPARE'\n   ;\n\nPREPARED\n   : 'PREPARED'\n   ;\n\nPRESERVE\n   : 'PRESERVE'\n   ;\n\nPRIOR\n   : 'PRIOR'\n   ;\n\nPRIVILEGES\n   : 'PRIVILEGES'\n   ;\n\nPROCEDURAL\n   : 'PROCEDURAL'\n   ;\n\nPROCEDURE\n   : 'PROCEDURE'\n   ;\n\nPROGRAM\n   : 'PROGRAM'\n   ;\n\nQUOTE\n   : 'QUOTE'\n   ;\n\nRANGE\n   : 'RANGE'\n   ;\n\nREAD\n   : 'READ'\n   ;\n\nREASSIGN\n   : 'REASSIGN'\n   ;\n\nRECHECK\n   : 'RECHECK'\n   ;\n\nRECURSIVE\n   : 'RECURSIVE'\n   ;\n\nREF\n   : 'REF'\n   ;\n\nREFRESH\n   : 'REFRESH'\n   ;\n\nREINDEX\n   : 'REINDEX'\n   ;\n\nRELATIVE_P\n   : 'RELATIVE'\n   ;\n\nRELEASE\n   : 'RELEASE'\n   ;\n\nRENAME\n   : 'RENAME'\n   ;\n\nREPEATABLE\n   : 'REPEATABLE'\n   ;\n\nREPLACE\n   : 'REPLACE'\n   ;\n\nREPLICA\n   : 'REPLICA'\n   ;\n\nRESET\n   : 'RESET'\n   ;\n\nRESTART\n   : 'RESTART'\n   ;\n\nRESTRICT\n   : 'RESTRICT'\n   ;\n\nRETURNS\n   : 'RETURNS'\n   ;\n\nREVOKE\n   : 'REVOKE'\n   ;\n\nROLE\n   : 'ROLE'\n   ;\n\nROLLBACK\n   : 'ROLLBACK'\n   ;\n\nROWS\n   : 'ROWS'\n   ;\n\nRULE\n   : 'RULE'\n   ;\n\nSAVEPOINT\n   : 'SAVEPOINT'\n   ;\n\nSCHEMA\n   : 'SCHEMA'\n   ;\n\nSCROLL\n   : 'SCROLL'\n   ;\n\nSEARCH\n   : 'SEARCH'\n   ;\n\nSECOND_P\n   : 'SECOND'\n   ;\n\nSECURITY\n   : 'SECURITY'\n   ;\n\nSEQUENCE\n   : 'SEQUENCE'\n   ;\n\nSEQUENCES\n   : 'SEQUENCES'\n   ;\n\nSERIALIZABLE\n   : 'SERIALIZABLE'\n   ;\n\nSERVER\n   : 'SERVER'\n   ;\n\nSESSION\n   : 'SESSION'\n   ;\n\nSET\n   : 'SET'\n   ;\n\nSHARE\n   : 'SHARE'\n   ;\n\nSHOW\n   : 'SHOW'\n   ;\n\nSIMPLE\n   : 'SIMPLE'\n   ;\n\nSNAPSHOT\n   : 'SNAPSHOT'\n   ;\n\nSTABLE\n   : 'STABLE'\n   ;\n\nSTANDALONE_P\n   : 'STANDALONE'\n   ;\n\nSTART\n   : 'START'\n   ;\n\nSTATEMENT\n   : 'STATEMENT'\n   ;\n\nSTATISTICS\n   : 'STATISTICS'\n   ;\n\nSTDIN\n   : 'STDIN'\n   ;\n\nSTDOUT\n   : 'STDOUT'\n   ;\n\nSTORAGE\n   : 'STORAGE'\n   ;\n\nSTRICT_P\n   : 'STRICT'\n   ;\n\nSTRIP_P\n   : 'STRIP'\n   ;\n\nSYSID\n   : 'SYSID'\n   ;\n\nSYSTEM_P\n   : 'SYSTEM'\n   ;\n\nTABLES\n   : 'TABLES'\n   ;\n\nTABLESPACE\n   : 'TABLESPACE'\n   ;\n\nTEMP\n   : 'TEMP'\n   ;\n\nTEMPLATE\n   : 'TEMPLATE'\n   ;\n\nTEMPORARY\n   : 'TEMPORARY'\n   ;\n\nTEXT_P\n   : 'TEXT'\n   ;\n\nTRANSACTION\n   : 'TRANSACTION'\n   ;\n\nTRIGGER\n   : 'TRIGGER'\n   ;\n\nTRUNCATE\n   : 'TRUNCATE'\n   ;\n\nTRUSTED\n   : 'TRUSTED'\n   ;\n\nTYPE_P\n   : 'TYPE'\n   ;\n\nTYPES_P\n   : 'TYPES'\n   ;\n\nUNBOUNDED\n   : 'UNBOUNDED'\n   ;\n\nUNCOMMITTED\n   : 'UNCOMMITTED'\n   ;\n\nUNENCRYPTED\n   : 'UNENCRYPTED'\n   ;\n\nUNKNOWN\n   : 'UNKNOWN'\n   ;\n\nUNLISTEN\n   : 'UNLISTEN'\n   ;\n\nUNLOGGED\n   : 'UNLOGGED'\n   ;\n\nUNTIL\n   : 'UNTIL'\n   ;\n\nUPDATE\n   : 'UPDATE'\n   ;\n\nVACUUM\n   : 'VACUUM'\n   ;\n\nVALID\n   : 'VALID'\n   ;\n\nVALIDATE\n   : 'VALIDATE'\n   ;\n\nVALIDATOR\n   : 'VALIDATOR'\n   ;\n   //VALUE\t\t\t\t: 'VALUE;\n\nVARYING\n   : 'VARYING'\n   ;\n\nVERSION_P\n   : 'VERSION'\n   ;\n\nVIEW\n   : 'VIEW'\n   ;\n\nVOLATILE\n   : 'VOLATILE'\n   ;\n\nWHITESPACE_P\n   : 'WHITESPACE'\n   ;\n\nWITHOUT\n   : 'WITHOUT'\n   ;\n\nWORK\n   : 'WORK'\n   ;\n\nWRAPPER\n   : 'WRAPPER'\n   ;\n\nWRITE\n   : 'WRITE'\n   ;\n\nXML_P\n   : 'XML'\n   ;\n\nYEAR_P\n   : 'YEAR'\n   ;\n\nYES_P\n   : 'YES'\n   ;\n\nZONE\n   : 'ZONE'\n   ;\n   //\n\n   // non-reserved keywords (can not be function or type)\n\n   //\n\nBETWEEN\n   : 'BETWEEN'\n   ;\n\nBIGINT\n   : 'BIGINT'\n   ;\n\nBIT\n   : 'BIT'\n   ;\n\nBOOLEAN_P\n   : 'BOOLEAN'\n   ;\n\nCHAR_P\n   : 'CHAR'\n   ;\n\nCHARACTER\n   : 'CHARACTER'\n   ;\n\nCOALESCE\n   : 'COALESCE'\n   ;\n\nDEC\n   : 'DEC'\n   ;\n\nDECIMAL_P\n   : 'DECIMAL'\n   ;\n\nEXISTS\n   : 'EXISTS'\n   ;\n\nEXTRACT\n   : 'EXTRACT'\n   ;\n\nFLOAT_P\n   : 'FLOAT'\n   ;\n\nGREATEST\n   : 'GREATEST'\n   ;\n\nINOUT\n   : 'INOUT'\n   ;\n\nINT_P\n   : 'INT'\n   ;\n\nINTEGER\n   : 'INTEGER'\n   ;\n\nINTERVAL\n   : 'INTERVAL'\n   ;\n\nLEAST\n   : 'LEAST'\n   ;\n\nNATIONAL\n   : 'NATIONAL'\n   ;\n\nNCHAR\n   : 'NCHAR'\n   ;\n\nNONE\n   : 'NONE'\n   ;\n\nNULLIF\n   : 'NULLIF'\n   ;\n\nNUMERIC\n   : 'NUMERIC'\n   ;\n\nOVERLAY\n   : 'OVERLAY'\n   ;\n\nPOSITION\n   : 'POSITION'\n   ;\n\nPRECISION\n   : 'PRECISION'\n   ;\n\nREAL\n   : 'REAL'\n   ;\n\nROW\n   : 'ROW'\n   ;\n\nSETOF\n   : 'SETOF'\n   ;\n\nSMALLINT\n   : 'SMALLINT'\n   ;\n\nSUBSTRING\n   : 'SUBSTRING'\n   ;\n\nTIME\n   : 'TIME'\n   ;\n\nTIMESTAMP\n   : 'TIMESTAMP'\n   ;\n\nTREAT\n   : 'TREAT'\n   ;\n\nTRIM\n   : 'TRIM'\n   ;\n\nVALUES\n   : 'VALUES'\n   ;\n\nVARCHAR\n   : 'VARCHAR'\n   ;\n\nXMLATTRIBUTES\n   : 'XMLATTRIBUTES'\n   ;\n\nXMLCOMMENT\n   : 'XMLCOMMENT'\n   ;\n\nXMLAGG\n   : 'XMLAGG'\n   ;\n\nXML_IS_WELL_FORMED\n   : 'XML_IS_WELL_FORMED'\n   ;\n\nXML_IS_WELL_FORMED_DOCUMENT\n   : 'XML_IS_WELL_FORMED_DOCUMENT'\n   ;\n\nXML_IS_WELL_FORMED_CONTENT\n   : 'XML_IS_WELL_FORMED_CONTENT'\n   ;\n\nXPATH\n   : 'XPATH'\n   ;\n\nXPATH_EXISTS\n   : 'XPATH_EXISTS'\n   ;\n\nXMLCONCAT\n   : 'XMLCONCAT'\n   ;\n\nXMLELEMENT\n   : 'XMLELEMENT'\n   ;\n\nXMLEXISTS\n   : 'XMLEXISTS'\n   ;\n\nXMLFOREST\n   : 'XMLFOREST'\n   ;\n\nXMLPARSE\n   : 'XMLPARSE'\n   ;\n\nXMLPI\n   : 'XMLPI'\n   ;\n\nXMLROOT\n   : 'XMLROOT'\n   ;\n\nXMLSERIALIZE\n   : 'XMLSERIALIZE'\n   ;\n   //MISSED\n\nCALL\n   : 'CALL'\n   ;\n\nCURRENT_P\n   : 'CURRENT'\n   ;\n\nATTACH\n   : 'ATTACH'\n   ;\n\nDETACH\n   : 'DETACH'\n   ;\n\nEXPRESSION\n   : 'EXPRESSION'\n   ;\n\nGENERATED\n   : 'GENERATED'\n   ;\n\nLOGGED\n   : 'LOGGED'\n   ;\n\nSTORED\n   : 'STORED'\n   ;\n\nINCLUDE\n   : 'INCLUDE'\n   ;\n\nROUTINE\n   : 'ROUTINE'\n   ;\n\nTRANSFORM\n   : 'TRANSFORM'\n   ;\n\nIMPORT_P\n   : 'IMPORT'\n   ;\n\nPOLICY\n   : 'POLICY'\n   ;\n\nMETHOD\n   : 'METHOD'\n   ;\n\nREFERENCING\n   : 'REFERENCING'\n   ;\n\nNEW\n   : 'NEW'\n   ;\n\nOLD\n   : 'OLD'\n   ;\n\nVALUE_P\n   : 'VALUE'\n   ;\n\nSUBSCRIPTION\n   : 'SUBSCRIPTION'\n   ;\n\nPUBLICATION\n   : 'PUBLICATION'\n   ;\n\nOUT_P\n   : 'OUT'\n   ;\n\nEND_P\n   : 'END'\n   ;\n\nROUTINES\n   : 'ROUTINES'\n   ;\n\nSCHEMAS\n   : 'SCHEMAS'\n   ;\n\nPROCEDURES\n   : 'PROCEDURES'\n   ;\n\nINPUT_P\n   : 'INPUT'\n   ;\n\nSUPPORT\n   : 'SUPPORT'\n   ;\n\nPARALLEL\n   : 'PARALLEL'\n   ;\n\nSQL_P\n   : 'SQL'\n   ;\n\nDEPENDS\n   : 'DEPENDS'\n   ;\n\nOVERRIDING\n   : 'OVERRIDING'\n   ;\n\n// support gauss start--------------------------------\nAUTOMAPPED\n   : 'AUTOMAPPED'\n   ;\nSAMPLE\n   : 'SAMPLE'\n   ;\nPERCENT_P\n   : 'PERCENT'\n   ;\nSTAT\n   : 'STAT'\n   ;\nCOLLECT\n   : 'COLLECT'\n   ;\n\nMULTISET\n   : 'MULTISET'\n   ;\n\nMINUS_P\n   : 'MINUS'\n   ;\n\nGROUPCONCAT\n   : 'GROUP_CONCAT'\n   ;\n\nSEPARATOR\n   : 'SEPARATOR'\n   ;\n\nIGNORE\n   : 'IGNORE'\n   ;\nOPEN_BRACE\n   : '{'\n   ;\nCLOSE_BRACE\n   : '}'\n   ;\nOVERWRITE\n   : 'OVERWRITE'\n   ;\nDISTRIBUTE\n   : 'DISTRIBUTE'\n   ;\nDISTRIBUTED\n   : 'DISTRIBUTED'\n   ;\nDISTRIBUTION\n   : 'DISTRIBUTION'\n   ;\nREPLICATION\n   : 'REPLICATION'\n   ;\nROUNDROBIN\n   : 'ROUNDROBIN'\n   ;\nHASH\n   : 'HASH'\n   ;\nRANDOMLY\n   : 'RANDOMLY'\n   ;\nNODE_P\n   : 'NODE'\n   ;\n\nLIST_P\n   : 'LIST'\n   ;\n\nLESS\n   : 'LESS'\n   ;\n\nTHAN\n   : 'THAN'\n   ;\n\nEVERY\n   : 'EVERY'\n   ;\n\nMOVEMENT\n   : 'MOVEMENT'\n   ;\n\nTSTag\n   : 'TSTag'\n   ;\n\nTSTime\n   : 'TSTime'\n   ;\n\nTSField\n   : 'TSField'\n   ;\n\nREPLICATED\n   : 'REPLICATED'\n   ;\n\n// support gauss end --------------------------------\n\nCONFLICT\n   : 'CONFLICT'\n   ;\n\nSKIP_P\n   : 'SKIP'\n   ;\n\nLOCKED\n   : 'LOCKED'\n   ;\n\nTIES\n   : 'TIES'\n   ;\n\nROLLUP\n   : 'ROLLUP'\n   ;\n\nCUBE\n   : 'CUBE'\n   ;\n\nGROUPING\n   : 'GROUPING'\n   ;\n\nSETS\n   : 'SETS'\n   ;\n\nTABLESAMPLE\n   : 'TABLESAMPLE'\n   ;\n\nORDINALITY\n   : 'ORDINALITY'\n   ;\n\nXMLTABLE\n   : 'XMLTABLE'\n   ;\n\nCOLUMNS\n   : 'COLUMNS'\n   ;\n\nXMLNAMESPACES\n   : 'XMLNAMESPACES'\n   ;\n\nROWTYPE\n   : 'ROWTYPE'\n   ;\n\nNORMALIZED\n   : 'NORMALIZED'\n   ;\n\nWITHIN\n   : 'WITHIN'\n   ;\n\nFILTER\n   : 'FILTER'\n   ;\n\nGROUPS\n   : 'GROUPS'\n   ;\n\nOTHERS\n   : 'OTHERS'\n   ;\n\nNFC\n   : 'NFC'\n   ;\n\nNFD\n   : 'NFD'\n   ;\n\nNFKC\n   : 'NFKC'\n   ;\n\nNFKD\n   : 'NFKD'\n   ;\n\nUESCAPE\n   : 'UESCAPE'\n   ;\n\nVIEWS\n   : 'VIEWS'\n   ;\n\nNORMALIZE\n   : 'NORMALIZE'\n   ;\n\nDUMP\n   : 'DUMP'\n   ;\n\nPRINT_STRICT_PARAMS\n   : 'PRINT_STRICT_PARAMS'\n   ;\n\nVARIABLE_CONFLICT\n   : 'VARIABLE_CONFLICT'\n   ;\n\nERROR\n   : 'ERROR'\n   ;\n\nUSE_VARIABLE\n   : 'USE_VARIABLE'\n   ;\n\nUSE_COLUMN\n   : 'USE_COLUMN'\n   ;\n\nALIAS\n   : 'ALIAS'\n   ;\n\nCONSTANT\n   : 'CONSTANT'\n   ;\n\nPERFORM\n   : 'PERFORM'\n   ;\n\nGET\n   : 'GET'\n   ;\n\nDIAGNOSTICS\n   : 'DIAGNOSTICS'\n   ;\n\nSTACKED\n   : 'STACKED'\n   ;\n\nELSIF\n   : 'ELSIF'\n   ;\n\nWHILE\n   : 'WHILE'\n   ;\n\nREVERSE\n   : 'REVERSE'\n   ;\n\nFOREACH\n   : 'FOREACH'\n   ;\n\nSLICE\n   : 'SLICE'\n   ;\n\nEXIT\n   : 'EXIT'\n   ;\n\nRETURN\n   : 'RETURN'\n   ;\n\nQUERY\n   : 'QUERY'\n   ;\n\nRAISE\n   : 'RAISE'\n   ;\n\nSQLSTATE\n   : 'SQLSTATE'\n   ;\n\nDEBUG\n   : 'DEBUG'\n   ;\n\nLOG\n   : 'LOG'\n   ;\n\nINFO\n   : 'INFO'\n   ;\n\nNOTICE\n   : 'NOTICE'\n   ;\n\nWARNING\n   : 'WARNING'\n   ;\n\nEXCEPTION\n   : 'EXCEPTION'\n   ;\n\nASSERT\n   : 'ASSERT'\n   ;\n\nLOOP\n   : 'LOOP'\n   ;\n\nOPEN\n   : 'OPEN'\n   ;\n   //\n\n   // IDENTIFIERS (4.1.1)\n\n   //\n\nABS\n   : 'ABS'\n   ;\n\nCBRT\n   : 'CBRT'\n   ;\n\nCEIL\n   : 'CEIL'\n   ;\n\nCEILING\n   : 'CEILING'\n   ;\n\nDEGREES\n   : 'DEGREES'\n   ;\n\nDIV\n   : 'DIV'\n   ;\n\nEXP\n   : 'EXP'\n   ;\n\nFACTORIAL\n   : 'FACTORIAL'\n   ;\n\nFLOOR\n   : 'FLOOR'\n   ;\n\nGCD\n   : 'GCD'\n   ;\n\nLCM\n   : 'LCM'\n   ;\n\nLN\n   : 'LN'\n   ;\n\nLOG10\n   : 'LOG10'\n   ;\n\nMIN_SCALE\n   : 'MIN_SCALE'\n   ;\n\nMOD\n   : 'MOD'\n   ;\n\nPI\n   : 'PI'\n   ;\n\nPOWER\n   : 'POWER'\n   ;\n\nRADIANS\n   : 'RADIANS'\n   ;\n\nROUND\n   : 'ROUND'\n   ;\n\nSCALE\n   : 'SCALE'\n   ;\n\nSIGN\n   : 'SIGN'\n   ;\n\nSQRT\n   : 'SQRT'\n   ;\n\nTRIM_SCALE\n   : 'TRIM_SCALE'\n   ;\n\nTRUNC\n   : 'TRUNC'\n   ;\n\nWIDTH_BUCKET\n   : 'WIDTH_BUCKET'\n   ;\n\nRANDOM\n   : 'RANDOM'\n   ;\n\nSETSEED\n   : 'SETSEED'\n   ;\n\nACOS\n   : 'ACOS'\n   ;\n\nACOSD\n   : 'ACOSD'\n   ;\n\nASIN\n   : 'ASIN'\n   ;\n\nASIND\n   : 'ASIND'\n   ;\n\nATAN\n   : 'ATAN'\n   ;\n\nATAND\n   : 'ATAND'\n   ;\n\nATAN2\n   : 'ATAN2'\n   ;\n\nATAN2D\n   : 'ATAN2D'\n   ;\n\nCOS\n   : 'COS'\n   ;\n\nCOSD\n   : 'COSD'\n   ;\n\nCOT\n   : 'COT'\n   ;\n\nCOTD\n   : 'COTD'\n   ;\n\nSIN\n   : 'SIN'\n   ;\n\nSIND\n   : 'SIND'\n   ;\n\nTAN\n   : 'TAN'\n   ;\n\nTAND\n   : 'TAND'\n   ;\n\nSINH\n   : 'SINH'\n   ;\n\nCOSH\n   : 'COSH'\n   ;\n\nTANH\n   : 'TANH'\n   ;\n\nASINH\n   : 'ASINH'\n   ;\n\nACOSH\n   : 'ACOSH'\n   ;\n\nATANH\n   : 'ATANH'\n   ;\n\nBIT_LENGTH\n   : 'BIT_LENGTH'\n   ;\n\nCHAR_LENGTH\n   : 'CHAR_LENGTH'\n   ;\n\nCHARACTER_LENGTH\n   : 'CHARACTER_LENGTH'\n   ;\n\nLOWER\n   : 'LOWER'\n   ;\n\nOCTET_LENGTH\n   : 'OCTET_LENGTH'\n   ;\n\nUPPER\n   : 'UPPER'\n   ;\n\nASCII\n   : 'ASCII'\n   ;\n\nBTRIM\n   : 'BTRIM'\n   ;\n\nCHR\n   : 'CHR'\n   ;\n\nCONCAT\n   : 'CONCAT'\n   ;\n\nCONCAT_WS\n   : 'CONCAT_WS'\n   ;\n\nFORMAT\n   : 'FORMAT'\n   ;\n\nINITCAP\n   : 'INITCAP'\n   ;\n\nLENGTH\n   : 'LENGTH'\n   ;\n\nLPAD\n   : 'LPAD'\n   ;\n\nLTRIM\n   : 'LTRIM'\n   ;\n\nMD5\n   : 'MD5'\n   ;\n\nPARSE_IDENT\n   : 'PARSE_IDENT'\n   ;\n\nPG_CLIENT_ENCODING\n   : 'PG_CLIENT_ENCODING'\n   ;\n\nQUOTE_IDENT\n   : 'QUOTE_IDENT'\n   ;\n\nQUOTE_LITERAL\n   : 'QUOTE_LITERAL'\n   ;\n\nQUOTE_NULLABLE\n   : 'QUOTE_NULLABLE'\n   ;\n\nREGEXP_COUNT\n   : 'REGEXP_COUNT'\n   ;\n\nREGEXP_INSTR\n   : 'REGEXP_INSTR'\n   ;\n\nREGEXP_LIKE\n   : 'REGEXP_LIKE'\n   ;\n\nREGEXP_MATCH\n   : 'REGEXP_MATCH'\n   ;\n\nREGEXP_MATCHES\n   : 'REGEXP_MATCHES'\n   ;\n\nREGEXP_REPLACE\n   : 'REGEXP_REPLACE'\n   ;\n\nREGEXP_SPLIT_TO_ARRAY\n   : 'REGEXP_SPLIT_TO_ARRAY'\n   ;\n\nREGEXP_SPLIT_TO_TABLE\n   : 'REGEXP_SPLIT_TO_TABLE'\n   ;\n\nREGEXP_SUBSTR\n   : 'REGEXP_SUBSTR'\n   ;\n\nREPEAT\n   : 'REPEAT'\n   ;\n\nRPAD\n   : 'RPAD'\n   ;\n\nRTRIM\n   : 'RTRIM'\n   ;\n\nSPLIT_PART\n   : 'SPLIT_PART'\n   ;\n\nSTARTS_WITH\n   : 'STARTS_WITH'\n   ;\n\nSTRING_TO_ARRAY\n   : 'STRING_TO_ARRAY'\n   ;\n\nSTRING_TO_TABLE\n   : 'STRING_TO_TABLE'\n   ;\n\nSTRPOS\n   : 'STRPOS'\n   ;\n\nSUBSTR\n   : 'SUBSTR'\n   ;\n\nTO_ASCII\n   : 'TO_ASCII'\n   ;\n\nTO_HEX\n   : 'TO_HEX'\n   ;\n\nTRANSLATE\n   : 'TRANSLATE'\n   ;\n\nUNISTR\n   : 'UNISTR'\n   ;\n\nAGE\n   : 'AGE'\n   ;\n\nCLOCK_TIMESTAMP\n   : 'CLOCK_TIMESTAMP'\n   ;\n\nDATE_BIN\n   : 'DATE_BIN'\n   ;\n\nDATE_PART\n   : 'DATE_PART'\n   ;\n\nDATE_TRUNC\n   : 'DATE_TRUNC'\n   ;\n\nISFINITE\n   : 'ISFINITE'\n   ;\n\nJUSTIFY_DAYS\n   : 'JUSTIFY_DAYS'\n   ;\n\nJUSTIFY_HOURS\n   : 'JUSTIFY_HOURS'\n   ;\n\nJUSTIFY_INTERVAL\n   : 'JUSTIFY_INTERVAL'\n   ;\n\nMAKE_DATE\n   : 'MAKE_DATE'\n   ;\n\nMAKE_INTERVAL\n   : 'MAKE_INTERVAL'\n   ;\n\nMAKE_TIME\n   : 'MAKE_TIME'\n   ;\n\nMAKE_TIMESTAMP\n   : 'MAKE_TIMESTAMP'\n   ;\n\nMAKE_TIMESTAMPTZ\n   : 'MAKE_TIMESTAMPTZ'\n   ;\n\nNOW\n   : 'NOW'\n   ;\n\nSTATEMENT_TIMESTAMP\n   : 'STATEMENT_TIMESTAMP'\n   ;\n\nTIMEOFDAY\n   : 'TIMEOFDAY'\n   ;\n\nTRANSACTION_TIMESTAMP\n   : 'TRANSACTION_TIMESTAMP'\n   ;\n\nTO_TIMESTAMP\n   : 'TO_TIMESTAMP'\n   ;\n\nTO_CHAR\n   : 'TO_CHAR'\n   ;\n\nTO_DATE\n   : 'TO_DATE'\n   ;\n\nTO_NUMBER\n   : 'TO_NUMBER'\n   ;\n\nIdentifier\n   : IdentifierStartChar IdentifierChar*\n   ;\n\nfragment IdentifierStartChar\n   : // these are the valid identifier start characters below 0x7F\n   [a-zA-Z_]\n   | // these are the valid characters from 0x80 to 0xFF\n   [\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u00FF]\n   | // these are the letters above 0xFF which only need a single UTF-16 code unit\n   [\\u0100-\\uD7FF\\uE000-\\uFFFF]\n   {charIsLetter()}?\n   | // letters which require multiple UTF-16 code units\n   [\\uD800-\\uDBFF] [\\uDC00-\\uDFFF]\n   {\n    CheckIfUtf32Letter()\n   }?\n\n   ;\n\nfragment IdentifierChar\n   : StrictIdentifierChar\n   | '$'\n   ;\n\nfragment StrictIdentifierChar\n   : IdentifierStartChar\n   | [0-9]\n   ;\n/* Quoted Identifiers\n *\n *   These are divided into four separate tokens, allowing distinction of valid quoted identifiers from invalid quoted\n *   identifiers without sacrificing the ability of the lexer to reliably recover from lexical errors in the input.\n */\n\n\nQuotedIdentifier\n   : UnterminatedQuotedIdentifier '\"'\n   ;\n   // This is a quoted identifier which only contains valid characters but is not terminated\n\nUnterminatedQuotedIdentifier\n   : '\"' ('\"\"' | ~ [\\u0000\"])*\n   ;\n   // This is a quoted identifier which is terminated but contains a \\u0000 character\nInvalidQuotedIdentifier\n   : InvalidUnterminatedQuotedIdentifier '\"'\n   ;\n   // This is a quoted identifier which is unterminated and contains a \\u0000 character\nInvalidUnterminatedQuotedIdentifier\n   : '\"' ('\"\"' | ~ '\"')*\n   ;\n/* Unicode Quoted Identifiers\n *\n *   These are divided into four separate tokens, allowing distinction of valid Unicode quoted identifiers from invalid\n *   Unicode quoted identifiers without sacrificing the ability of the lexer to reliably recover from lexical errors in\n *   the input. Note that escape sequences are never checked as part of this determination due to the ability of users\n *   to change the escape character with a UESCAPE clause following the Unicode quoted identifier.\n *\n * TODO: these rules assume \"\" is still a valid escape sequence within a Unicode quoted identifier.\n */\nUnicodeQuotedIdentifier\n   : 'U' '&' QuotedIdentifier\n   ;\n   // This is a Unicode quoted identifier which only contains valid characters but is not terminated\nUnterminatedUnicodeQuotedIdentifier\n   : 'U' '&' UnterminatedQuotedIdentifier\n   ;\n   // This is a Unicode quoted identifier which is terminated but contains a \\u0000 character\nInvalidUnicodeQuotedIdentifier\n   : 'U' '&' InvalidQuotedIdentifier\n   ;\n   // This is a Unicode quoted identifier which is unterminated and contains a \\u0000 character\nInvalidUnterminatedUnicodeQuotedIdentifier\n   : 'U' '&' InvalidUnterminatedQuotedIdentifier\n   ;\n   //\n   // CONSTANTS (4.1.2)\n   //\n   // String Constants (4.1.2.1)\nStringConstant\n   : UnterminatedStringConstant '\\''\n   ;\n\nUnterminatedStringConstant\n   : '\\'' ('\\'\\'' | ~ '\\'')*\n   ;\n   // String Constants with C-style Escapes (4.1.2.2)\n\nBeginEscapeStringConstant\n   : 'E' '\\'' -> more , pushMode (EscapeStringConstantMode)\n   ;\n   // String Constants with Unicode Escapes (4.1.2.3)\n\n   //\n\n   //   Note that escape sequences are never checked as part of this token due to the ability of users to change the escape\n\n   //   character with a UESCAPE clause following the Unicode string constant.\n\n   //\n\n   // TODO: these rules assume '' is still a valid escape sequence within a Unicode string constant.\n\nUnicodeEscapeStringConstant\n   : UnterminatedUnicodeEscapeStringConstant '\\''\n   ;\n\nUnterminatedUnicodeEscapeStringConstant\n   : 'U' '&' UnterminatedStringConstant\n   ;\n   // Dollar-quoted String Constants (4.1.2.4)\n\nBeginDollarStringConstant\n   : '$' Tag? '$'\n   {pushTag();} -> pushMode (DollarQuotedStringMode)\n   ;\n/* \"The tag, if any, of a dollar-quoted string follows the same rules as an\n * unquoted identifier, except that it cannot contain a dollar sign.\"\n */\n\n\nfragment Tag\n   : IdentifierStartChar StrictIdentifierChar*\n   ;\n   // Bit-strings Constants (4.1.2.5)\n\nBinaryStringConstant\n   : UnterminatedBinaryStringConstant '\\''\n   ;\n\nUnterminatedBinaryStringConstant\n   : 'B' '\\'' [01]*\n   ;\n\nInvalidBinaryStringConstant\n   : InvalidUnterminatedBinaryStringConstant '\\''\n   ;\n\nInvalidUnterminatedBinaryStringConstant\n   : 'B' UnterminatedStringConstant\n   ;\n\nHexadecimalStringConstant\n   : UnterminatedHexadecimalStringConstant '\\''\n   ;\n\nUnterminatedHexadecimalStringConstant\n   : 'X' '\\'' [0-9A-F]*\n   ;\n\nInvalidHexadecimalStringConstant\n   : InvalidUnterminatedHexadecimalStringConstant '\\''\n   ;\n\nInvalidUnterminatedHexadecimalStringConstant\n   : 'X' UnterminatedStringConstant\n   ;\n   // Numeric Constants (4.1.2.6)\n\nIntegral\n   : Digits\n   ;\n\nNumericFail\n   : Digits '..'\n   {HandleNumericFail();}\n   ;\n\nNumeric\n   : Digits '.' Digits? /*? replaced with + to solve problem with DOT_DOT .. but this surely must be rewriten */\n\n   ('E' [+-]? Digits)?\n   | '.' Digits ('E' [+-]? Digits)?\n   | Digits 'E' [+-]? Digits\n   ;\n\nfragment Digits\n   : [0-9]+\n   ;\n\nPLSQLVARIABLENAME\n   : ':' [A-Z_] [A-Z_0-9$]*\n   ;\n\nPLSQLIDENTIFIER\n   : ':\"' ('\\\\' . | '\"\"' | ~ ('\"' | '\\\\'))* '\"'\n   ;\n   //\n\n   // WHITESPACE (4.1)\n\n   //\n\nWhitespace\n   : [ \\t]+ -> channel (HIDDEN)\n   ;\n\nNewline\n   : ('\\r' '\\n'? | '\\n') -> channel (HIDDEN)\n   ;\n   //\n\n   // COMMENTS (4.1.5)\n\n   //\n\nLineComment\n   : '--' ~ [\\r\\n]* -> channel (HIDDEN)\n   ;\n\nBlockComment\n   : ('/*' ('/'* BlockComment | ~ [/*] | '/'+ ~ [/*] | '*'+ ~ [/*])* '*'* '*/') -> channel (HIDDEN)\n   ;\nUnterminatedBlockComment\n   : '/*' ('/'* BlockComment | // these characters are not part of special sequences in a block comment\n   ~ [/*] | // handle / or * characters which are not part of /* or */ and do not appear at the end of the file\n   ('/'+ ~ [/*] | '*'+ ~ [/*]))*\n   // Handle the case of / or * characters at the end of the file, or a nested unterminated block comment\n   ('/'+ | '*'+ | '/'* UnterminatedBlockComment)?\n   // Optional assertion to make sure this rule is working as intended\n   {\n            UnterminatedBlockCommentDebugAssert();\n   }\n   ;\n   //\n   // META-COMMANDS\n   //\n   // http://www.postgresql.org/docs/9.3/static/app-psql.html\nMetaCommand\n   : '\\\\' (~ [\\r\\n\\\\\"] | '\"' ~ [\\r\\n\"]* '\"')* ('\"' ~ [\\r\\n\"]*)?\n   ;\nEndMetaCommand\n   : '\\\\\\\\'\n   ;\n   //\n   // ERROR\n   //\n   // Any character which does not match one of the above rules will appear in the token stream as an ErrorCharacter token.\n   // This ensures the lexer itself will never encounter a syntax error, so all error handling may be performed by the\n   // parser.\nErrorCharacter\n   : .\n   ;\nmode EscapeStringConstantMode;\nEscapeStringConstant\n   : EscapeStringText '\\'' -> mode (AfterEscapeStringConstantMode)\n   ;\nUnterminatedEscapeStringConstant\n   : EscapeStringText\n   // Handle a final unmatched \\ character appearing at the end of the file\n   '\\\\'? EOF\n   ;\nfragment EscapeStringText\n   : ('\\'\\'' | '\\\\' ( // two-digit hex escapes are still valid when treated as single-digit escapes\n   'x' [0-9a-fA-F] |\n   'u' [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] |\n   'U' [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] | // Any character other than the Unicode escapes can follow a backslash. Some have special meaning,\n   // but that doesn't affect the syntax.\n   ~ [xuU]) | ~ ['\\\\])*\n   ;\nInvalidEscapeStringConstant\n   : InvalidEscapeStringText '\\'' -> mode (AfterEscapeStringConstantMode)\n   ;\nInvalidUnterminatedEscapeStringConstant\n   : InvalidEscapeStringText\n   // Handle a final unmatched \\ character appearing at the end of the file\n   '\\\\'? EOF\n   ;\nfragment InvalidEscapeStringText\n   : ('\\'\\'' | '\\\\' . | ~ ['\\\\])*\n   ;\nmode AfterEscapeStringConstantMode;\nAfterEscapeStringConstantMode_Whitespace\n   : Whitespace -> type (Whitespace) , channel (HIDDEN)\n   ;\nAfterEscapeStringConstantMode_Newline\n   : Newline -> type (Newline) , channel (HIDDEN) , mode (AfterEscapeStringConstantWithNewlineMode)\n   ;\nAfterEscapeStringConstantMode_NotContinued\n   :\n   {} // intentionally empty\n   -> skip , popMode\n   ;\nmode AfterEscapeStringConstantWithNewlineMode;\nAfterEscapeStringConstantWithNewlineMode_Whitespace\n   : Whitespace -> type (Whitespace) , channel (HIDDEN)\n   ;\nAfterEscapeStringConstantWithNewlineMode_Newline\n   : Newline -> type (Newline) , channel (HIDDEN)\n   ;\nAfterEscapeStringConstantWithNewlineMode_Continued\n   : '\\'' -> more , mode (EscapeStringConstantMode)\n   ;\nAfterEscapeStringConstantWithNewlineMode_NotContinued\n   :\n   {} // intentionally empty\n   -> skip , popMode\n   ;\nmode DollarQuotedStringMode;\nDollarText\n   : ~ '$'+\n   //| '$'([0-9])+\n   | // this alternative improves the efficiency of handling $ characters within a dollar-quoted string which are\n   // not part of the ending tag.\n   '$' ~ '$'*\n   ;\nEndDollarStringConstant\n   : ('$' Tag? '$')\n   {isTag()}?\n   {popTag();} -> popMode\n   ;"
  },
  {
    "path": "superior-postgres-parser/src/main/antlr4/io/github/melin/superior/parser/postgre/antlr4/PostgreSqlParser.g4",
    "content": "parser grammar PostgreSqlParser;\n\n\noptions { tokenVocab = PostgreSqlLexer;\nsuperClass = PostgreSqlParserBase;\n}\n\n@header\n{\n}\n@members\n{\n}\nroot\n   : stmtblock EOF\n   ;\n\nplsqlroot\n   : pl_function\n   ;\n\nstmtblock\n   : stmtmulti\n   ;\n\nstmtmulti\n   : (stmt SEMI?)*\n   ;\n\nstmt\n   : altereventtrigstmt\n   | altercollationstmt\n   | alterdatabasestmt\n   | alterdatabasesetstmt\n   | alterdefaultprivilegesstmt\n   | alterdomainstmt\n   | alterenumstmt\n   | alterextensionstmt\n   | alterextensioncontentsstmt\n   | alterfdwstmt\n   | alterforeignserverstmt\n   | alterfunctionstmt\n   | altergroupstmt\n   | alterobjectdependsstmt\n   | alterobjectschemastmt\n   | alterownerstmt\n   | alteroperatorstmt\n   | altertypestmt\n   | alterpolicystmt\n   | alterseqstmt\n   | altersystemstmt\n   | altertablestmt\n   | altertblspcstmt\n   | altercompositetypestmt\n   | alterpublicationstmt\n   | alterrolesetstmt\n   | alterrolestmt\n   | altersubscriptionstmt\n   | alterstatsstmt\n   | altertsconfigurationstmt\n   | altertsdictionarystmt\n   | alterusermappingstmt\n   | analyzestmt\n   | callstmt\n   | checkpointstmt\n   | closeportalstmt\n   | clusterstmt\n   | commentstmt\n   | constraintssetstmt\n   | copystmt\n   | createamstmt\n   | createasstmt\n   | createassertionstmt\n   | createcaststmt\n   | createconversionstmt\n   | createdomainstmt\n   | createextensionstmt\n   | createfdwstmt\n   | createforeignserverstmt\n   | createforeigntablestmt\n   | createfunctionstmt\n   | creategroupstmt\n   | creatematviewstmt\n   | createopclassstmt\n   | createopfamilystmt\n   | createpublicationstmt\n   | alteropfamilystmt\n   | createpolicystmt\n   | createplangstmt\n   | createschemastmt\n   | createseqstmt\n   | createstmt\n   | createsubscriptionstmt\n   | createstatsstmt\n   | createtablespacestmt\n   | createtransformstmt\n   | createtrigstmt\n   | createeventtrigstmt\n   | createrolestmt\n   | createuserstmt\n   | createusermappingstmt\n   | createdbstmt\n   | deallocatestmt\n   | declarecursorstmt\n   | definestmt\n   | deletestmt\n   | discardstmt\n   | dostmt\n   | dropcaststmt\n   | dropopclassstmt\n   | dropopfamilystmt\n   | dropownedstmt\n   | dropstmt\n   | dropsubscriptionstmt\n   | droptablespacestmt\n   | droptransformstmt\n   | droprolestmt\n   | dropusermappingstmt\n   | dropdbstmt\n   | executestmt\n   | explainstmt\n   | fetchstmt\n   | grantstmt\n   | grantrolestmt\n   | importforeignschemastmt\n   | indexstmt\n   | insertstmt\n   | mergestmt\n   | listenstmt\n   | refreshmatviewstmt\n   | loadstmt\n   | lockstmt\n   | notifystmt\n   | preparestmt\n   | reassignownedstmt\n   | reindexstmt\n   | removeaggrstmt\n   | removefuncstmt\n   | removeoperstmt\n   | renamestmt\n   | revokerolestmt\n   | rulestmt\n   | seclabelstmt\n   | selectstmt\n   | transactionstmt\n   | truncatestmt\n   | unlistenstmt\n   | updatestmt\n   | vacuumstmt\n   | variableresetstmt\n   | variablesetstmt\n   | variableshowstmt\n   | viewstmt\n   | plsqlconsolecommand\n   ;\n\nplsqlconsolecommand\n   : MetaCommand EndMetaCommand?\n   ;\n\ncallstmt\n   : CALL func_application\n   ;\n\ncreaterolestmt\n   : CREATE ROLE roleid opt_with optrolelist\n   ;\n\nopt_with\n   : WITH\n   //| WITH_LA\n   |\n   ;\n\noptrolelist\n   : createoptroleelem*\n   ;\n\nalteroptrolelist\n   : alteroptroleelem*\n   ;\n\nalteroptroleelem\n   : PASSWORD (sconst | NULL_P)\n   | (ENCRYPTED | UNENCRYPTED) PASSWORD sconst\n   | INHERIT\n   | CONNECTION LIMIT signediconst\n   | VALID UNTIL sconst\n   | USER role_list\n   | identifier\n   ;\n\ncreateoptroleelem\n   : alteroptroleelem\n   | SYSID iconst\n   | ADMIN role_list\n   | ROLE role_list\n   | IN_P (ROLE | GROUP_P) role_list\n   ;\n\ncreateuserstmt\n   : CREATE USER roleid opt_with optrolelist\n   ;\n\nalterrolestmt\n   : ALTER (ROLE | USER) rolespec opt_with alteroptrolelist\n   ;\n\nopt_in_database\n   :\n   | IN_P DATABASE name\n   ;\n\nalterrolesetstmt\n   : ALTER (ROLE | USER) ALL? rolespec opt_in_database setresetclause\n   ;\n\ndroprolestmt\n   : DROP (ROLE | USER | GROUP_P) (IF_P EXISTS)? role_list\n   ;\n\ncreategroupstmt\n   : CREATE GROUP_P roleid opt_with optrolelist\n   ;\n\naltergroupstmt\n   : ALTER GROUP_P rolespec add_drop USER role_list\n   ;\n\nadd_drop\n   : ADD_P\n   | DROP\n   ;\n\ncreateschemastmt\n   : CREATE SCHEMA (IF_P NOT EXISTS)? (optschemaname AUTHORIZATION rolespec | colid) optschemaeltlist\n   ;\n\noptschemaname\n   : colid\n   |\n   ;\n\noptschemaeltlist\n   : schema_stmt*\n   ;\n\nschema_stmt\n   : createstmt\n   | indexstmt\n   | createseqstmt\n   | createtrigstmt\n   | grantstmt\n   | viewstmt\n   ;\n\nvariablesetstmt\n   : SET (LOCAL | SESSION)? set_rest\n   ;\n\nset_rest\n   : TRANSACTION transaction_mode_list\n   | SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list\n   | set_rest_more\n   ;\n\ngeneric_set\n   : var_name (TO | EQUAL) var_list\n   ;\n\nset_rest_more\n   : generic_set\n   | var_name FROM CURRENT_P\n   | TIME ZONE zone_value\n   | CATALOG sconst\n   | SCHEMA sconst\n   | NAMES opt_encoding\n   | ROLE nonreservedword_or_sconst\n   | SESSION AUTHORIZATION nonreservedword_or_sconst\n   | XML_P OPTION document_or_content\n   | TRANSACTION SNAPSHOT sconst\n   ;\n\nvar_name\n   : colid (DOT colid)*\n   ;\n\nvar_list\n   : var_value (COMMA var_value)*\n   ;\n\nvar_value\n   : opt_boolean_or_string\n   | numericonly\n   ;\n\niso_level\n   : READ (UNCOMMITTED | COMMITTED)\n   | REPEATABLE READ\n   | SERIALIZABLE\n   ;\n\nopt_boolean_or_string\n   : TRUE_P\n   | FALSE_P\n   | ON\n   | nonreservedword_or_sconst\n   ;\n\nzone_value\n   : sconst\n   | identifier\n   | constinterval sconst opt_interval\n   | constinterval OPEN_PAREN iconst CLOSE_PAREN sconst\n   | numericonly\n   | DEFAULT\n   | LOCAL\n   ;\n\nopt_encoding\n   : sconst\n   | DEFAULT\n   |\n   ;\n\nnonreservedword_or_sconst\n   : nonreservedword\n   | sconst\n   ;\n\nvariableresetstmt\n   : RESET reset_rest\n   ;\n\nreset_rest\n   : generic_reset\n   | TIME ZONE\n   | TRANSACTION ISOLATION LEVEL\n   | SESSION AUTHORIZATION\n   ;\n\ngeneric_reset\n   : var_name\n   | ALL\n   ;\n\nsetresetclause\n   : SET set_rest\n   | variableresetstmt\n   ;\n\nfunctionsetresetclause\n   : SET set_rest_more\n   | variableresetstmt\n   ;\n\nvariableshowstmt\n   : SHOW (var_name | TIME ZONE | TRANSACTION ISOLATION LEVEL | SESSION AUTHORIZATION | ALL)\n   ;\n\nconstraintssetstmt\n   : SET CONSTRAINTS constraints_set_list constraints_set_mode\n   ;\n\nconstraints_set_list\n   : ALL\n   | qualified_name_list\n   ;\n\nconstraints_set_mode\n   : DEFERRED\n   | IMMEDIATE\n   ;\n\ncheckpointstmt\n   : CHECKPOINT\n   ;\n\ndiscardstmt\n   : DISCARD (ALL | TEMP | TEMPORARY | PLANS | SEQUENCES)\n   ;\n\naltertablestmt\n   : ALTER TABLE (IF_P EXISTS)? relation_expr (alter_table_cmds | partition_cmd)\n   | ALTER TABLE ALL IN_P TABLESPACE name (OWNED BY role_list)? SET TABLESPACE name opt_nowait\n   | ALTER INDEX (IF_P EXISTS)? qualified_name (alter_table_cmds | index_partition_cmd)\n   | ALTER INDEX ALL IN_P TABLESPACE name (OWNED BY role_list)? SET TABLESPACE name opt_nowait\n   | ALTER SEQUENCE (IF_P EXISTS)? qualified_name alter_table_cmds\n   | ALTER VIEW (IF_P EXISTS)? qualified_name alter_table_cmds\n   | ALTER MATERIALIZED VIEW (IF_P EXISTS)? qualified_name alter_table_cmds\n   | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name (OWNED BY role_list)? SET TABLESPACE name opt_nowait\n   | ALTER FOREIGN TABLE (IF_P EXISTS)? relation_expr alter_table_cmds\n   ;\n\nalter_table_cmds\n   : alter_table_cmd (COMMA alter_table_cmd)*\n   ;\n\npartition_cmd\n   : ATTACH PARTITION qualified_name partitionboundspec\n   | DETACH PARTITION qualified_name\n   ;\n\nindex_partition_cmd\n   : ATTACH PARTITION qualified_name\n   ;\n\nalter_table_cmd\n   : ADD_P columnDef\n   | ADD_P IF_P NOT EXISTS columnDef\n   | ADD_P COLUMN columnDef\n   | ADD_P COLUMN IF_P NOT EXISTS columnDef\n   | ALTER opt_column colid alter_column_default\n   | ALTER opt_column colid DROP NOT NULL_P\n   | ALTER opt_column colid SET NOT NULL_P\n   | ALTER opt_column colid DROP EXPRESSION\n   | ALTER opt_column colid DROP EXPRESSION IF_P EXISTS\n   | ALTER opt_column colid SET STATISTICS signediconst\n   | ALTER opt_column iconst SET STATISTICS signediconst\n   | ALTER opt_column colid SET reloptions\n   | ALTER opt_column colid RESET reloptions\n   | ALTER opt_column colid SET STORAGE colid\n   | ALTER opt_column colid ADD_P GENERATED generated_when AS IDENTITY_P optparenthesizedseqoptlist\n   | ALTER opt_column colid alter_identity_column_option_list\n   | ALTER opt_column colid DROP IDENTITY_P\n   | ALTER opt_column colid DROP IDENTITY_P IF_P EXISTS\n   | DROP opt_column IF_P EXISTS colid opt_drop_behavior\n   | DROP opt_column colid opt_drop_behavior\n   | ALTER opt_column colid opt_set_data TYPE_P typename opt_collate_clause alter_using\n   | ALTER opt_column colid alter_generic_options\n   | ADD_P tableconstraint\n   | ALTER CONSTRAINT name constraintattributespec\n   | VALIDATE CONSTRAINT name\n   | DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior\n   | DROP CONSTRAINT name opt_drop_behavior\n   | SET WITHOUT OIDS\n   | CLUSTER ON name\n   | SET WITHOUT CLUSTER\n   | SET LOGGED\n   | SET UNLOGGED\n   | ENABLE_P TRIGGER name\n   | ENABLE_P ALWAYS TRIGGER name\n   | ENABLE_P REPLICA TRIGGER name\n   | ENABLE_P TRIGGER ALL\n   | ENABLE_P TRIGGER USER\n   | DISABLE_P TRIGGER name\n   | DISABLE_P TRIGGER ALL\n   | DISABLE_P TRIGGER USER\n   | ENABLE_P RULE name\n   | ENABLE_P ALWAYS RULE name\n   | ENABLE_P REPLICA RULE name\n   | DISABLE_P RULE name\n   | INHERIT qualified_name\n   | NO INHERIT qualified_name\n   | OF any_name\n   | NOT OF\n   | OWNER TO rolespec\n   | SET TABLESPACE name\n   | SET reloptions\n   | RESET reloptions\n   | REPLICA IDENTITY_P replica_identity\n   | ENABLE_P ROW LEVEL SECURITY\n   | DISABLE_P ROW LEVEL SECURITY\n   | FORCE ROW LEVEL SECURITY\n   | NO FORCE ROW LEVEL SECURITY\n   | alter_generic_options\n   ;\n\nalter_column_default\n   : SET DEFAULT a_expr\n   | DROP DEFAULT\n   ;\n\nopt_drop_behavior\n   : CASCADE\n   | RESTRICT\n   |\n   ;\n\nopt_collate_clause\n   : COLLATE any_name\n   |\n   ;\n\nalter_using\n   : USING a_expr\n   |\n   ;\n\nreplica_identity\n   : NOTHING\n   | FULL\n   | DEFAULT\n   | USING INDEX name\n   ;\n\nreloptions\n   : OPEN_PAREN reloption_list CLOSE_PAREN\n   ;\n\nopt_reloptions\n   : WITH reloptions\n   |\n   ;\n\nreloption_list\n   : reloption_elem (COMMA reloption_elem)*\n   ;\n\nreloption_elem\n   : collabel (EQUAL def_arg | DOT collabel (EQUAL def_arg)?)?\n   ;\n\nalter_identity_column_option_list\n   : alter_identity_column_option+\n   ;\n\nalter_identity_column_option\n   : RESTART (opt_with numericonly)?\n   | SET (seqoptelem | GENERATED generated_when)\n   ;\n\npartitionboundspec\n   : FOR VALUES WITH OPEN_PAREN hash_partbound CLOSE_PAREN\n   | FOR VALUES IN_P OPEN_PAREN expr_list CLOSE_PAREN\n   | FOR VALUES FROM OPEN_PAREN expr_list CLOSE_PAREN TO OPEN_PAREN expr_list CLOSE_PAREN\n   | DEFAULT\n   ;\n\nhash_partbound_elem\n   : nonreservedword iconst\n   ;\n\nhash_partbound\n   : hash_partbound_elem (COMMA hash_partbound_elem)*\n   ;\n\naltercompositetypestmt\n   : ALTER TYPE_P any_name alter_type_cmds\n   ;\n\nalter_type_cmds\n   : alter_type_cmd (COMMA alter_type_cmd)*\n   ;\n\nalter_type_cmd\n   : ADD_P ATTRIBUTE tablefuncelement opt_drop_behavior\n   | DROP ATTRIBUTE (IF_P EXISTS)? colid opt_drop_behavior\n   | ALTER ATTRIBUTE colid opt_set_data TYPE_P typename opt_collate_clause opt_drop_behavior\n   ;\n\ncloseportalstmt\n   : CLOSE (cursor_name | ALL)\n   ;\n\ncopystmt\n   : COPY opt_binary qualified_name opt_column_list copy_from opt_program copy_file_name copy_delimiter opt_with copy_options where_clause\n   | COPY OPEN_PAREN preparablestmt CLOSE_PAREN TO opt_program copy_file_name opt_with copy_options\n   ;\n\ncopy_from\n   : FROM\n   | TO\n   ;\n\nopt_program\n   : PROGRAM\n   |\n   ;\n\ncopy_file_name\n   : sconst\n   | STDIN\n   | STDOUT\n   ;\n\ncopy_options\n   : copy_opt_list\n   | OPEN_PAREN copy_generic_opt_list CLOSE_PAREN\n   ;\n\ncopy_opt_list\n   : copy_opt_item*\n   ;\n\ncopy_opt_item\n   : BINARY\n   | FREEZE\n   | DELIMITER opt_as sconst\n   | NULL_P opt_as sconst\n   | CSV\n   | HEADER_P\n   | QUOTE opt_as sconst\n   | ESCAPE opt_as sconst\n   | FORCE QUOTE columnlist\n   | FORCE QUOTE STAR\n   | FORCE NOT NULL_P columnlist\n   | FORCE NULL_P columnlist\n   | ENCODING sconst\n   ;\n\nopt_binary\n   : BINARY\n   |\n   ;\n\ncopy_delimiter\n   : opt_using DELIMITERS sconst\n   |\n   ;\n\nopt_using\n   : USING\n   |\n   ;\n\ncopy_generic_opt_list\n   : copy_generic_opt_elem (COMMA copy_generic_opt_elem)*\n   ;\n\ncopy_generic_opt_elem\n   : collabel copy_generic_opt_arg\n   ;\n\ncopy_generic_opt_arg\n   : opt_boolean_or_string\n   | numericonly\n   | STAR\n   | OPEN_PAREN copy_generic_opt_arg_list CLOSE_PAREN\n   |\n   ;\n\ncopy_generic_opt_arg_list\n   : copy_generic_opt_arg_list_item (COMMA copy_generic_opt_arg_list_item)*\n   ;\n\ncopy_generic_opt_arg_list_item\n   : opt_boolean_or_string\n   ;\n\ncreatestmt\n   : CREATE opttemp TABLE (IF_P NOT EXISTS)? qualified_name\n   (\n        OPEN_PAREN opttableelementlist CLOSE_PAREN optinherit optpartitionspec table_access_method_clause gaussprimayindex optwith oncommitoption opttablespace gaussextension\n        | OF any_name opttypedtableelementlist optpartitionspec table_access_method_clause optwith oncommitoption opttablespace\n        | PARTITION OF qualified_name opttypedtableelementlist partitionboundspec optpartitionspec table_access_method_clause optwith oncommitoption opttablespace\n   )\n   ;\n\n// -------- support gauss\n\ngaussprimayindex\n   : PRIMARY INDEX OPEN_PAREN colid CLOSE_PAREN\n   |\n   ;\n\ngaussextension\n   : distributeby toGroupOrNode tablePartition?\n   |\n   ;\n\ndistributeby\n   : DISTRIBUTE BY (REPLICATION | ROUNDROBIN | HASH OPEN_PAREN distributebyhashlist CLOSE_PAREN)\n   | DISTRIBUTED BY OPEN_PAREN distributebyhashlist CLOSE_PAREN\n   | DISTRIBUTED (RANDOMLY | REPLICATED)\n   |\n   ;\n\ndistributebyhashlist\n   : distributebyhashitem (COMMA distributebyhashitem)*\n   ;\n\ndistributebyhashitem\n   : collabel\n   ;\n\ntoGroupOrNode\n   : TO GROUP_P collabel\n   | TO NODE_P OPEN_PAREN collabel (COMMA collabel)* CLOSE_PAREN\n   |\n   ;\n\n tablePartition\n   : PARTITION BY partition_list ((ENABLE_P | DISABLE_P) ROW MOVEMENT)?\n   ;\n\n partition_list\n   : value_partition_stmt\n   | range_partition_stmt\n   | list_partition_stmt\n   | normal_partition_stmt\n   ;\n\nnormal_partition_stmt\n   : OPEN_PAREN list_partition_value CLOSE_PAREN AUTOMAPPED?\n   ;\n\nlist_partition_stmt\n   : LIST_P OPEN_PAREN partition_key CLOSE_PAREN OPEN_PAREN list_partition_items CLOSE_PAREN\n   ;\n\nlist_partition_items\n   : list_partition_item (COMMA list_partition_item)*\n   ;\n\nlist_partition_item\n   : PARTITION partition_name VALUES LESS THAN OPEN_PAREN list_partition_value CLOSE_PAREN table_space_item?\n   ;\n\nlist_partition_value\n   : partition_name (COMMA partition_name)*\n   | DEFAULT\n   ;\n\nvalue_partition_stmt\n   : VALUES OPEN_PAREN partition_key CLOSE_PAREN\n   ;\n\nrange_partition_stmt\n   : RANGE OPEN_PAREN partition_key CLOSE_PAREN OPEN_PAREN (partition_less_than_items | partition_start_end_items) CLOSE_PAREN\n   ;\n\npartition_less_than_items\n   : partition_less_than_item (COMMA partition_less_than_item)*\n   ;\n\npartition_start_end_items\n   : partition_start_end_item (COMMA partition_start_end_item)*\n   ;\n\npartition_less_than_item\n   : PARTITION partition_name VALUES LESS THAN OPEN_PAREN (partition_value | MAXVALUE) CLOSE_PAREN table_space_item?\n   ;\n\npartition_start_end_item\n   : PARTITION partition_name start_end_item table_space_item?\n   ;\n\nstart_end_item\n   : start_item\n   | end_item\n   | start_item end_item (EVERY OPEN_PAREN aexprconst CLOSE_PAREN)?\n   ;\n\nstart_item\n   : START OPEN_PAREN partition_value CLOSE_PAREN\n   ;\n\nend_item\n   : END_P OPEN_PAREN (partition_value | MAXVALUE) CLOSE_PAREN\n   ;\n\npartition_key\n   : colid\n   ;\n\npartition_name\n   : colid\n   ;\n\npartition_value\n   : a_expr\n   ;\n\ntable_space_item\n   : TABLESPACE table_space_name\n   ;\n\ntable_space_name\n   : qualified_name\n   ;\n\n// -------- support gauss\n\nopttemp\n   : TEMPORARY\n   | TEMP\n   | LOCAL (TEMPORARY | TEMP)\n   | GLOBAL (TEMPORARY | TEMP)\n   | UNLOGGED\n   |\n   ;\n\nopttableelementlist\n   : tableelementlist\n   |\n   ;\n\nopttypedtableelementlist\n   : OPEN_PAREN typedtableelementlist CLOSE_PAREN\n   |\n   ;\n\ntableelementlist\n   : tableelement (COMMA tableelement)*\n   ;\n\ntypedtableelementlist\n   : typedtableelement (COMMA typedtableelement)*\n   ;\n\ntableelement\n   : tableconstraint\n   | tablelikeclause\n   | columnDef\n   ;\n\ntypedtableelement\n   : columnOptions\n   | tableconstraint\n   ;\n\ncolumnDef\n   : colid typename create_generic_options colquallist\n   ;\n\ncolumnOptions\n   : colid (WITH OPTIONS)? colquallist\n   ;\n\ncolquallist\n   : colconstraint*\n   ;\n\ncolconstraint\n   : CONSTRAINT name colconstraintelem\n   | colconstraintelem\n   | constraintattr\n   | COLLATE any_name\n   ;\n\ncolconstraintelem\n   : NOT NULL_P\n   | NULL_P\n   | UNIQUE opt_definition optconstablespace\n   | PRIMARY KEY opt_definition optconstablespace\n   | CHECK OPEN_PAREN a_expr CLOSE_PAREN opt_no_inherit\n   | DEFAULT b_expr\n   | GENERATED generated_when AS (IDENTITY_P optparenthesizedseqoptlist | OPEN_PAREN a_expr CLOSE_PAREN STORED)\n   | REFERENCES qualified_name opt_column_list key_match key_actions\n   ;\n\ngenerated_when\n   : ALWAYS\n   | BY DEFAULT\n   ;\n\nconstraintattr\n   : DEFERRABLE\n   | NOT DEFERRABLE\n   | INITIALLY (DEFERRED | IMMEDIATE)\n   ;\n\ntablelikeclause\n   : LIKE qualified_name tablelikeoptionlist\n   ;\n\ntablelikeoptionlist\n   : ((INCLUDING | EXCLUDING) tablelikeoption)*\n   ;\n\ntablelikeoption\n   : COMMENTS\n   | CONSTRAINTS\n   | DEFAULTS\n   | IDENTITY_P\n   | GENERATED\n   | INDEXES\n   | STATISTICS\n   | STORAGE\n   | ALL\n   ;\n\ntableconstraint\n   : CONSTRAINT name constraintelem\n   | constraintelem\n   ;\n\nconstraintelem\n   : CHECK OPEN_PAREN a_expr CLOSE_PAREN constraintattributespec\n   | UNIQUE (OPEN_PAREN columnlist CLOSE_PAREN opt_c_include opt_definition optconstablespace constraintattributespec | existingindex constraintattributespec)\n   | PRIMARY KEY (OPEN_PAREN columnlist CLOSE_PAREN opt_c_include opt_definition optconstablespace constraintattributespec | existingindex constraintattributespec)\n   | EXCLUDE access_method_clause OPEN_PAREN exclusionconstraintlist CLOSE_PAREN opt_c_include opt_definition optconstablespace exclusionwhereclause constraintattributespec\n   | FOREIGN KEY OPEN_PAREN columnlist CLOSE_PAREN REFERENCES qualified_name opt_column_list key_match key_actions constraintattributespec\n   ;\n\nopt_no_inherit\n   : NO INHERIT\n   |\n   ;\n\nopt_column_list\n   : OPEN_PAREN columnlist CLOSE_PAREN\n   |\n   ;\n\ncolumnlist\n   : columnElem (COMMA columnElem)*\n   ;\n\ncolumnElem\n   : colid\n   ;\n\nopt_c_include\n   : INCLUDE OPEN_PAREN columnlist CLOSE_PAREN\n   |\n   ;\n\nkey_match\n   : MATCH (FULL | PARTIAL | SIMPLE)\n   |\n   ;\n\nexclusionconstraintlist\n   : exclusionconstraintelem (COMMA exclusionconstraintelem)*\n   ;\n\nexclusionconstraintelem\n   : index_elem WITH (any_operator | OPERATOR OPEN_PAREN any_operator CLOSE_PAREN)\n   ;\n\nexclusionwhereclause\n   : WHERE OPEN_PAREN a_expr CLOSE_PAREN\n   |\n   ;\n\nkey_actions\n   : key_update\n   | key_delete\n   | key_update key_delete\n   | key_delete key_update\n   |\n   ;\n\nkey_update\n   : ON UPDATE key_action\n   ;\n\nkey_delete\n   : ON DELETE_P key_action\n   ;\n\nkey_action\n   : NO ACTION\n   | RESTRICT\n   | CASCADE\n   | SET (NULL_P | DEFAULT)\n   ;\n\noptinherit\n   : INHERITS OPEN_PAREN qualified_name_list CLOSE_PAREN\n   |\n   ;\n\noptpartitionspec\n   : partitionspec\n   |\n   ;\n\npartitionspec\n   : PARTITION BY colid OPEN_PAREN part_params CLOSE_PAREN\n   ;\n\npart_params\n   : part_elem (COMMA part_elem)*\n   ;\n\npart_elem\n   : colid opt_collate opt_class\n   | func_expr_windowless opt_collate opt_class\n   | OPEN_PAREN a_expr CLOSE_PAREN opt_collate opt_class\n   ;\n\ntable_access_method_clause\n   : USING name\n   |\n   ;\n\noptwith\n   : WITH reloptions\n   | WITHOUT OIDS\n   |\n   ;\n\noncommitoption\n   : ON COMMIT (DROP | DELETE_P ROWS | PRESERVE ROWS)\n   |\n   ;\n\nopttablespace\n   : TABLESPACE name\n   |\n   ;\n\noptconstablespace\n   : USING INDEX TABLESPACE name\n   |\n   ;\n\nexistingindex\n   : USING INDEX name\n   ;\n\ncreatestatsstmt\n   : CREATE STATISTICS (IF_P NOT EXISTS)? any_name opt_name_list ON expr_list FROM from_list\n   ;\n\nalterstatsstmt\n   : ALTER STATISTICS (IF_P EXISTS)? any_name SET STATISTICS signediconst\n   ;\n\ncreateasstmt\n   : CREATE opttemp TABLE (IF_P NOT EXISTS)? create_as_target AS selectstmt opt_with_data\n   ;\n\ncreate_as_target\n   : qualified_name opt_column_list table_access_method_clause optwith oncommitoption opttablespace gaussextension\n   ;\n\nopt_with_data\n   : WITH (DATA_P | NO DATA_P)\n   |\n   ;\n\ncreatematviewstmt\n   : CREATE optnolog MATERIALIZED VIEW (IF_P NOT EXISTS)? create_mv_target AS selectstmt opt_with_data\n   ;\n\ncreate_mv_target\n   : qualified_name opt_column_list table_access_method_clause opt_reloptions opttablespace\n   ;\n\noptnolog\n   : UNLOGGED\n   |\n   ;\n\nrefreshmatviewstmt\n   : REFRESH MATERIALIZED VIEW opt_concurrently qualified_name opt_with_data\n   ;\n\ncreateseqstmt\n   : CREATE opttemp SEQUENCE (IF_P NOT EXISTS)? qualified_name optseqoptlist\n   ;\n\nalterseqstmt\n   : ALTER SEQUENCE (IF_P EXISTS)? qualified_name seqoptlist\n   ;\n\noptseqoptlist\n   : seqoptlist\n   |\n   ;\n\noptparenthesizedseqoptlist\n   : OPEN_PAREN seqoptlist CLOSE_PAREN\n   |\n   ;\n\nseqoptlist\n   : seqoptelem+\n   ;\n\nseqoptelem\n   : AS simpletypename\n   | CACHE numericonly\n   | CYCLE\n   | INCREMENT opt_by numericonly\n   | MAXVALUE numericonly\n   | MINVALUE numericonly\n   | NO (MAXVALUE | MINVALUE | CYCLE)\n   | OWNED BY any_name\n   | SEQUENCE NAME_P any_name\n   | START opt_with numericonly\n   | RESTART opt_with numericonly?\n   ;\n\nopt_by\n   : BY\n   |\n   ;\n\nnumericonly\n   : fconst\n   | PLUS fconst\n   | MINUS fconst\n   | signediconst\n   ;\n\nnumericonly_list\n   : numericonly (COMMA numericonly)*\n   ;\n\ncreateplangstmt\n   : CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE name (HANDLER handler_name opt_inline_handler opt_validator)?\n   ;\n\nopt_trusted\n   : TRUSTED\n   |\n   ;\n\nhandler_name\n   : name attrs?\n   ;\n\nopt_inline_handler\n   : INLINE_P handler_name\n   |\n   ;\n\nvalidator_clause\n   : VALIDATOR handler_name\n   | NO VALIDATOR\n   ;\n\nopt_validator\n   : validator_clause\n   |\n   ;\n\nopt_procedural\n   : PROCEDURAL\n   |\n   ;\n\ncreatetablespacestmt\n   : CREATE TABLESPACE name opttablespaceowner LOCATION sconst opt_reloptions\n   ;\n\nopttablespaceowner\n   : OWNER rolespec\n   |\n   ;\n\ndroptablespacestmt\n   : DROP TABLESPACE (IF_P EXISTS)? name\n   ;\n\ncreateextensionstmt\n   : CREATE EXTENSION (IF_P NOT EXISTS)? name opt_with create_extension_opt_list\n   ;\n\ncreate_extension_opt_list\n   : create_extension_opt_item*\n   ;\n\ncreate_extension_opt_item\n   : SCHEMA name\n   | VERSION_P nonreservedword_or_sconst\n   | FROM nonreservedword_or_sconst\n   | CASCADE\n   ;\n\nalterextensionstmt\n   : ALTER EXTENSION name UPDATE alter_extension_opt_list\n   ;\n\nalter_extension_opt_list\n   : alter_extension_opt_item*\n   ;\n\nalter_extension_opt_item\n   : TO nonreservedword_or_sconst\n   ;\n\nalterextensioncontentsstmt\n   : ALTER EXTENSION name add_drop object_type_name name\n   | ALTER EXTENSION name add_drop object_type_any_name any_name\n   | ALTER EXTENSION name add_drop AGGREGATE aggregate_with_argtypes\n   | ALTER EXTENSION name add_drop CAST OPEN_PAREN typename AS typename CLOSE_PAREN\n   | ALTER EXTENSION name add_drop DOMAIN_P typename\n   | ALTER EXTENSION name add_drop FUNCTION function_with_argtypes\n   | ALTER EXTENSION name add_drop OPERATOR operator_with_argtypes\n   | ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING name\n   | ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING name\n   | ALTER EXTENSION name add_drop PROCEDURE function_with_argtypes\n   | ALTER EXTENSION name add_drop ROUTINE function_with_argtypes\n   | ALTER EXTENSION name add_drop TRANSFORM FOR typename LANGUAGE name\n   | ALTER EXTENSION name add_drop TYPE_P typename\n   ;\n\ncreatefdwstmt\n   : CREATE FOREIGN DATA_P WRAPPER name opt_fdw_options create_generic_options\n   ;\n\nfdw_option\n   : HANDLER handler_name\n   | NO HANDLER\n   | VALIDATOR handler_name\n   | NO VALIDATOR\n   ;\n\nfdw_options\n   : fdw_option+\n   ;\n\nopt_fdw_options\n   : fdw_options\n   |\n   ;\n\nalterfdwstmt\n   : ALTER FOREIGN DATA_P WRAPPER name opt_fdw_options alter_generic_options\n   | ALTER FOREIGN DATA_P WRAPPER name fdw_options\n   ;\n\ncreate_generic_options\n   : OPTIONS OPEN_PAREN generic_option_list CLOSE_PAREN\n   |\n   ;\n\ngeneric_option_list\n   : generic_option_elem (COMMA generic_option_elem)*\n   ;\n\nalter_generic_options\n   : OPTIONS OPEN_PAREN alter_generic_option_list CLOSE_PAREN\n   ;\n\nalter_generic_option_list\n   : alter_generic_option_elem (COMMA alter_generic_option_elem)*\n   ;\n\nalter_generic_option_elem\n   : generic_option_elem\n   | SET generic_option_elem\n   | ADD_P generic_option_elem\n   | DROP generic_option_name\n   ;\n\ngeneric_option_elem\n   : generic_option_name generic_option_arg\n   ;\n\ngeneric_option_name\n   : collabel\n   ;\n\ngeneric_option_arg\n   : sconst\n   ;\n\ncreateforeignserverstmt\n   : CREATE SERVER name opt_type opt_foreign_server_version FOREIGN DATA_P WRAPPER name create_generic_options\n   | CREATE SERVER IF_P NOT EXISTS name opt_type opt_foreign_server_version FOREIGN DATA_P WRAPPER name create_generic_options\n   ;\n\nopt_type\n   : TYPE_P sconst\n   |\n   ;\n\nforeign_server_version\n   : VERSION_P (sconst | NULL_P)\n   ;\n\nopt_foreign_server_version\n   : foreign_server_version\n   |\n   ;\n\nalterforeignserverstmt\n   : ALTER SERVER name (alter_generic_options | foreign_server_version alter_generic_options?)\n   ;\n\ncreateforeigntablestmt\n   : CREATE FOREIGN TABLE qualified_name OPEN_PAREN opttableelementlist CLOSE_PAREN optinherit SERVER name create_generic_options\n   | CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name OPEN_PAREN opttableelementlist CLOSE_PAREN optinherit SERVER name create_generic_options\n   | CREATE FOREIGN TABLE qualified_name PARTITION OF qualified_name opttypedtableelementlist partitionboundspec SERVER name create_generic_options\n   | CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name PARTITION OF qualified_name opttypedtableelementlist partitionboundspec SERVER name create_generic_options\n   ;\n\nimportforeignschemastmt\n   : IMPORT_P FOREIGN SCHEMA name import_qualification FROM SERVER name INTO name create_generic_options\n   ;\n\nimport_qualification_type\n   : LIMIT TO\n   | EXCEPT\n   ;\n\nimport_qualification\n   : import_qualification_type OPEN_PAREN relation_expr_list CLOSE_PAREN\n   |\n   ;\n\ncreateusermappingstmt\n   : CREATE USER MAPPING FOR auth_ident SERVER name create_generic_options\n   | CREATE USER MAPPING IF_P NOT EXISTS FOR auth_ident SERVER name create_generic_options\n   ;\n\nauth_ident\n   : rolespec\n   | USER\n   ;\n\ndropusermappingstmt\n   : DROP USER MAPPING FOR auth_ident SERVER name\n   | DROP USER MAPPING IF_P EXISTS FOR auth_ident SERVER name\n   ;\n\nalterusermappingstmt\n   : ALTER USER MAPPING FOR auth_ident SERVER name alter_generic_options\n   ;\n\ncreatepolicystmt\n   : CREATE POLICY name ON qualified_name rowsecuritydefaultpermissive rowsecuritydefaultforcmd rowsecuritydefaulttorole rowsecurityoptionalexpr rowsecurityoptionalwithcheck\n   ;\n\nalterpolicystmt\n   : ALTER POLICY name ON qualified_name rowsecurityoptionaltorole rowsecurityoptionalexpr rowsecurityoptionalwithcheck\n   ;\n\nrowsecurityoptionalexpr\n   : USING OPEN_PAREN a_expr CLOSE_PAREN\n   |\n   ;\n\nrowsecurityoptionalwithcheck\n   : WITH CHECK OPEN_PAREN a_expr CLOSE_PAREN\n   |\n   ;\n\nrowsecuritydefaulttorole\n   : TO role_list\n   |\n   ;\n\nrowsecurityoptionaltorole\n   : TO role_list\n   |\n   ;\n\nrowsecuritydefaultpermissive\n   : AS identifier\n   |\n   ;\n\nrowsecuritydefaultforcmd\n   : FOR row_security_cmd\n   |\n   ;\n\nrow_security_cmd\n   : ALL\n   | SELECT\n   | INSERT\n   | UPDATE\n   | DELETE_P\n   ;\n\ncreateamstmt\n   : CREATE ACCESS METHOD name TYPE_P am_type HANDLER handler_name\n   ;\n\nam_type\n   : INDEX\n   | TABLE\n   ;\n\ncreatetrigstmt\n   : CREATE TRIGGER name triggeractiontime triggerevents ON qualified_name triggerreferencing triggerforspec triggerwhen EXECUTE function_or_procedure func_name OPEN_PAREN triggerfuncargs CLOSE_PAREN\n   | CREATE CONSTRAINT TRIGGER name AFTER triggerevents ON qualified_name optconstrfromtable constraintattributespec FOR EACH ROW triggerwhen EXECUTE function_or_procedure func_name OPEN_PAREN triggerfuncargs CLOSE_PAREN\n   ;\n\ntriggeractiontime\n   : BEFORE\n   | AFTER\n   | INSTEAD OF\n   ;\n\ntriggerevents\n   : triggeroneevent (OR triggeroneevent)*\n   ;\n\ntriggeroneevent\n   : INSERT\n   | DELETE_P\n   | UPDATE\n   | UPDATE OF columnlist\n   | TRUNCATE\n   ;\n\ntriggerreferencing\n   : REFERENCING triggertransitions\n   |\n   ;\n\ntriggertransitions\n   : triggertransition+\n   ;\n\ntriggertransition\n   : transitionoldornew transitionrowortable opt_as transitionrelname\n   ;\n\ntransitionoldornew\n   : NEW\n   | OLD\n   ;\n\ntransitionrowortable\n   : TABLE\n   | ROW\n   ;\n\ntransitionrelname\n   : colid\n   ;\n\ntriggerforspec\n   : FOR triggerforopteach triggerfortype\n   |\n   ;\n\ntriggerforopteach\n   : EACH\n   |\n   ;\n\ntriggerfortype\n   : ROW\n   | STATEMENT\n   ;\n\ntriggerwhen\n   : WHEN OPEN_PAREN a_expr CLOSE_PAREN\n   |\n   ;\n\nfunction_or_procedure\n   : FUNCTION\n   | PROCEDURE\n   ;\n\ntriggerfuncargs\n   : (triggerfuncarg |) (COMMA triggerfuncarg)*\n   ;\n\ntriggerfuncarg\n   : iconst\n   | fconst\n   | sconst\n   | collabel\n   ;\n\noptconstrfromtable\n   : FROM qualified_name\n   |\n   ;\n\nconstraintattributespec\n   : constraintattributeElem*\n   ;\n\nconstraintattributeElem\n   : NOT DEFERRABLE\n   | DEFERRABLE\n   | INITIALLY IMMEDIATE\n   | INITIALLY DEFERRED\n   | NOT VALID\n   | NO INHERIT\n   ;\n\ncreateeventtrigstmt\n   : CREATE EVENT TRIGGER name ON collabel EXECUTE function_or_procedure func_name OPEN_PAREN CLOSE_PAREN\n   | CREATE EVENT TRIGGER name ON collabel WHEN event_trigger_when_list EXECUTE function_or_procedure func_name OPEN_PAREN CLOSE_PAREN\n   ;\n\nevent_trigger_when_list\n   : event_trigger_when_item (AND event_trigger_when_item)*\n   ;\n\nevent_trigger_when_item\n   : colid IN_P OPEN_PAREN event_trigger_value_list CLOSE_PAREN\n   ;\n\nevent_trigger_value_list\n   : sconst (COMMA sconst)*\n   ;\n\naltereventtrigstmt\n   : ALTER EVENT TRIGGER name enable_trigger\n   ;\n\nenable_trigger\n   : ENABLE_P\n   | ENABLE_P REPLICA\n   | ENABLE_P ALWAYS\n   | DISABLE_P\n   ;\n\ncreateassertionstmt\n   : CREATE ASSERTION any_name CHECK OPEN_PAREN a_expr CLOSE_PAREN constraintattributespec\n   ;\n\ndefinestmt\n   : CREATE opt_or_replace AGGREGATE func_name aggr_args definition\n   | CREATE opt_or_replace AGGREGATE func_name old_aggr_definition\n   | CREATE OPERATOR any_operator definition\n   | CREATE TYPE_P any_name definition\n   | CREATE TYPE_P any_name\n   | CREATE TYPE_P any_name AS OPEN_PAREN opttablefuncelementlist CLOSE_PAREN\n   | CREATE TYPE_P any_name AS ENUM_P OPEN_PAREN opt_enum_val_list CLOSE_PAREN\n   | CREATE TYPE_P any_name AS RANGE definition\n   | CREATE TEXT_P SEARCH PARSER any_name definition\n   | CREATE TEXT_P SEARCH DICTIONARY any_name definition\n   | CREATE TEXT_P SEARCH TEMPLATE any_name definition\n   | CREATE TEXT_P SEARCH CONFIGURATION any_name definition\n   | CREATE COLLATION any_name definition\n   | CREATE COLLATION IF_P NOT EXISTS any_name definition\n   | CREATE COLLATION any_name FROM any_name\n   | CREATE COLLATION IF_P NOT EXISTS any_name FROM any_name\n   ;\n\ndefinition\n   : OPEN_PAREN def_list CLOSE_PAREN\n   ;\n\ndef_list\n   : def_elem (COMMA def_elem)*\n   ;\n\ndef_elem\n   : collabel (EQUAL def_arg)?\n   ;\n\ndef_arg\n   : func_type\n   | reserved_keyword\n   | qual_all_op\n   | numericonly\n   | sconst\n   | NONE\n   ;\n\nold_aggr_definition\n   : OPEN_PAREN old_aggr_list CLOSE_PAREN\n   ;\n\nold_aggr_list\n   : old_aggr_elem (COMMA old_aggr_elem)*\n   ;\n\nold_aggr_elem\n   : identifier EQUAL def_arg\n   ;\n\nopt_enum_val_list\n   : enum_val_list\n   |\n   ;\n\nenum_val_list\n   : sconst (COMMA sconst)*\n   ;\n\nalterenumstmt\n   : ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists sconst\n   | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists sconst BEFORE sconst\n   | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists sconst AFTER sconst\n   | ALTER TYPE_P any_name RENAME VALUE_P sconst TO sconst\n   ;\n\nopt_if_not_exists\n   : IF_P NOT EXISTS\n   |\n   ;\n\ncreateopclassstmt\n   : CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P typename USING name opt_opfamily AS opclass_item_list\n   ;\n\nopclass_item_list\n   : opclass_item (COMMA opclass_item)*\n   ;\n\nopclass_item\n   : OPERATOR iconst any_operator opclass_purpose opt_recheck\n   | OPERATOR iconst operator_with_argtypes opclass_purpose opt_recheck\n   | FUNCTION iconst function_with_argtypes\n   | FUNCTION iconst OPEN_PAREN type_list CLOSE_PAREN function_with_argtypes\n   | STORAGE typename\n   ;\n\nopt_default\n   : DEFAULT\n   |\n   ;\n\nopt_opfamily\n   : FAMILY any_name\n   |\n   ;\n\nopclass_purpose\n   : FOR SEARCH\n   | FOR ORDER BY any_name\n   |\n   ;\n\nopt_recheck\n   : RECHECK\n   |\n   ;\n\ncreateopfamilystmt\n   : CREATE OPERATOR FAMILY any_name USING name\n   ;\n\nalteropfamilystmt\n   : ALTER OPERATOR FAMILY any_name USING name ADD_P opclass_item_list\n   | ALTER OPERATOR FAMILY any_name USING name DROP opclass_drop_list\n   ;\n\nopclass_drop_list\n   : opclass_drop (COMMA opclass_drop)*\n   ;\n\nopclass_drop\n   : OPERATOR iconst OPEN_PAREN type_list CLOSE_PAREN\n   | FUNCTION iconst OPEN_PAREN type_list CLOSE_PAREN\n   ;\n\ndropopclassstmt\n   : DROP OPERATOR CLASS any_name USING name opt_drop_behavior\n   | DROP OPERATOR CLASS IF_P EXISTS any_name USING name opt_drop_behavior\n   ;\n\ndropopfamilystmt\n   : DROP OPERATOR FAMILY any_name USING name opt_drop_behavior\n   | DROP OPERATOR FAMILY IF_P EXISTS any_name USING name opt_drop_behavior\n   ;\n\ndropownedstmt\n   : DROP OWNED BY role_list opt_drop_behavior\n   ;\n\nreassignownedstmt\n   : REASSIGN OWNED BY role_list TO rolespec\n   ;\n\ndropstmt\n   : DROP object_type_any_name IF_P EXISTS any_name_list opt_drop_behavior\n   | DROP object_type_any_name any_name_list opt_drop_behavior\n   | DROP drop_type_name IF_P EXISTS name_list opt_drop_behavior\n   | DROP drop_type_name name_list opt_drop_behavior\n   | DROP object_type_name_on_any_name name ON any_name opt_drop_behavior\n   | DROP object_type_name_on_any_name IF_P EXISTS name ON any_name opt_drop_behavior\n   | DROP TYPE_P type_name_list opt_drop_behavior\n   | DROP TYPE_P IF_P EXISTS type_name_list opt_drop_behavior\n   | DROP DOMAIN_P type_name_list opt_drop_behavior\n   | DROP DOMAIN_P IF_P EXISTS type_name_list opt_drop_behavior\n   | DROP INDEX CONCURRENTLY any_name_list opt_drop_behavior\n   | DROP INDEX CONCURRENTLY IF_P EXISTS any_name_list opt_drop_behavior\n   ;\n\nobject_type_any_name\n   : TABLE\n   | SEQUENCE\n   | VIEW\n   | MATERIALIZED VIEW\n   | INDEX\n   | FOREIGN TABLE\n   | COLLATION\n   | CONVERSION_P\n   | STATISTICS\n   | TEXT_P SEARCH PARSER\n   | TEXT_P SEARCH DICTIONARY\n   | TEXT_P SEARCH TEMPLATE\n   | TEXT_P SEARCH CONFIGURATION\n   ;\n\nobject_type_name\n   : drop_type_name\n   | DATABASE\n   | ROLE\n   | SUBSCRIPTION\n   | TABLESPACE\n   ;\n\ndrop_type_name\n   : ACCESS METHOD\n   | EVENT TRIGGER\n   | EXTENSION\n   | FOREIGN DATA_P WRAPPER\n   | opt_procedural LANGUAGE\n   | PUBLICATION\n   | SCHEMA\n   | SERVER\n   ;\n\nobject_type_name_on_any_name\n   : POLICY\n   | RULE\n   | TRIGGER\n   ;\n\nany_name_list\n   : any_name (COMMA any_name)*\n   ;\n\nany_name\n   : colid attrs?\n   ;\n\nattrs\n   :(DOT attr_name)+\n   ;\n\ntype_name_list\n   : typename (COMMA typename)*\n   ;\n\ntruncatestmt\n   : TRUNCATE opt_table relation_expr_list opt_restart_seqs opt_drop_behavior\n   ;\n\nopt_restart_seqs\n   : CONTINUE_P IDENTITY_P\n   | RESTART IDENTITY_P\n   |\n   ;\n\ncommentstmt\n   : COMMENT ON object_type_any_name any_name IS comment_text\n   | COMMENT ON COLUMN any_name IS comment_text\n   | COMMENT ON object_type_name name IS comment_text\n   | COMMENT ON TYPE_P typename IS comment_text\n   | COMMENT ON DOMAIN_P typename IS comment_text\n   | COMMENT ON AGGREGATE aggregate_with_argtypes IS comment_text\n   | COMMENT ON FUNCTION function_with_argtypes IS comment_text\n   | COMMENT ON OPERATOR operator_with_argtypes IS comment_text\n   | COMMENT ON CONSTRAINT name ON any_name IS comment_text\n   | COMMENT ON CONSTRAINT name ON DOMAIN_P any_name IS comment_text\n   | COMMENT ON object_type_name_on_any_name name ON any_name IS comment_text\n   | COMMENT ON PROCEDURE function_with_argtypes IS comment_text\n   | COMMENT ON ROUTINE function_with_argtypes IS comment_text\n   | COMMENT ON TRANSFORM FOR typename LANGUAGE name IS comment_text\n   | COMMENT ON OPERATOR CLASS any_name USING name IS comment_text\n   | COMMENT ON OPERATOR FAMILY any_name USING name IS comment_text\n   | COMMENT ON LARGE_P OBJECT_P numericonly IS comment_text\n   | COMMENT ON CAST OPEN_PAREN typename AS typename CLOSE_PAREN IS comment_text\n   ;\n\ncomment_text\n   : sconst\n   | NULL_P\n   ;\n\nseclabelstmt\n   : SECURITY LABEL opt_provider ON object_type_any_name any_name IS security_label\n   | SECURITY LABEL opt_provider ON COLUMN any_name IS security_label\n   | SECURITY LABEL opt_provider ON object_type_name name IS security_label\n   | SECURITY LABEL opt_provider ON TYPE_P typename IS security_label\n   | SECURITY LABEL opt_provider ON DOMAIN_P typename IS security_label\n   | SECURITY LABEL opt_provider ON AGGREGATE aggregate_with_argtypes IS security_label\n   | SECURITY LABEL opt_provider ON FUNCTION function_with_argtypes IS security_label\n   | SECURITY LABEL opt_provider ON LARGE_P OBJECT_P numericonly IS security_label\n   | SECURITY LABEL opt_provider ON PROCEDURE function_with_argtypes IS security_label\n   | SECURITY LABEL opt_provider ON ROUTINE function_with_argtypes IS security_label\n   ;\n\nopt_provider\n   : FOR nonreservedword_or_sconst\n   |\n   ;\n\nsecurity_label\n   : sconst\n   | NULL_P\n   ;\n\nfetchstmt\n   : FETCH fetch_args\n   | MOVE fetch_args\n   ;\n\nfetch_args\n   : cursor_name\n   | from_in cursor_name\n   | NEXT opt_from_in cursor_name\n   | PRIOR opt_from_in cursor_name\n   | FIRST_P opt_from_in cursor_name\n   | LAST_P opt_from_in cursor_name\n   | ABSOLUTE_P signediconst opt_from_in cursor_name\n   | RELATIVE_P signediconst opt_from_in cursor_name\n   | signediconst opt_from_in cursor_name\n   | ALL opt_from_in cursor_name\n   | FORWARD opt_from_in cursor_name\n   | FORWARD signediconst opt_from_in cursor_name\n   | FORWARD ALL opt_from_in cursor_name\n   | BACKWARD opt_from_in cursor_name\n   | BACKWARD signediconst opt_from_in cursor_name\n   | BACKWARD ALL opt_from_in cursor_name\n   ;\n\nfrom_in\n   : FROM\n   | IN_P\n   ;\n\nopt_from_in\n   : from_in\n   |\n   ;\n\ngrantstmt\n   : GRANT privileges ON privilege_target TO grantee_list opt_grant_grant_option\n   ;\n\nrevokestmt\n   : REVOKE privileges ON privilege_target FROM grantee_list opt_drop_behavior\n   | REVOKE GRANT OPTION FOR privileges ON privilege_target FROM grantee_list opt_drop_behavior\n   ;\n\nprivileges\n   : privilege_list\n   | ALL\n   | ALL PRIVILEGES\n   | ALL OPEN_PAREN columnlist CLOSE_PAREN\n   | ALL PRIVILEGES OPEN_PAREN columnlist CLOSE_PAREN\n   ;\n\nprivilege_list\n   : privilege (COMMA privilege)*\n   ;\n\nprivilege\n   : SELECT opt_column_list\n   | REFERENCES opt_column_list\n   | CREATE opt_column_list\n   | colid opt_column_list\n   ;\n\nprivilege_target\n   : qualified_name_list\n   | TABLE qualified_name_list\n   | SEQUENCE qualified_name_list\n   | FOREIGN DATA_P WRAPPER name_list\n   | FOREIGN SERVER name_list\n   | FUNCTION function_with_argtypes_list\n   | PROCEDURE function_with_argtypes_list\n   | ROUTINE function_with_argtypes_list\n   | DATABASE name_list\n   | DOMAIN_P any_name_list\n   | LANGUAGE name_list\n   | LARGE_P OBJECT_P numericonly_list\n   | SCHEMA name_list\n   | TABLESPACE name_list\n   | TYPE_P any_name_list\n   | ALL TABLES IN_P SCHEMA name_list\n   | ALL SEQUENCES IN_P SCHEMA name_list\n   | ALL FUNCTIONS IN_P SCHEMA name_list\n   | ALL PROCEDURES IN_P SCHEMA name_list\n   | ALL ROUTINES IN_P SCHEMA name_list\n   ;\n\ngrantee_list\n   : grantee (COMMA grantee)*\n   ;\n\ngrantee\n   : rolespec\n   | GROUP_P rolespec\n   ;\n\nopt_grant_grant_option\n   : WITH GRANT OPTION\n   |\n   ;\n\ngrantrolestmt\n   : GRANT privilege_list TO role_list opt_grant_admin_option opt_granted_by\n   ;\n\nrevokerolestmt\n   : REVOKE privilege_list FROM role_list opt_granted_by opt_drop_behavior\n   | REVOKE ADMIN OPTION FOR privilege_list FROM role_list opt_granted_by opt_drop_behavior\n   ;\n\nopt_grant_admin_option\n   : WITH ADMIN OPTION\n   |\n   ;\n\nopt_granted_by\n   : GRANTED BY rolespec\n   |\n   ;\n\nalterdefaultprivilegesstmt\n   : ALTER DEFAULT PRIVILEGES defacloptionlist defaclaction\n   ;\n\ndefacloptionlist\n   : defacloption*\n   ;\n\ndefacloption\n   : IN_P SCHEMA name_list\n   | FOR ROLE role_list\n   | FOR USER role_list\n   ;\n\ndefaclaction\n   : GRANT privileges ON defacl_privilege_target TO grantee_list opt_grant_grant_option\n   | REVOKE privileges ON defacl_privilege_target FROM grantee_list opt_drop_behavior\n   | REVOKE GRANT OPTION FOR privileges ON defacl_privilege_target FROM grantee_list opt_drop_behavior\n   ;\n\ndefacl_privilege_target\n   : TABLES\n   | FUNCTIONS\n   | ROUTINES\n   | SEQUENCES\n   | TYPES_P\n   | SCHEMAS\n   ;\n   //create index\n\nindexstmt\n   : CREATE opt_unique INDEX opt_concurrently opt_index_name ON relation_expr access_method_clause OPEN_PAREN index_params CLOSE_PAREN opt_include opt_reloptions opttablespace where_clause\n   | CREATE opt_unique INDEX opt_concurrently IF_P NOT EXISTS name ON relation_expr access_method_clause OPEN_PAREN index_params CLOSE_PAREN opt_include opt_reloptions opttablespace where_clause\n   ;\n\nopt_unique\n   : UNIQUE\n   |\n   ;\n\nopt_concurrently\n   : CONCURRENTLY\n   |\n   ;\n\nopt_index_name\n   : name\n   |\n   ;\n\naccess_method_clause\n   : USING name\n   |\n   ;\n\nindex_params\n   : index_elem (COMMA index_elem)*\n   ;\n\nindex_elem_options\n   : opt_collate opt_class opt_asc_desc opt_nulls_order\n   | opt_collate any_name reloptions opt_asc_desc opt_nulls_order\n   ;\n\nindex_elem\n   : colid index_elem_options\n   | func_expr_windowless index_elem_options\n   | OPEN_PAREN a_expr CLOSE_PAREN index_elem_options\n   ;\n\nopt_include\n   : INCLUDE OPEN_PAREN index_including_params CLOSE_PAREN\n   |\n   ;\n\nindex_including_params\n   : index_elem (COMMA index_elem)*\n   ;\n\nopt_collate\n   : COLLATE any_name\n   |\n   ;\n\nopt_class\n   : any_name\n   |\n   ;\n\nopt_asc_desc\n   : ASC\n   | DESC\n   |\n   ;\n   //TOD NULLS_LA was used\n\nopt_nulls_order\n   : NULLS_P FIRST_P\n   | NULLS_P LAST_P\n   |\n   ;\n\ncreatefunctionstmt\n   : CREATE opt_or_replace (FUNCTION | PROCEDURE) func_name func_args_with_defaults\n     (\n        RETURNS (func_return | TABLE OPEN_PAREN table_func_column_list CLOSE_PAREN)\n     )?\n     createfunc_opt_list\n   ;\n\nopt_or_replace\n   : OR REPLACE\n   |\n   ;\n\nfunc_args\n   : OPEN_PAREN func_args_list? CLOSE_PAREN\n   ;\n\nfunc_args_list\n   : func_arg (COMMA func_arg)*\n   ;\n\nfunction_with_argtypes_list\n   : function_with_argtypes (COMMA function_with_argtypes)*\n   ;\n\nfunction_with_argtypes\n   : func_name func_args\n   | type_func_name_keyword\n   | colid indirection?\n   ;\n\nfunc_args_with_defaults\n   : OPEN_PAREN func_args_with_defaults_list? CLOSE_PAREN\n   ;\n\nfunc_args_with_defaults_list\n   : func_arg_with_default (COMMA func_arg_with_default)*\n   ;\n\nfunc_arg\n   : arg_class param_name? func_type\n   | param_name arg_class? func_type\n   | func_type\n   ;\n\narg_class\n   : IN_P OUT_P?\n   | OUT_P\n   | INOUT\n   | VARIADIC\n   ;\n\nparam_name\n   : type_function_name\n   | builtin_function_name\n   | LEFT\n   | RIGHT\n   ;\n\nfunc_return\n   : func_type\n   ;\n\nfunc_type\n   : typename\n   | SETOF? (builtin_function_name | type_function_name | LEFT | RIGHT) attrs PERCENT TYPE_P\n   ;\n\nfunc_arg_with_default\n   : func_arg ((DEFAULT | EQUAL) a_expr)?\n   ;\n\naggr_arg\n   : func_arg\n   ;\n\naggr_args\n   : OPEN_PAREN (STAR | aggr_args_list | ORDER BY aggr_args_list | aggr_args_list ORDER BY aggr_args_list) CLOSE_PAREN\n   ;\n\naggr_args_list\n   : aggr_arg (COMMA aggr_arg)*\n   ;\n\naggregate_with_argtypes\n   : func_name aggr_args\n   ;\n\naggregate_with_argtypes_list\n   : aggregate_with_argtypes (COMMA aggregate_with_argtypes)*\n   ;\n\ncreatefunc_opt_list\n   : createfunc_opt_item+\n   {\n                ParseRoutineBody(_localctx);\n            }\n   //                    | createfunc_opt_list createfunc_opt_item\n\n   ;\n\ncommon_func_opt_item\n   : CALLED ON NULL_P INPUT_P\n   | RETURNS NULL_P ON NULL_P INPUT_P\n   | STRICT_P\n   | IMMUTABLE\n   | STABLE\n   | VOLATILE\n   | EXTERNAL SECURITY DEFINER\n   | EXTERNAL SECURITY INVOKER\n   | SECURITY DEFINER\n   | SECURITY INVOKER\n   | LEAKPROOF\n   | NOT LEAKPROOF\n   | SHIPPABLE\n   | NOT SHIPPABLE\n   | FENCED\n   | NOT FENCED\n   | PACKAGE\n   | COST numericonly\n   | ROWS numericonly\n   | SUPPORT any_name\n   | functionsetresetclause\n   | PARALLEL colid\n   ;\n\ncreatefunc_opt_item\n   : AS func_as\n   | LANGUAGE nonreservedword_or_sconst\n   | TRANSFORM transform_type_list\n   | WINDOW\n   | common_func_opt_item\n   ;\n   //https://www.postgresql.org/docs/9.1/sql-createfunction.html\n\n   //    | AS 'definition'\n\n   //    | AS 'obj_file', 'link_symbol'\n\nfunc_as locals[ParserRuleContext Definition]\n   :\n   /* |AS 'definition'*/\n   def = sconst\n   /*| AS 'obj_file', 'link_symbol'*/\n   | sconst COMMA sconst\n   ;\n\ntransform_type_list\n   :FOR TYPE_P typename (COMMA FOR TYPE_P typename)*\n   ;\n\nopt_definition\n   : WITH definition\n   |\n   ;\n\ntable_func_column\n   : param_name func_type\n   ;\n\ntable_func_column_list\n   : table_func_column (COMMA table_func_column)*\n   ;\n\nalterfunctionstmt\n   : ALTER (FUNCTION | PROCEDURE | ROUTINE) function_with_argtypes alterfunc_opt_list opt_restrict\n   ;\n\nalterfunc_opt_list\n   : common_func_opt_item+\n   ;\n\nopt_restrict\n   : RESTRICT\n   |\n   ;\n\nremovefuncstmt\n   : DROP FUNCTION function_with_argtypes_list opt_drop_behavior\n   | DROP FUNCTION IF_P EXISTS function_with_argtypes_list opt_drop_behavior\n   | DROP PROCEDURE function_with_argtypes_list opt_drop_behavior\n   | DROP PROCEDURE IF_P EXISTS function_with_argtypes_list opt_drop_behavior\n   | DROP ROUTINE function_with_argtypes_list opt_drop_behavior\n   | DROP ROUTINE IF_P EXISTS function_with_argtypes_list opt_drop_behavior\n   ;\n\nremoveaggrstmt\n   : DROP AGGREGATE aggregate_with_argtypes_list opt_drop_behavior\n   | DROP AGGREGATE IF_P EXISTS aggregate_with_argtypes_list opt_drop_behavior\n   ;\n\nremoveoperstmt\n   : DROP OPERATOR operator_with_argtypes_list opt_drop_behavior\n   | DROP OPERATOR IF_P EXISTS operator_with_argtypes_list opt_drop_behavior\n   ;\n\noper_argtypes\n   : OPEN_PAREN typename CLOSE_PAREN\n   | OPEN_PAREN typename COMMA typename CLOSE_PAREN\n   | OPEN_PAREN NONE COMMA typename CLOSE_PAREN\n   | OPEN_PAREN typename COMMA NONE CLOSE_PAREN\n   ;\n\nany_operator\n   : (colid DOT)* all_op\n   ;\n\noperator_with_argtypes_list\n   : operator_with_argtypes (COMMA operator_with_argtypes)*\n   ;\n\noperator_with_argtypes\n   : any_operator oper_argtypes\n   ;\n\ndostmt\n   : DO dostmt_opt_list\n   ;\n\ndostmt_opt_list\n   : dostmt_opt_item+\n   ;\n\ndostmt_opt_item\n   : sconst\n   | LANGUAGE nonreservedword_or_sconst\n   ;\n\ncreatecaststmt\n   : CREATE CAST OPEN_PAREN typename AS typename CLOSE_PAREN WITH FUNCTION function_with_argtypes cast_context\n   | CREATE CAST OPEN_PAREN typename AS typename CLOSE_PAREN WITHOUT FUNCTION cast_context\n   | CREATE CAST OPEN_PAREN typename AS typename CLOSE_PAREN WITH INOUT cast_context\n   ;\n\ncast_context\n   : AS IMPLICIT_P\n   | AS ASSIGNMENT\n   |\n   ;\n\ndropcaststmt\n   : DROP CAST opt_if_exists OPEN_PAREN typename AS typename CLOSE_PAREN opt_drop_behavior\n   ;\n\nopt_if_exists\n   : IF_P EXISTS\n   |\n   ;\n\ncreatetransformstmt\n   : CREATE opt_or_replace TRANSFORM FOR typename LANGUAGE name OPEN_PAREN transform_element_list CLOSE_PAREN\n   ;\n\ntransform_element_list\n   : FROM SQL_P WITH FUNCTION function_with_argtypes COMMA TO SQL_P WITH FUNCTION function_with_argtypes\n   | TO SQL_P WITH FUNCTION function_with_argtypes COMMA FROM SQL_P WITH FUNCTION function_with_argtypes\n   | FROM SQL_P WITH FUNCTION function_with_argtypes\n   | TO SQL_P WITH FUNCTION function_with_argtypes\n   ;\n\ndroptransformstmt\n   : DROP TRANSFORM opt_if_exists FOR typename LANGUAGE name opt_drop_behavior\n   ;\n\nreindexstmt\n   : REINDEX reindex_target_type opt_concurrently qualified_name\n   | REINDEX reindex_target_multitable opt_concurrently name\n   | REINDEX OPEN_PAREN reindex_option_list CLOSE_PAREN reindex_target_type opt_concurrently qualified_name\n   | REINDEX OPEN_PAREN reindex_option_list CLOSE_PAREN reindex_target_multitable opt_concurrently name\n   ;\n\nreindex_target_type\n   : INDEX\n   | TABLE\n   | SCHEMA\n   | DATABASE\n   | SYSTEM_P\n   ;\n\nreindex_target_multitable\n   : SCHEMA\n   | SYSTEM_P\n   | DATABASE\n   ;\n\nreindex_option_list\n   : reindex_option_elem (COMMA reindex_option_elem)*\n   ;\n\nreindex_option_elem\n   : VERBOSE\n   | TABLESPACE\n   | CONCURRENTLY\n   ;\n\naltertblspcstmt\n   : ALTER TABLESPACE name SET reloptions\n   | ALTER TABLESPACE name RESET reloptions\n   ;\n\nrenamestmt\n   : ALTER AGGREGATE aggregate_with_argtypes RENAME TO name\n   | ALTER COLLATION any_name RENAME TO name\n   | ALTER CONVERSION_P any_name RENAME TO name\n   | ALTER DATABASE name RENAME TO name\n   | ALTER DOMAIN_P any_name RENAME TO name\n   | ALTER DOMAIN_P any_name RENAME CONSTRAINT name TO name\n   | ALTER FOREIGN DATA_P WRAPPER name RENAME TO name\n   | ALTER FUNCTION function_with_argtypes RENAME TO name\n   | ALTER GROUP_P roleid RENAME TO roleid\n   | ALTER opt_procedural LANGUAGE name RENAME TO name\n   | ALTER OPERATOR CLASS any_name USING name RENAME TO name\n   | ALTER OPERATOR FAMILY any_name USING name RENAME TO name\n   | ALTER POLICY name ON qualified_name RENAME TO name\n   | ALTER POLICY IF_P EXISTS name ON qualified_name RENAME TO name\n   | ALTER PROCEDURE function_with_argtypes RENAME TO name\n   | ALTER PUBLICATION name RENAME TO name\n   | ALTER ROUTINE function_with_argtypes RENAME TO name\n   | ALTER SCHEMA name RENAME TO name\n   | ALTER SERVER name RENAME TO name\n   | ALTER SUBSCRIPTION name RENAME TO name\n   | ALTER TABLE relation_expr RENAME TO name\n   | ALTER TABLE IF_P EXISTS relation_expr RENAME TO name\n   | ALTER SEQUENCE qualified_name RENAME TO name\n   | ALTER SEQUENCE IF_P EXISTS qualified_name RENAME TO name\n   | ALTER VIEW qualified_name RENAME TO name\n   | ALTER VIEW IF_P EXISTS qualified_name RENAME TO name\n   | ALTER MATERIALIZED VIEW qualified_name RENAME TO name\n   | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name RENAME TO name\n   | ALTER INDEX qualified_name RENAME TO name\n   | ALTER INDEX IF_P EXISTS qualified_name RENAME TO name\n   | ALTER FOREIGN TABLE relation_expr RENAME TO name\n   | ALTER FOREIGN TABLE IF_P EXISTS relation_expr RENAME TO name\n   | ALTER TABLE relation_expr RENAME opt_column name TO name\n   | ALTER TABLE IF_P EXISTS relation_expr RENAME opt_column name TO name\n   | ALTER VIEW qualified_name RENAME opt_column name TO name\n   | ALTER VIEW IF_P EXISTS qualified_name RENAME opt_column name TO name\n   | ALTER MATERIALIZED VIEW qualified_name RENAME opt_column name TO name\n   | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name RENAME opt_column name TO name\n   | ALTER TABLE relation_expr RENAME CONSTRAINT name TO name\n   | ALTER TABLE IF_P EXISTS relation_expr RENAME CONSTRAINT name TO name\n   | ALTER FOREIGN TABLE relation_expr RENAME opt_column name TO name\n   | ALTER FOREIGN TABLE IF_P EXISTS relation_expr RENAME opt_column name TO name\n   | ALTER RULE name ON qualified_name RENAME TO name\n   | ALTER TRIGGER name ON qualified_name RENAME TO name\n   | ALTER EVENT TRIGGER name RENAME TO name\n   | ALTER ROLE roleid RENAME TO roleid\n   | ALTER USER roleid RENAME TO roleid\n   | ALTER TABLESPACE name RENAME TO name\n   | ALTER STATISTICS any_name RENAME TO name\n   | ALTER TEXT_P SEARCH PARSER any_name RENAME TO name\n   | ALTER TEXT_P SEARCH DICTIONARY any_name RENAME TO name\n   | ALTER TEXT_P SEARCH TEMPLATE any_name RENAME TO name\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name RENAME TO name\n   | ALTER TYPE_P any_name RENAME TO name\n   | ALTER TYPE_P any_name RENAME ATTRIBUTE name TO name opt_drop_behavior\n   ;\n\nopt_column\n   : COLUMN\n   |\n   ;\n\nopt_set_data\n   : SET DATA_P\n   |\n   ;\n\nalterobjectdependsstmt\n   : ALTER FUNCTION function_with_argtypes opt_no DEPENDS ON EXTENSION name\n   | ALTER PROCEDURE function_with_argtypes opt_no DEPENDS ON EXTENSION name\n   | ALTER ROUTINE function_with_argtypes opt_no DEPENDS ON EXTENSION name\n   | ALTER TRIGGER name ON qualified_name opt_no DEPENDS ON EXTENSION name\n   | ALTER MATERIALIZED VIEW qualified_name opt_no DEPENDS ON EXTENSION name\n   | ALTER INDEX qualified_name opt_no DEPENDS ON EXTENSION name\n   ;\n\nopt_no\n   : NO\n   |\n   ;\n\nalterobjectschemastmt\n   : ALTER AGGREGATE aggregate_with_argtypes SET SCHEMA name\n   | ALTER COLLATION any_name SET SCHEMA name\n   | ALTER CONVERSION_P any_name SET SCHEMA name\n   | ALTER DOMAIN_P any_name SET SCHEMA name\n   | ALTER EXTENSION name SET SCHEMA name\n   | ALTER FUNCTION function_with_argtypes SET SCHEMA name\n   | ALTER OPERATOR operator_with_argtypes SET SCHEMA name\n   | ALTER OPERATOR CLASS any_name USING name SET SCHEMA name\n   | ALTER OPERATOR FAMILY any_name USING name SET SCHEMA name\n   | ALTER PROCEDURE function_with_argtypes SET SCHEMA name\n   | ALTER ROUTINE function_with_argtypes SET SCHEMA name\n   | ALTER TABLE relation_expr SET SCHEMA name\n   | ALTER TABLE IF_P EXISTS relation_expr SET SCHEMA name\n   | ALTER STATISTICS any_name SET SCHEMA name\n   | ALTER TEXT_P SEARCH PARSER any_name SET SCHEMA name\n   | ALTER TEXT_P SEARCH DICTIONARY any_name SET SCHEMA name\n   | ALTER TEXT_P SEARCH TEMPLATE any_name SET SCHEMA name\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name SET SCHEMA name\n   | ALTER SEQUENCE qualified_name SET SCHEMA name\n   | ALTER SEQUENCE IF_P EXISTS qualified_name SET SCHEMA name\n   | ALTER VIEW qualified_name SET SCHEMA name\n   | ALTER VIEW IF_P EXISTS qualified_name SET SCHEMA name\n   | ALTER MATERIALIZED VIEW qualified_name SET SCHEMA name\n   | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name SET SCHEMA name\n   | ALTER FOREIGN TABLE relation_expr SET SCHEMA name\n   | ALTER FOREIGN TABLE IF_P EXISTS relation_expr SET SCHEMA name\n   | ALTER TYPE_P any_name SET SCHEMA name\n   ;\n\nalteroperatorstmt\n   : ALTER OPERATOR operator_with_argtypes SET OPEN_PAREN operator_def_list CLOSE_PAREN\n   ;\n\noperator_def_list\n   : operator_def_elem (COMMA operator_def_elem)*\n   ;\n\noperator_def_elem\n   : collabel EQUAL NONE\n   | collabel EQUAL operator_def_arg\n   ;\n\noperator_def_arg\n   : func_type\n   | reserved_keyword\n   | qual_all_op\n   | numericonly\n   | sconst\n   ;\n\naltertypestmt\n   : ALTER TYPE_P any_name SET OPEN_PAREN operator_def_list CLOSE_PAREN\n   ;\n\nalterownerstmt\n   : ALTER AGGREGATE aggregate_with_argtypes OWNER TO rolespec\n   | ALTER COLLATION any_name OWNER TO rolespec\n   | ALTER CONVERSION_P any_name OWNER TO rolespec\n   | ALTER DATABASE name OWNER TO rolespec\n   | ALTER DOMAIN_P any_name OWNER TO rolespec\n   | ALTER FUNCTION function_with_argtypes OWNER TO rolespec\n   | ALTER opt_procedural LANGUAGE name OWNER TO rolespec\n   | ALTER LARGE_P OBJECT_P numericonly OWNER TO rolespec\n   | ALTER OPERATOR operator_with_argtypes OWNER TO rolespec\n   | ALTER OPERATOR CLASS any_name USING name OWNER TO rolespec\n   | ALTER OPERATOR FAMILY any_name USING name OWNER TO rolespec\n   | ALTER PROCEDURE function_with_argtypes OWNER TO rolespec\n   | ALTER ROUTINE function_with_argtypes OWNER TO rolespec\n   | ALTER SCHEMA name OWNER TO rolespec\n   | ALTER TYPE_P any_name OWNER TO rolespec\n   | ALTER TABLESPACE name OWNER TO rolespec\n   | ALTER STATISTICS any_name OWNER TO rolespec\n   | ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO rolespec\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO rolespec\n   | ALTER FOREIGN DATA_P WRAPPER name OWNER TO rolespec\n   | ALTER SERVER name OWNER TO rolespec\n   | ALTER EVENT TRIGGER name OWNER TO rolespec\n   | ALTER PUBLICATION name OWNER TO rolespec\n   | ALTER SUBSCRIPTION name OWNER TO rolespec\n   ;\n\ncreatepublicationstmt\n   : CREATE PUBLICATION name opt_publication_for_tables opt_definition\n   ;\n\nopt_publication_for_tables\n   : publication_for_tables\n   |\n   ;\n\npublication_for_tables\n   : FOR TABLE relation_expr_list\n   | FOR ALL TABLES\n   ;\n\nalterpublicationstmt\n   : ALTER PUBLICATION name SET definition\n   | ALTER PUBLICATION name ADD_P TABLE relation_expr_list\n   | ALTER PUBLICATION name SET TABLE relation_expr_list\n   | ALTER PUBLICATION name DROP TABLE relation_expr_list\n   ;\n\ncreatesubscriptionstmt\n   : CREATE SUBSCRIPTION name CONNECTION sconst PUBLICATION publication_name_list opt_definition\n   ;\n\npublication_name_list\n   : publication_name_item (COMMA publication_name_item)*\n   ;\n\npublication_name_item\n   : collabel\n   ;\n\naltersubscriptionstmt\n   : ALTER SUBSCRIPTION name SET definition\n   | ALTER SUBSCRIPTION name CONNECTION sconst\n   | ALTER SUBSCRIPTION name REFRESH PUBLICATION opt_definition\n   | ALTER SUBSCRIPTION name SET PUBLICATION publication_name_list opt_definition\n   | ALTER SUBSCRIPTION name ENABLE_P\n   | ALTER SUBSCRIPTION name DISABLE_P\n   ;\n\ndropsubscriptionstmt\n   : DROP SUBSCRIPTION name opt_drop_behavior\n   | DROP SUBSCRIPTION IF_P EXISTS name opt_drop_behavior\n   ;\n\nrulestmt\n   : CREATE opt_or_replace RULE name AS ON event TO qualified_name where_clause DO opt_instead ruleactionlist\n   ;\n\nruleactionlist\n   : NOTHING\n   | ruleactionstmt\n   | OPEN_PAREN ruleactionmulti CLOSE_PAREN\n   ;\n\nruleactionmulti\n   : ruleactionstmtOrEmpty (SEMI ruleactionstmtOrEmpty)*\n   ;\n\nruleactionstmt\n   : selectstmt\n   | insertstmt\n   | updatestmt\n   | deletestmt\n   | notifystmt\n   ;\n\nruleactionstmtOrEmpty\n   : ruleactionstmt\n   |\n   ;\n\nevent\n   : SELECT\n   | UPDATE\n   | DELETE_P\n   | INSERT\n   ;\n\nopt_instead\n   : INSTEAD\n   | ALSO\n   |\n   ;\n\nnotifystmt\n   : NOTIFY colid notify_payload\n   ;\n\nnotify_payload\n   : COMMA sconst\n   |\n   ;\n\nlistenstmt\n   : LISTEN colid\n   ;\n\nunlistenstmt\n   : UNLISTEN colid\n   | UNLISTEN STAR\n   ;\n\ntransactionstmt\n   : ABORT_P opt_transaction opt_transaction_chain\n   | BEGIN_P opt_transaction transaction_mode_list_or_empty\n   | START TRANSACTION transaction_mode_list_or_empty\n   | COMMIT opt_transaction opt_transaction_chain\n   | END_P opt_transaction opt_transaction_chain\n   | ROLLBACK opt_transaction opt_transaction_chain\n   | SAVEPOINT colid\n   | RELEASE SAVEPOINT colid\n   | RELEASE colid\n   | ROLLBACK opt_transaction TO SAVEPOINT colid\n   | ROLLBACK opt_transaction TO colid\n   | PREPARE TRANSACTION sconst\n   | COMMIT PREPARED sconst\n   | ROLLBACK PREPARED sconst\n   ;\n\nopt_transaction\n   : WORK\n   | TRANSACTION\n   |\n   ;\n\ntransaction_mode_item\n   : ISOLATION LEVEL iso_level\n   | READ ONLY\n   | READ WRITE\n   | DEFERRABLE\n   | NOT DEFERRABLE\n   ;\n\ntransaction_mode_list\n   : transaction_mode_item (COMMA? transaction_mode_item)*\n   ;\n\ntransaction_mode_list_or_empty\n   : transaction_mode_list\n   |\n   ;\n\nopt_transaction_chain\n   : AND NO? CHAIN\n   |\n   ;\n\nviewstmt\n   : CREATE (OR REPLACE)? opttemp\n    (\n          VIEW qualified_name opt_column_list opt_reloptions\n        | RECURSIVE VIEW qualified_name OPEN_PAREN columnlist CLOSE_PAREN opt_reloptions\n    )\n     AS selectstmt opt_check_option\n   ;\n\nopt_check_option\n   : WITH (CASCADED | LOCAL)? CHECK OPTION\n   |\n   ;\n\nloadstmt\n   : LOAD file_name\n   ;\n\ncreatedbstmt\n   : CREATE DATABASE name opt_with createdb_opt_list\n   ;\n\ncreatedb_opt_list\n   : createdb_opt_items\n   |\n   ;\n\ncreatedb_opt_items\n   : createdb_opt_item+\n   ;\n\ncreatedb_opt_item\n   : createdb_opt_name opt_equal (signediconst | opt_boolean_or_string | DEFAULT)\n   ;\n\ncreatedb_opt_name\n   : identifier\n   | CONNECTION LIMIT\n   | ENCODING\n   | LOCATION\n   | OWNER\n   | TABLESPACE\n   | TEMPLATE\n   ;\n\nopt_equal\n   : EQUAL\n   |\n   ;\n\nalterdatabasestmt\n   : ALTER DATABASE name (WITH createdb_opt_list | createdb_opt_list | SET TABLESPACE name)\n   ;\n\nalterdatabasesetstmt\n   : ALTER DATABASE name setresetclause\n   ;\n\ndropdbstmt\n   : DROP DATABASE (IF_P EXISTS)? name (opt_with OPEN_PAREN drop_option_list CLOSE_PAREN)?\n   ;\n\ndrop_option_list\n   : drop_option (COMMA drop_option)*\n   ;\n\ndrop_option\n   : FORCE\n   ;\n\naltercollationstmt\n   : ALTER COLLATION any_name REFRESH VERSION_P\n   ;\n\naltersystemstmt\n   : ALTER SYSTEM_P (SET | RESET) generic_set\n   ;\n\ncreatedomainstmt\n   : CREATE DOMAIN_P any_name opt_as typename colquallist\n   ;\n\nalterdomainstmt\n   : ALTER DOMAIN_P any_name (alter_column_default | DROP NOT NULL_P | SET NOT NULL_P | ADD_P tableconstraint | DROP CONSTRAINT (IF_P EXISTS)? name opt_drop_behavior | VALIDATE CONSTRAINT name)\n   ;\n\nopt_as\n   : AS\n   |\n   ;\n\naltertsdictionarystmt\n   : ALTER TEXT_P SEARCH DICTIONARY any_name definition\n   ;\n\naltertsconfigurationstmt\n   : ALTER TEXT_P SEARCH CONFIGURATION any_name ADD_P MAPPING FOR name_list any_with any_name_list\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list any_with any_name_list\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING REPLACE any_name any_with any_name\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list REPLACE any_name any_with any_name\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING FOR name_list\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING IF_P EXISTS FOR name_list\n   ;\n\nany_with\n   : WITH\n   //TODO\n\n   //         | WITH_LA\n\n   ;\n\ncreateconversionstmt\n   : CREATE opt_default CONVERSION_P any_name FOR sconst TO sconst FROM any_name\n   ;\n\nclusterstmt\n   : CLUSTER opt_verbose qualified_name cluster_index_specification\n   | CLUSTER opt_verbose\n   | CLUSTER opt_verbose name ON qualified_name\n   ;\n\ncluster_index_specification\n   : USING name\n   |\n   ;\n\nvacuumstmt\n   : VACUUM opt_full opt_freeze opt_verbose opt_analyze opt_vacuum_relation_list\n   | VACUUM OPEN_PAREN vac_analyze_option_list CLOSE_PAREN opt_vacuum_relation_list\n   ;\n\nanalyzestmt\n   : analyze_keyword opt_verbose opt_vacuum_relation_list\n   | analyze_keyword OPEN_PAREN vac_analyze_option_list CLOSE_PAREN opt_vacuum_relation_list\n   ;\n\nvac_analyze_option_list\n   : vac_analyze_option_elem (COMMA vac_analyze_option_elem)*\n   ;\n\nanalyze_keyword\n   : ANALYZE\n   | ANALYSE\n   ;\n\nvac_analyze_option_elem\n   : vac_analyze_option_name vac_analyze_option_arg\n   ;\n\nvac_analyze_option_name\n   : nonreservedword\n   | analyze_keyword\n   ;\n\nvac_analyze_option_arg\n   : opt_boolean_or_string\n   | numericonly\n   |\n   ;\n\nopt_analyze\n   : analyze_keyword\n   |\n   ;\n\nopt_verbose\n   : VERBOSE\n   |\n   ;\n\nopt_full\n   : FULL\n   |\n   ;\n\nopt_freeze\n   : FREEZE\n   |\n   ;\n\nopt_name_list\n   : OPEN_PAREN name_list CLOSE_PAREN\n   |\n   ;\n\nvacuum_relation\n   : qualified_name opt_name_list\n   ;\n\nvacuum_relation_list\n   : vacuum_relation (COMMA vacuum_relation)*\n   ;\n\nopt_vacuum_relation_list\n   : vacuum_relation_list\n   |\n   ;\n\nexplainstmt\n   : EXPLAIN explainablestmt\n   | EXPLAIN analyze_keyword opt_verbose explainablestmt\n   | EXPLAIN VERBOSE explainablestmt\n   | EXPLAIN OPEN_PAREN explain_option_list CLOSE_PAREN explainablestmt\n   ;\n\nexplainablestmt\n   : selectstmt\n   | insertstmt\n   | updatestmt\n   | deletestmt\n   | declarecursorstmt\n   | createasstmt\n   | creatematviewstmt\n   | refreshmatviewstmt\n   | executestmt\n   ;\n\nexplain_option_list\n   : explain_option_elem (COMMA explain_option_elem)*\n   ;\n\nexplain_option_elem\n   : explain_option_name explain_option_arg\n   ;\n\nexplain_option_name\n   : nonreservedword\n   | analyze_keyword\n   ;\n\nexplain_option_arg\n   : opt_boolean_or_string\n   | numericonly\n   |\n   ;\n\npreparestmt\n   : PREPARE name prep_type_clause AS preparablestmt\n   ;\n\nprep_type_clause\n   : OPEN_PAREN type_list CLOSE_PAREN\n   |\n   ;\n\npreparablestmt\n   : selectstmt\n   | insertstmt\n   | updatestmt\n   | deletestmt\n   ;\n\nexecutestmt\n   : EXECUTE name execute_param_clause\n   | CREATE opttemp TABLE create_as_target AS EXECUTE name execute_param_clause opt_with_data\n   | CREATE opttemp TABLE IF_P NOT EXISTS create_as_target AS EXECUTE name execute_param_clause opt_with_data\n   ;\n\nexecute_param_clause\n   : OPEN_PAREN expr_list CLOSE_PAREN\n   |\n   ;\n\ndeallocatestmt\n   : DEALLOCATE name\n   | DEALLOCATE PREPARE name\n   | DEALLOCATE ALL\n   | DEALLOCATE PREPARE ALL\n   ;\n\ninsertstmt\n   : opt_with_clause INSERT INTO insert_target insert_rest opt_on_conflict returning_clause\n   ;\n\ninsert_target\n   : qualified_name (AS colid)?\n   ;\n\ninsert_rest\n   : selectstmt\n   | OVERRIDING override_kind VALUE_P selectstmt\n   | OPEN_PAREN insert_column_list CLOSE_PAREN (OVERRIDING override_kind VALUE_P)? selectstmt\n   | DEFAULT VALUES\n   ;\n\noverride_kind\n   : USER\n   | SYSTEM_P\n   ;\n\ninsert_column_list\n   : insert_column_item (COMMA insert_column_item)*\n   ;\n\ninsert_column_item\n   : colid opt_indirection\n   ;\n\nopt_on_conflict\n   : ON CONFLICT opt_conf_expr DO (UPDATE SET set_clause_list where_clause | NOTHING)\n   |\n   ;\n\nopt_conf_expr\n   : OPEN_PAREN index_params CLOSE_PAREN where_clause\n   | ON CONSTRAINT name\n   |\n   ;\n\nreturning_clause\n   : RETURNING target_list\n   |\n   ;\n\n// https://www.postgresql.org/docs/current/sql-merge.html\nmergestmt\n   : MERGE INTO? qualified_name alias_clause? USING (select_with_parens|qualified_name) alias_clause? ON a_expr\n        (merge_insert_clause merge_update_clause? | merge_update_clause merge_insert_clause?) merge_delete_clause?\n   ;\n\nmerge_insert_clause\n   : WHEN NOT MATCHED (AND a_expr)? THEN? INSERT (OPEN_PAREN insert_column_list CLOSE_PAREN)? values_clause\n   ;\n\nmerge_update_clause\n   : WHEN MATCHED (AND a_expr)? THEN? UPDATE SET set_clause_list\n   ;\n\nmerge_delete_clause\n   : WHEN MATCHED THEN? DELETE_P\n   ;\n\ndeletestmt\n   : opt_with_clause DELETE_P FROM relation_expr_opt_alias using_clause where_or_current_clause returning_clause\n   ;\n\nusing_clause\n   : USING from_list\n   |\n   ;\n\nlockstmt\n   : LOCK_P opt_table relation_expr_list opt_lock opt_nowait\n   ;\n\nopt_lock\n   : IN_P lock_type MODE\n   |\n   ;\n\nlock_type\n   : ACCESS (SHARE | EXCLUSIVE)\n   | ROW (SHARE | EXCLUSIVE)\n   | SHARE (UPDATE EXCLUSIVE | ROW EXCLUSIVE)?\n   | EXCLUSIVE\n   ;\n\nopt_nowait\n   : NOWAIT\n   |\n   ;\n\nopt_nowait_or_skip\n   : NOWAIT\n   | SKIP_P LOCKED\n   |\n   ;\n\nupdatestmt\n   : opt_with_clause UPDATE relation_expr_opt_alias SET set_clause_list from_clause where_or_current_clause returning_clause\n   ;\n\nset_clause_list\n   : set_clause (COMMA set_clause)*\n   ;\n\nset_clause\n   : set_target EQUAL a_expr\n   | OPEN_PAREN set_target_list CLOSE_PAREN EQUAL a_expr\n   ;\n\nset_target\n   : colid opt_indirection\n   ;\n\nset_target_list\n   : set_target (COMMA set_target)*\n   ;\n\ndeclarecursorstmt\n   : DECLARE cursor_name cursor_options CURSOR opt_hold FOR selectstmt\n   ;\n\ncursor_name\n   : name\n   ;\n\ncursor_options\n   : (NO SCROLL | SCROLL | BINARY | INSENSITIVE)*\n   ;\n\nopt_hold\n   :\n   | WITH HOLD\n   | WITHOUT HOLD\n   ;\n/*\nTODO: why select_with_parens alternative is needed at all?\ni guess it because original byson grammar can choose selectstmt(2)->select_with_parens on only OPEN_PARENT/SELECT kewords at the begining of statement;\n(select * from tab);\nparse can go through selectstmt( )->select_no_parens(1)->select_clause(2)->select_with_parens(1)->select_no_parens(1)->select_clause(1)->simple_select\ninstead of           selectstmt(1)->select_no_parens(1)->select_clause(2)->select_with_parens(1)->select_no_parens(1)->select_clause(1)->simple_select\nall standard tests passed on both variants\n*/\n\n\nselectstmt\n   : select_no_parens\n   | select_with_parens\n   ;\n\nselect_with_parens\n   : OPEN_PAREN select_no_parens CLOSE_PAREN\n   | OPEN_PAREN select_with_parens CLOSE_PAREN\n   ;\n\nselect_no_parens\n   : select_clause opt_sort_clause (for_locking_clause opt_select_limit | select_limit opt_for_locking_clause)?\n   | with_clause select_clause opt_sort_clause (for_locking_clause opt_select_limit | select_limit opt_for_locking_clause)?\n   ;\n\nselect_clause\n   : simple_select_intersect ((UNION | EXCEPT) all_or_distinct simple_select_intersect)*\n   ;\n\nsimple_select_intersect\n    : simple_select_pramary (INTERSECT all_or_distinct simple_select_pramary)*\n    ;\n\nsimple_select_pramary\n   : ( SELECT (opt_all_clause into_clause opt_target_list | distinct_clause target_list)\n           into_clause\n           from_clause\n           where_clause\n           group_clause\n           having_clause\n           window_clause\n    )\n   | values_clause\n   | TABLE relation_expr\n   | select_with_parens\n   ;\n\nwith_clause\n   : WITH RECURSIVE? cte_list\n   ;\n\ncte_list\n   : common_table_expr (COMMA common_table_expr)*\n   ;\n\ncommon_table_expr\n   : name opt_name_list AS opt_materialized OPEN_PAREN preparablestmt CLOSE_PAREN\n   ;\n\nopt_materialized\n   : MATERIALIZED\n   | NOT MATERIALIZED\n   |\n   ;\n\nopt_with_clause\n   : with_clause\n   |\n   ;\n\ninto_clause\n   : INTO (opt_strict opttempTableName | into_target)\n   |\n   ;\n\nopt_strict\n   :\n   | STRICT_P\n   ;\n\nopttempTableName\n   : (LOCAL|GLOBAL)? (TEMPORARY | TEMP) opt_table qualified_name\n   | UNLOGGED opt_table qualified_name\n   | TABLE qualified_name\n   | qualified_name\n   ;\n\nopt_table\n   : TABLE\n   |\n   ;\n\nall_or_distinct\n   : ALL\n   | DISTINCT\n   |\n   ;\n\ndistinct_clause\n   : DISTINCT (ON OPEN_PAREN expr_list CLOSE_PAREN)?\n   ;\n\nopt_all_clause\n   : ALL\n   |\n   ;\n\nopt_sort_clause\n   : sort_clause\n   |\n   ;\n\nsort_clause\n   : ORDER BY sortby_list\n   ;\n\nsortby_list\n   : sortby (COMMA sortby)*\n   ;\n\nsortby\n   : a_expr (USING qual_all_op | opt_asc_desc) opt_nulls_order\n   ;\n\nselect_limit\n   : limit_clause offset_clause?\n   | offset_clause limit_clause?\n   ;\n\nopt_select_limit\n   : select_limit\n   |\n   ;\n\nlimit_clause\n   : LIMIT select_limit_value (COMMA select_offset_value)?\n   | FETCH first_or_next (select_fetch_first_value row_or_rows (ONLY | WITH TIES) | row_or_rows (ONLY | WITH TIES))\n   ;\n\noffset_clause\n   : OFFSET (select_offset_value | select_fetch_first_value row_or_rows)\n   ;\n\nselect_limit_value\n   : a_expr\n   | ALL\n   ;\n\nselect_offset_value\n   : a_expr\n   ;\n\nselect_fetch_first_value\n   : c_expr\n   | PLUS i_or_f_const\n   | MINUS i_or_f_const\n   ;\n\ni_or_f_const\n   : iconst\n   | fconst\n   ;\n\nrow_or_rows\n   : ROW\n   | ROWS\n   ;\n\nfirst_or_next\n   : FIRST_P\n   | NEXT\n   ;\n\ngroup_clause\n   : GROUP_P BY group_by_list\n   |\n   ;\n\ngroup_by_list\n   : group_by_item (COMMA group_by_item)*\n   ;\n\ngroup_by_item\n   : empty_grouping_set\n   | cube_clause\n   | rollup_clause\n   | grouping_sets_clause\n   | a_expr\n   ;\n\nempty_grouping_set\n   : OPEN_PAREN CLOSE_PAREN\n   ;\n\nrollup_clause\n   : ROLLUP OPEN_PAREN expr_list CLOSE_PAREN\n   ;\n\ncube_clause\n   : CUBE OPEN_PAREN expr_list CLOSE_PAREN\n   ;\n\ngrouping_sets_clause\n   : GROUPING SETS OPEN_PAREN group_by_list CLOSE_PAREN\n   ;\n\nhaving_clause\n   : HAVING a_expr\n   |\n   ;\n\nfor_locking_clause\n   : for_locking_items\n   | FOR READ ONLY\n   ;\n\nopt_for_locking_clause\n   : for_locking_clause\n   |\n   ;\n\nfor_locking_items\n   : for_locking_item+\n   ;\n\nfor_locking_item\n   : for_locking_strength locked_rels_list opt_nowait_or_skip\n   ;\n\nfor_locking_strength\n   : FOR ((NO KEY)? UPDATE | KEY? SHARE)\n   ;\n\nlocked_rels_list\n   : OF qualified_name_list\n   |\n   ;\n\nvalues_clause\n   : VALUES OPEN_PAREN expr_list CLOSE_PAREN (COMMA OPEN_PAREN expr_list CLOSE_PAREN)*\n   ;\n\nfrom_clause\n   : FROM from_list\n   |\n   ;\n\nfrom_list\n   : non_ansi_join\n   | table_ref (COMMA table_ref)*\n   ;\n\nnon_ansi_join\n   : table_ref (COMMA table_ref)+\n   ;\n\ntable_ref\n   : (relation_expr opt_alias_clause tablesample_clause?\n      | func_table func_alias_clause\n      | xmltable opt_alias_clause\n      | select_with_parens opt_alias_clause\n      | LATERAL_P (\n                    xmltable opt_alias_clause\n                    | func_table func_alias_clause\n                    | select_with_parens opt_alias_clause\n                  )\n      | OPEN_PAREN table_ref (\n                                CROSS JOIN table_ref\n                                | NATURAL join_type? JOIN table_ref\n                                | join_type? JOIN table_ref join_qual\n                             )? CLOSE_PAREN opt_alias_clause\n     )\n        (CROSS JOIN table_ref | NATURAL join_type? JOIN table_ref | join_type? JOIN table_ref join_qual)*\n   ;\n\nalias_clause\n   : AS? colid (OPEN_PAREN name_list CLOSE_PAREN)?\n   ;\n\nopt_alias_clause\n   : table_alias_clause\n   |\n   ;\n\ntable_alias_clause\n   : AS? table_alias (OPEN_PAREN name_list CLOSE_PAREN)?\n   ;\n\nfunc_alias_clause\n   : alias_clause\n   | (AS colid? | colid) OPEN_PAREN tablefuncelementlist CLOSE_PAREN\n   |\n   ;\n\njoin_type\n   : (FULL | LEFT | RIGHT | INNER_P) OUTER_P?\n   ;\n\njoin_qual\n   : USING OPEN_PAREN name_list CLOSE_PAREN\n   | ON a_expr\n   ;\n\nrelation_expr\n   : qualified_name STAR?\n   | ONLY (qualified_name | OPEN_PAREN qualified_name CLOSE_PAREN)\n   ;\n\nrelation_expr_list\n   : relation_expr (COMMA relation_expr)*\n   ;\n\nrelation_expr_opt_alias\n   : relation_expr (AS? colid)?\n   ;\n\ntablesample_clause\n   : TABLESAMPLE func_name OPEN_PAREN expr_list CLOSE_PAREN opt_repeatable_clause\n   ;\n\nopt_repeatable_clause\n   : REPEATABLE OPEN_PAREN a_expr CLOSE_PAREN\n   |\n   ;\n\nfunc_table\n   : func_expr_windowless opt_ordinality\n   | ROWS FROM OPEN_PAREN rowsfrom_list CLOSE_PAREN opt_ordinality\n   ;\n\nrowsfrom_item\n   : func_expr_windowless opt_col_def_list\n   ;\n\nrowsfrom_list\n   : rowsfrom_item (COMMA rowsfrom_item)*\n   ;\n\nopt_col_def_list\n   : AS OPEN_PAREN tablefuncelementlist CLOSE_PAREN\n   |\n   ;\n   //TODO WITH_LA was used\n\nopt_ordinality\n   : WITH ORDINALITY\n   |\n   ;\n\nwhere_clause\n   : WHERE a_expr\n   |\n   ;\n\nwhere_or_current_clause\n   : WHERE (CURRENT_P OF cursor_name | a_expr)\n   |\n   ;\n\nopttablefuncelementlist\n   : tablefuncelementlist\n   |\n   ;\n\ntablefuncelementlist\n   : tablefuncelement (COMMA tablefuncelement)*\n   ;\n\ntablefuncelement\n   : colid typename opt_collate_clause\n   ;\n\nxmltable\n   : XMLTABLE OPEN_PAREN (c_expr xmlexists_argument COLUMNS xmltable_column_list | XMLNAMESPACES OPEN_PAREN xml_namespace_list CLOSE_PAREN COMMA c_expr xmlexists_argument COLUMNS xmltable_column_list) CLOSE_PAREN\n   ;\n\nxmltable_column_list\n   : xmltable_column_el (COMMA xmltable_column_el)*\n   ;\n\nxmltable_column_el\n   : colid (typename xmltable_column_option_list? | FOR ORDINALITY)\n   ;\n\nxmltable_column_option_list\n   : xmltable_column_option_el+\n   ;\n\nxmltable_column_option_el\n   : DEFAULT a_expr\n   | identifier a_expr\n   | NOT NULL_P\n   | NULL_P\n   ;\n\nxml_namespace_list\n   : xml_namespace_el (COMMA xml_namespace_el)*\n   ;\n\nxml_namespace_el\n   : b_expr AS collabel\n   | DEFAULT b_expr\n   ;\n\ntypename\n   : SETOF? simpletypename (opt_array_bounds | ARRAY (OPEN_BRACKET iconst CLOSE_BRACKET)?)\n   | qualified_name PERCENT (ROWTYPE | TYPE_P)\n   ;\n\nopt_array_bounds\n   : (OPEN_BRACKET iconst? CLOSE_BRACKET)*\n   ;\n\nsimpletypename\n   : generictype\n   | numeric\n   | bit\n   | character\n   | constdatetime\n   | constinterval (opt_interval | OPEN_PAREN iconst CLOSE_PAREN)\n   ;\n\nconsttypename\n   : numeric\n   | constbit\n   | constcharacter\n   | constdatetime\n   ;\n\ngenerictype\n   : (builtin_function_name | type_function_name | LEFT | RIGHT) attrs? opt_type_modifiers\n   ;\n\nopt_type_modifiers\n   : OPEN_PAREN expr_list CLOSE_PAREN\n   |\n   ;\n\nnumeric\n   : INT_P\n   | INTEGER\n   | SMALLINT\n   | BIGINT\n   | REAL\n   | FLOAT_P opt_float\n   | DOUBLE_P PRECISION\n   | DECIMAL_P opt_type_modifiers\n   | DEC opt_type_modifiers\n   | NUMERIC opt_type_modifiers\n   | BOOLEAN_P\n   ;\n\nopt_float\n   : OPEN_PAREN iconst CLOSE_PAREN\n   |\n   ;\n   //todo: merge alts\n\nbit\n   : bitwithlength\n   | bitwithoutlength\n   ;\n\nconstbit\n   : bitwithlength\n   | bitwithoutlength\n   ;\n\nbitwithlength\n   : BIT opt_varying OPEN_PAREN expr_list CLOSE_PAREN\n   ;\n\nbitwithoutlength\n   : BIT opt_varying\n   ;\n\ncharacter\n   : character_c (OPEN_PAREN iconst CLOSE_PAREN)?\n   ;\n\nconstcharacter\n   : character_c (OPEN_PAREN iconst CLOSE_PAREN)?\n   ;\n\ncharacter_c\n   : (CHARACTER | CHAR_P | NCHAR) opt_varying\n   | VARCHAR\n   | NATIONAL (CHARACTER | CHAR_P) opt_varying\n   ;\n\nopt_varying\n   : VARYING\n   |\n   ;\n\nconstdatetime\n   : (TIMESTAMP | TIME) (OPEN_PAREN iconst CLOSE_PAREN)? opt_timezone\n   ;\n\nconstinterval\n   : INTERVAL\n   ;\n   //TODO with_la was used\n\nopt_timezone\n   : WITH TIME ZONE\n   | WITHOUT TIME ZONE\n   |\n   ;\n\nopt_interval\n   : YEAR_P\n   | MONTH_P\n   | DAY_P\n   | HOUR_P\n   | MINUTE_P\n   | interval_second\n   | YEAR_P TO MONTH_P\n   | DAY_P TO (HOUR_P | MINUTE_P | interval_second)\n   | HOUR_P TO (MINUTE_P | interval_second)\n   | MINUTE_P TO interval_second\n   |\n   ;\n\ninterval_second\n   : SECOND_P (OPEN_PAREN iconst CLOSE_PAREN)?\n   ;\n\nopt_escape\n   : ESCAPE a_expr\n   |\n   ;\n   //precendence accroding to Table 4.2. Operator Precedence (highest to lowest)\n\n   //https://www.postgresql.org/docs/12/sql-syntax-lexical.html#SQL-PRECEDENCE\n\n/*\noriginal version of a_expr, for info\n a_expr: c_expr\n        //::\tleft\tPostgreSQL-style typecast\n       | a_expr TYPECAST typename -- 1\n       | a_expr COLLATE any_name -- 2\n       | a_expr AT TIME ZONE a_expr-- 3\n       //right\tunary plus, unary minus\n       | (PLUS| MINUS) a_expr -- 4\n        //left\texponentiation\n       | a_expr CARET a_expr -- 5\n        //left\tmultiplication, division, modulo\n       | a_expr (STAR | SLASH | PERCENT) a_expr -- 6\n        //left\taddition, subtraction\n       | a_expr (PLUS | MINUS) a_expr -- 7\n        //left\tall other native and user-defined operators\n       | a_expr qual_op a_expr -- 8\n       | qual_op a_expr -- 9\n        //range containment, set membership, string matching BETWEEN IN LIKE ILIKE SIMILAR\n       | a_expr NOT? (LIKE|ILIKE|SIMILAR TO|(BETWEEN SYMMETRIC?)) a_expr opt_escape -- 10\n        //< > = <= >= <>\t \tcomparison operators\n       | a_expr (LT | GT | EQUAL | LESS_EQUALS | GREATER_EQUALS | NOT_EQUALS) a_expr -- 11\n       //IS ISNULL NOTNULL\t \tIS TRUE, IS FALSE, IS NULL, IS DISTINCT FROM, etc\n       | a_expr IS NOT?\n            (\n                NULL_P\n                |TRUE_P\n                |FALSE_P\n                |UNKNOWN\n                |DISTINCT FROM a_expr\n                |OF OPEN_PAREN type_list CLOSE_PAREN\n                |DOCUMENT_P\n                |unicode_normal_form? NORMALIZED\n            ) -- 12\n       | a_expr (ISNULL|NOTNULL) -- 13\n       | row OVERLAPS row -- 14\n       //NOT\tright\tlogical negation\n       | NOT a_expr -- 15\n        //AND\tleft\tlogical conjunction\n       | a_expr AND a_expr -- 16\n        //OR\tleft\tlogical disjunction\n       | a_expr OR a_expr -- 17\n       | a_expr (LESS_LESS|GREATER_GREATER) a_expr -- 18\n       | a_expr qual_op -- 19\n       | a_expr NOT? IN_P in_expr -- 20\n       | a_expr subquery_Op sub_type (select_with_parens|OPEN_PAREN a_expr CLOSE_PAREN) -- 21\n       | UNIQUE select_with_parens -- 22\n       | DEFAULT -- 23\n;\n*/\n\n\na_expr\n   : a_expr_qual\n   ;\n/*23*/\n\n\n/*moved to c_expr*/\n\n\n/*22*/\n\n\n/*moved to c_expr*/\n\n\n/*19*/\n\n\na_expr_qual\n   : a_expr_lessless qual_op?\n   ;\n/*18*/\n\n\na_expr_lessless\n   : a_expr_or ((LESS_LESS | GREATER_GREATER) a_expr_or)*\n   ;\n/*17*/\n\n\na_expr_or\n   : a_expr_and (OR a_expr_and)*\n   ;\n/*16*/\n\na_expr_and\n   : a_expr_between (AND a_expr_between)*\n   ;\n/*21*/\n\na_expr_between\n   : a_expr_in (NOT? BETWEEN SYMMETRIC? a_expr_in AND a_expr_in)?\n   ;\n/*20*/\n\n\na_expr_in\n   : a_expr_unary_not (NOT? IN_P in_expr)?\n   ;\n/*15*/\n\n\na_expr_unary_not\n   : NOT? a_expr_isnull\n   ;\n/*14*/\n\n\n/*moved to c_expr*/\n\n\n/*13*/\n\n\na_expr_isnull\n   : a_expr_is_not (ISNULL | NOTNULL)?\n   ;\n/*12*/\n\n\na_expr_is_not\n   : a_expr_compare (IS NOT? (NULL_P | TRUE_P | FALSE_P | UNKNOWN | DISTINCT FROM a_expr | OF OPEN_PAREN type_list CLOSE_PAREN | DOCUMENT_P | unicode_normal_form? NORMALIZED))?\n   ;\n/*11*/\n\n\na_expr_compare\n   : a_expr_like ((LT | GT | EQUAL | LESS_EQUALS | GREATER_EQUALS | NOT_EQUALS) a_expr_like |subquery_Op sub_type (select_with_parens | OPEN_PAREN a_expr CLOSE_PAREN) /*21*/\n\n   )?\n   ;\n/*10*/\n\n\na_expr_like\n   : a_expr_qual_op (NOT? (LIKE | ILIKE | SIMILAR TO) a_expr_qual_op opt_escape)?\n   ;\n/* 8*/\n\n\na_expr_qual_op\n   : a_expr_unary_qualop (qual_op a_expr_unary_qualop)*\n   ;\n/* 9*/\n\n\na_expr_unary_qualop\n   : qual_op? a_expr_add\n   ;\n/* 7*/\n\n\na_expr_add\n   : a_expr_mul ((MINUS | PLUS) a_expr_mul)*\n   ;\n/* 6*/\n\n\na_expr_mul\n   : a_expr_caret ((STAR | SLASH | PERCENT) a_expr_caret)*\n   ;\n/* 5*/\n\n\na_expr_caret\n   : a_expr_unary_sign (CARET a_expr)?\n   ;\n/* 4*/\n\n\na_expr_unary_sign\n   : (MINUS | PLUS)? a_expr_at_time_zone /* */\n\n\n   ;\n/* 3*/\n\n\na_expr_at_time_zone\n   : a_expr_collate (AT TIME ZONE a_expr)?\n   ;\n/* 2*/\n\n\na_expr_collate\n   : a_expr_typecast (COLLATE any_name)?\n   ;\n/* 1*/\n\n\na_expr_typecast\n   : c_expr (TYPECAST typename)*\n   ;\n\nb_expr\n   : c_expr\n   | b_expr TYPECAST typename\n   //right\tunary plus, unary minus\n   | (PLUS | MINUS) b_expr\n   //^\tleft\texponentiation\n   | b_expr CARET b_expr\n   //* / %\tleft\tmultiplication, division, modulo\n   | b_expr (STAR | SLASH | PERCENT) b_expr\n   //+ -\tleft\taddition, subtraction\n   | b_expr (PLUS | MINUS) b_expr\n   //(any other operator)\tleft\tall other native and user-defined operators\n   | b_expr qual_op b_expr\n   //< > = <= >= <>\t \tcomparison operators\n   | b_expr (LT | GT | EQUAL | LESS_EQUALS | GREATER_EQUALS | NOT_EQUALS) b_expr\n   | qual_op b_expr\n   | b_expr qual_op\n   //S ISNULL NOTNULL\t \tIS TRUE, IS FALSE, IS NULL, IS DISTINCT FROM, etc\n   | b_expr IS NOT? (DISTINCT FROM b_expr | OF OPEN_PAREN type_list CLOSE_PAREN | DOCUMENT_P)\n   ;\n\nc_expr\n   : EXISTS select_with_parens # c_expr_exists\n   | ARRAY (select_with_parens | array_expr) # c_expr_expr\n   | PARAM opt_indirection # c_expr_expr\n   | GROUPING OPEN_PAREN expr_list CLOSE_PAREN # c_expr_expr\n   | /*22*/\n\n   UNIQUE select_with_parens # c_expr_expr\n   | columnref # c_expr_expr\n   | aexprconst # c_expr_expr\n   | plsqlvariablename # c_expr_expr\n   | OPEN_PAREN a_expr_in_parens = a_expr CLOSE_PAREN opt_indirection # c_expr_expr\n   | case_expr # c_expr_case\n   | func_expr # c_expr_expr\n   | select_with_parens indirection? # c_expr_expr\n   | explicit_row # c_expr_expr\n   | implicit_row # c_expr_expr\n   | row OVERLAPS row /* 14*/\n\n   # c_expr_expr\n   ;\n\nplsqlvariablename\n   : PLSQLVARIABLENAME\n   ;\n\nfunc_application\n   : func_name OPEN_PAREN (func_arg_list (COMMA VARIADIC func_arg_expr)? opt_sort_clause | VARIADIC func_arg_expr opt_sort_clause | (ALL | DISTINCT) func_arg_list opt_sort_clause | STAR |) CLOSE_PAREN\n   ;\n\nfunc_expr\n   : func_application within_group_clause filter_clause over_clause\n   | func_expr_common_subexpr\n   ;\n\nfunc_expr_windowless\n   : func_application\n   | func_expr_common_subexpr\n   ;\n\nfunc_expr_common_subexpr\n   : COLLATION FOR OPEN_PAREN a_expr CLOSE_PAREN\n   | CURRENT_DATE\n   | CURRENT_TIME (OPEN_PAREN iconst CLOSE_PAREN)?\n   | CURRENT_TIMESTAMP (OPEN_PAREN iconst CLOSE_PAREN)?\n   | LOCALTIME (OPEN_PAREN iconst CLOSE_PAREN)?\n   | LOCALTIMESTAMP (OPEN_PAREN iconst CLOSE_PAREN)?\n   | CURRENT_ROLE\n   | CURRENT_USER\n   | SESSION_USER\n   | USER\n   | CURRENT_CATALOG\n   | CURRENT_SCHEMA\n   | CAST OPEN_PAREN a_expr AS typename CLOSE_PAREN\n   | EXTRACT OPEN_PAREN extract_list CLOSE_PAREN\n   | NORMALIZE OPEN_PAREN a_expr (COMMA unicode_normal_form)? CLOSE_PAREN\n   | OVERLAY OPEN_PAREN overlay_list CLOSE_PAREN\n   | POSITION OPEN_PAREN position_list CLOSE_PAREN\n   | SUBSTRING OPEN_PAREN substr_list CLOSE_PAREN\n   | TREAT OPEN_PAREN a_expr AS typename CLOSE_PAREN\n   | TRIM OPEN_PAREN (BOTH | LEADING | TRAILING)? trim_list CLOSE_PAREN\n   | NULLIF OPEN_PAREN a_expr COMMA a_expr CLOSE_PAREN\n   | COALESCE OPEN_PAREN expr_list CLOSE_PAREN\n   | GREATEST OPEN_PAREN expr_list CLOSE_PAREN\n   | LEAST OPEN_PAREN expr_list CLOSE_PAREN\n   | XMLCONCAT OPEN_PAREN expr_list CLOSE_PAREN\n   | XMLELEMENT OPEN_PAREN NAME_P collabel (COMMA (xml_attributes | expr_list))? CLOSE_PAREN\n   | XMLEXISTS OPEN_PAREN c_expr xmlexists_argument CLOSE_PAREN\n   | XMLFOREST OPEN_PAREN xml_attribute_list CLOSE_PAREN\n   | XMLPARSE OPEN_PAREN document_or_content a_expr xml_whitespace_option CLOSE_PAREN\n   | XMLPI OPEN_PAREN NAME_P collabel (COMMA a_expr)? CLOSE_PAREN\n   | XMLROOT OPEN_PAREN XML_P a_expr COMMA xml_root_version opt_xml_root_standalone CLOSE_PAREN\n   | XMLSERIALIZE OPEN_PAREN document_or_content a_expr AS simpletypename CLOSE_PAREN\n   ;\n\nxml_root_version\n   : VERSION_P a_expr\n   | VERSION_P NO VALUE_P\n   ;\n\nopt_xml_root_standalone\n   : COMMA STANDALONE_P YES_P\n   | COMMA STANDALONE_P NO\n   | COMMA STANDALONE_P NO VALUE_P\n   |\n   ;\n\nxml_attributes\n   : XMLATTRIBUTES OPEN_PAREN xml_attribute_list CLOSE_PAREN\n   ;\n\nxml_attribute_list\n   : xml_attribute_el (COMMA xml_attribute_el)*\n   ;\n\nxml_attribute_el\n   : a_expr (AS collabel)?\n   ;\n\ndocument_or_content\n   : DOCUMENT_P\n   | CONTENT_P\n   ;\n\nxml_whitespace_option\n   : PRESERVE WHITESPACE_P\n   | STRIP_P WHITESPACE_P\n   |\n   ;\n\nxmlexists_argument\n   : PASSING c_expr\n   | PASSING c_expr xml_passing_mech\n   | PASSING xml_passing_mech c_expr\n   | PASSING xml_passing_mech c_expr xml_passing_mech\n   ;\n\nxml_passing_mech\n   : BY (REF | VALUE_P)\n   ;\n\nwithin_group_clause\n   : WITHIN GROUP_P OPEN_PAREN sort_clause CLOSE_PAREN\n   |\n   ;\n\nfilter_clause\n   : FILTER OPEN_PAREN WHERE a_expr CLOSE_PAREN\n   |\n   ;\n\nwindow_clause\n   : WINDOW window_definition_list\n   |\n   ;\n\nwindow_definition_list\n   : window_definition (COMMA window_definition)*\n   ;\n\nwindow_definition\n   : colid AS window_specification\n   ;\n\nover_clause\n   : OVER (window_specification | colid)\n   |\n   ;\n\nwindow_specification\n   : OPEN_PAREN opt_existing_window_name opt_partition_clause opt_sort_clause opt_frame_clause CLOSE_PAREN\n   ;\n\nopt_existing_window_name\n   : colid\n   |\n   ;\n\nopt_partition_clause\n   : PARTITION BY expr_list\n   |\n   ;\n\nopt_frame_clause\n   : RANGE frame_extent opt_window_exclusion_clause\n   | ROWS frame_extent opt_window_exclusion_clause\n   | GROUPS frame_extent opt_window_exclusion_clause\n   |\n   ;\n\nframe_extent\n   : frame_bound\n   | BETWEEN frame_bound AND frame_bound\n   ;\n\nframe_bound\n   : UNBOUNDED (PRECEDING | FOLLOWING)\n   | CURRENT_P ROW\n   | a_expr (PRECEDING | FOLLOWING)\n   ;\n\nopt_window_exclusion_clause\n   : EXCLUDE (CURRENT_P ROW | GROUP_P | TIES | NO OTHERS)\n   |\n   ;\n\nrow\n   : ROW OPEN_PAREN expr_list? CLOSE_PAREN\n   | OPEN_PAREN expr_list COMMA a_expr CLOSE_PAREN\n   ;\n\nexplicit_row\n   : ROW OPEN_PAREN expr_list? CLOSE_PAREN\n   ;\n/*\nTODO:\nfor some reason v1\nimplicit_row: OPEN_PAREN expr_list COMMA a_expr CLOSE_PAREN;\nworks better than v2\nimplicit_row: OPEN_PAREN expr_list  CLOSE_PAREN;\nwhile looks like they are almost the same, except v2 requieres at least 2 items in list\nwhile v1 allows single item in list\n*/\n\n\nimplicit_row\n   : OPEN_PAREN expr_list COMMA a_expr CLOSE_PAREN\n   ;\n\nsub_type\n   : ANY\n   | SOME\n   | ALL\n   ;\n\nall_op\n   : Operator\n   | mathop\n   ;\n\nmathop\n   : PLUS\n   | MINUS\n   | STAR\n   | SLASH\n   | PERCENT\n   | CARET\n   | LT\n   | GT\n   | EQUAL\n   | LESS_EQUALS\n   | GREATER_EQUALS\n   | NOT_EQUALS\n   ;\n\nqual_op\n   : Operator\n   | OPERATOR OPEN_PAREN any_operator CLOSE_PAREN\n   ;\n\nqual_all_op\n   : all_op\n   | OPERATOR OPEN_PAREN any_operator CLOSE_PAREN\n   ;\n\nsubquery_Op\n   : all_op\n   | OPERATOR OPEN_PAREN any_operator CLOSE_PAREN\n   | LIKE\n   | NOT LIKE\n   | ILIKE\n   | NOT ILIKE\n   ;\n\nexpr_list\n   : a_expr (COMMA a_expr)*\n   ;\n\nfunc_arg_list\n   : func_arg_expr (COMMA func_arg_expr)*\n   ;\n\nfunc_arg_expr\n   : a_expr\n   | param_name (COLON_EQUALS | EQUALS_GREATER) a_expr\n   ;\n\ntype_list\n   : typename (COMMA typename)*\n   ;\n\narray_expr\n   : OPEN_BRACKET (expr_list | array_expr_list)? CLOSE_BRACKET\n   ;\n\narray_expr_list\n   : array_expr (COMMA array_expr)*\n   ;\n\nextract_list\n   : extract_arg FROM a_expr\n   |\n   ;\n\nextract_arg\n   : identifier\n   | YEAR_P\n   | MONTH_P\n   | DAY_P\n   | HOUR_P\n   | MINUTE_P\n   | SECOND_P\n   | sconst\n   ;\n\nunicode_normal_form\n   : NFC\n   | NFD\n   | NFKC\n   | NFKD\n   ;\n\noverlay_list\n   : a_expr PLACING a_expr FROM a_expr (FOR a_expr)?\n   ;\n\nposition_list\n   : b_expr IN_P b_expr\n   |\n   ;\n\nsubstr_list\n   : a_expr FROM a_expr FOR a_expr\n   | a_expr FOR a_expr FROM a_expr\n   | a_expr FROM a_expr\n   | a_expr FOR a_expr\n   | a_expr SIMILAR a_expr ESCAPE a_expr\n   | expr_list\n   ;\n\ntrim_list\n   : a_expr FROM expr_list\n   | FROM expr_list\n   | expr_list\n   ;\n\nin_expr\n   : select_with_parens # in_expr_select\n   | OPEN_PAREN expr_list CLOSE_PAREN # in_expr_list\n   ;\n\ncase_expr\n   : CASE case_arg when_clause_list case_default END_P\n   ;\n\nwhen_clause_list\n   : when_clause+\n   ;\n\nwhen_clause\n   : WHEN a_expr THEN a_expr\n   ;\n\ncase_default\n   : ELSE a_expr\n   |\n   ;\n\ncase_arg\n   : a_expr\n   |\n   ;\n\ncolumnref\n   : colid indirection?\n   ;\n\nindirection_el\n   : DOT (attr_name | STAR)\n   | OPEN_BRACKET (a_expr | opt_slice_bound COLON opt_slice_bound) CLOSE_BRACKET\n   ;\n\nopt_slice_bound\n   : a_expr\n   |\n   ;\n\nindirection\n   : indirection_el+\n   ;\n\nopt_indirection\n   : indirection_el*\n   ;\n\nopt_target_list\n   : target_list\n   |\n   ;\n\ntarget_list\n   : target_el (COMMA target_el)*\n   ;\n\ntarget_el\n   : a_expr (AS collabel | identifier |) # target_label\n   | STAR # target_star\n   ;\n\nqualified_name_list\n   : qualified_name (COMMA qualified_name)*\n   ;\n\nqualified_name\n   : colid indirection?\n   ;\n\nname_list\n   : name (COMMA name)*\n   ;\n\nname\n   : colid\n   ;\n\nattr_name\n   : collabel\n   ;\n\nfile_name\n   : sconst\n   ;\n\nfunc_name\n   : builtin_function_name\n   | type_function_name\n   | colid indirection\n   | LEFT\n   | RIGHT\n   ;\n\naexprconst\n   : iconst\n   | fconst\n   | sconst\n   | bconst\n   | xconst\n   | func_name (sconst | OPEN_PAREN func_arg_list opt_sort_clause CLOSE_PAREN sconst)\n   | consttypename sconst\n   | constinterval (sconst opt_interval | OPEN_PAREN iconst CLOSE_PAREN sconst)\n   | TRUE_P\n   | FALSE_P\n   | NULL_P\n   ;\n\nxconst\n   : HexadecimalStringConstant\n   ;\n\nbconst\n   : BinaryStringConstant\n   ;\n\nfconst\n   : Numeric\n   ;\n\niconst\n   : Integral\n   ;\n\nsconst\n   : anysconst opt_uescape\n   ;\n\nanysconst\n   : StringConstant\n   | UnicodeEscapeStringConstant\n   | BeginDollarStringConstant DollarText* EndDollarStringConstant\n   | EscapeStringConstant\n   ;\n\nopt_uescape\n   : UESCAPE anysconst\n   |\n   ;\n\nsignediconst\n   : iconst\n   | PLUS iconst\n   | MINUS iconst\n   ;\n\nroleid\n   : rolespec\n   ;\n\nrolespec\n   : nonreservedword\n   | CURRENT_USER\n   | SESSION_USER\n   ;\n\nrole_list\n   : rolespec (COMMA rolespec)*\n   ;\n\ncolid\n   : identifier\n   | unreserved_keyword\n   | col_name_keyword\n   | plsql_unreserved_keyword\n   | LEFT\n   | RIGHT\n   ;\n\ntable_alias\n   : identifier\n   | unreserved_keyword\n   | col_name_keyword\n   | plsql_unreserved_keyword\n   ;\n\n\ntype_function_name\n   : identifier\n   | unreserved_keyword\n   | plsql_unreserved_keyword\n   | type_func_name_keyword\n   ;\n\nnonreservedword\n   : identifier\n   | unreserved_keyword\n   | col_name_keyword\n   | type_func_name_keyword\n   ;\n\ncollabel\n   : identifier\n   | plsql_unreserved_keyword\n   | unreserved_keyword\n   | col_name_keyword\n   | type_func_name_keyword\n   | reserved_keyword\n   ;\n\nidentifier\n   : Identifier opt_uescape\n   | QuotedIdentifier\n   | UnicodeQuotedIdentifier\n   | plsqlvariablename\n   | plsqlidentifier\n   | plsql_unreserved_keyword\n   ;\n\nplsqlidentifier\n   : PLSQLIDENTIFIER\n   ;\n\nunreserved_keyword\n   : ABORT_P\n   | ABSOLUTE_P\n   | ACCESS\n   | ACTION\n   | ADD_P\n   | ADMIN\n   | AFTER\n   | AGGREGATE\n   | ALSO\n   | ALTER\n   | ALWAYS\n   | ASSERTION\n   | ASSIGNMENT\n   | AT\n   | ATTACH\n   | ATTRIBUTE\n   | BACKWARD\n   | BEFORE\n   | BEGIN_P\n   | BY\n   | CACHE\n   | CALL\n   | CALLED\n   | CASCADE\n   | CASCADED\n   | CATALOG\n   | CHAIN\n   | CHARACTERISTICS\n   | CHECKPOINT\n   | CLASS\n   | CLOSE\n   | CLUSTER\n   | COLUMNS\n   | COMMENT\n   | COMMENTS\n   | COMMIT\n   | COMMITTED\n   | CONFIGURATION\n   | CONFLICT\n   | CONNECTION\n   | CONSTRAINTS\n   | CONTENT_P\n   | CONTINUE_P\n   | CONVERSION_P\n   | COPY\n   | COST\n   | CSV\n   | CUBE\n   | CURRENT_P\n   | CURSOR\n   | CYCLE\n   | DATA_P\n   | DATABASE\n   | DAY_P\n   | DEALLOCATE\n   | DECLARE\n   | DEFAULTS\n   | DEFERRED\n   | DEFINER\n   | DELETE_P\n   | DELIMITER\n   | DELIMITERS\n   | DEPENDS\n   | DETACH\n   | DICTIONARY\n   | DISABLE_P\n   | DISCARD\n   | DOCUMENT_P\n   | DOMAIN_P\n   | DOUBLE_P\n   | DROP\n   | EACH\n   | ENABLE_P\n   | ENCODING\n   | ENCRYPTED\n   | ENUM_P\n   | ESCAPE\n   | EVENT\n   | EXCLUDE\n   | EXCLUDING\n   | EXCLUSIVE\n   | EXECUTE\n   | EXPLAIN\n   | EXPRESSION\n   | EXTENSION\n   | EXTERNAL\n   | FAMILY\n   | FILTER\n   | FIRST_P\n   | FOLLOWING\n   | FORCE\n   | FORWARD\n   | FUNCTION\n   | FUNCTIONS\n   | GENERATED\n   | GLOBAL\n   | GRANTED\n   | GROUPS\n   | HANDLER\n   | HEADER_P\n   | HOLD\n   | HOUR_P\n   | IDENTITY_P\n   | IF_P\n   | IMMEDIATE\n   | IMMUTABLE\n   | IMPLICIT_P\n   | IMPORT_P\n   | INCLUDE\n   | INCLUDING\n   | INCREMENT\n   | INDEX\n   | INDEXES\n   | INHERIT\n   | INHERITS\n   | INLINE_P\n   | INPUT_P\n   | INSENSITIVE\n   | INSERT\n   | INSTEAD\n   | INVOKER\n   | ISOLATION\n   | KEY\n   | LABEL\n   | LANGUAGE\n   | LARGE_P\n   | LAST_P\n   | LEAKPROOF\n   | SHIPPABLE\n   | FENCED\n   | PACKAGE\n   | LEVEL\n   | LISTEN\n   | LOAD\n   | LOCAL\n   | LOCATION\n   | LOCK_P\n   | LOCKED\n   | LOGGED\n   | MAPPING\n   | MATCH\n   | MATERIALIZED\n   | MAXVALUE\n   | METHOD\n   | MINUTE_P\n   | MINVALUE\n   | MODE\n   | MONTH_P\n   | MOVE\n   | NAME_P\n   | NAMES\n   | NEW\n   | NEXT\n   | NFC\n   | NFD\n   | NFKC\n   | NFKD\n   | NO\n   | NORMALIZED\n   | NOTHING\n   | NOTIFY\n   | NOWAIT\n   | NULLS_P\n   | OBJECT_P\n   | OF\n   | OFF\n   | OIDS\n   | OLD\n   | OPERATOR\n   | OPTION\n   | OPTIONS\n   | ORDINALITY\n   | OTHERS\n   | OVER\n   | OVERRIDING\n   | OWNED\n   | OWNER\n   | PARALLEL\n   | PARSER\n   | PARTIAL\n   | PARTITION\n   | PASSING\n   | PASSWORD\n   | PLANS\n   | POLICY\n   | PRECEDING\n   | PREPARE\n   | PREPARED\n   | PRESERVE\n   | PRIOR\n   | PRIVILEGES\n   | PROCEDURAL\n   | PROCEDURE\n   | PROCEDURES\n   | PROGRAM\n   | PUBLICATION\n   | QUOTE\n   | RANGE\n   | READ\n   | REASSIGN\n   | RECHECK\n   | RECURSIVE\n   | REF\n   | REFERENCING\n   | REFRESH\n   | REINDEX\n   | RELATIVE_P\n   | RELEASE\n   | RENAME\n   | REPEATABLE\n   | REPLICA\n   | RESET\n   | RESTART\n   | RESTRICT\n   | RETURNS\n   | REVOKE\n   | ROLE\n   | ROLLBACK\n   | ROLLUP\n   | ROUTINE\n   | ROUTINES\n   | ROWS\n   | RULE\n   | SAVEPOINT\n   | SCHEMA\n   | SCHEMAS\n   | SCROLL\n   | SEARCH\n   | SECOND_P\n   | SECURITY\n   | SEQUENCE\n   | SEQUENCES\n   | SERIALIZABLE\n   | SERVER\n   | SESSION\n   | SET\n   | SETS\n   | SHARE\n   | SHOW\n   | SIMPLE\n   | SKIP_P\n   | SNAPSHOT\n   | SQL_P\n   | STABLE\n   | STANDALONE_P\n   | START\n   | STATEMENT\n   | STATISTICS\n   | STDIN\n   | STDOUT\n   | STORAGE\n   | STORED\n   | STRICT_P\n   | STRIP_P\n   | SUBSCRIPTION\n   | SUPPORT\n   | SYSID\n   | SYSTEM_P\n   | TABLES\n   | TABLESPACE\n   | TEMP\n   | TEMPLATE\n   | TEMPORARY\n   | TEXT_P\n   | TIES\n   | TRANSACTION\n   | TRANSFORM\n   | TRIGGER\n   | TRUNCATE\n   | TRUSTED\n   | TYPE_P\n   | TYPES_P\n   | UESCAPE\n   | UNBOUNDED\n   | UNCOMMITTED\n   | UNENCRYPTED\n   | UNKNOWN\n   | UNLISTEN\n   | UNLOGGED\n   | UNTIL\n   | UPDATE\n   | VACUUM\n   | VALID\n   | VALIDATE\n   | VALIDATOR\n   | VALUE_P\n   | VARYING\n   | VERSION_P\n   | VIEW\n   | VIEWS\n   | VOLATILE\n   | WHITESPACE_P\n   | WITHIN\n   | WITHOUT\n   | WORK\n   | WRAPPER\n   | WRITE\n   | XML_P\n   | YEAR_P\n   | YES_P\n   | ZONE\n   ;\n\ncol_name_keyword\n   : BETWEEN\n   | BIGINT\n   | bit\n   | BOOLEAN_P\n   | CHAR_P\n   | character\n   | COALESCE\n   | DEC\n   | DECIMAL_P\n   | EXISTS\n   | EXTRACT\n   | FLOAT_P\n   | GREATEST\n   | GROUPING\n   | INOUT\n   | INT_P\n   | INTEGER\n   | INTERVAL\n   | LEAST\n   | NATIONAL\n   | NCHAR\n   | NONE\n   | NORMALIZE\n   | NULLIF\n   | numeric\n   | OUT_P\n   | OVERLAY\n   | POSITION\n   | PRECISION\n   | REAL\n   | ROW\n   | SETOF\n   | SMALLINT\n   | SUBSTRING\n   | TIME\n   | TIMESTAMP\n   | TREAT\n   | TRIM\n   | VALUES\n   | VARCHAR\n   | XMLATTRIBUTES\n   | XMLCONCAT\n   | XMLELEMENT\n   | XMLEXISTS\n   | XMLFOREST\n   | XMLNAMESPACES\n   | XMLPARSE\n   | XMLPI\n   | XMLROOT\n   | XMLSERIALIZE\n   | XMLTABLE\n   | builtin_function_name\n   ;\n\ntype_func_name_keyword\n   : AUTHORIZATION\n   | BINARY\n   | COLLATION\n   | CONCURRENTLY\n   | CROSS\n   | CURRENT_SCHEMA\n   | FREEZE\n   | FULL\n   | ILIKE\n   | INNER_P\n   | IS\n   | ISNULL\n   | JOIN\n   | LIKE\n   | NATURAL\n   | NOTNULL\n   | OUTER_P\n   | OVERLAPS\n   | SIMILAR\n   | TABLESAMPLE\n   | VERBOSE\n   ;\n\nreserved_keyword\n   : ALL\n   | ANALYSE\n   | ANALYZE\n   | AND\n   | ANY\n   | ARRAY\n   | AS\n   | ASC\n   | ASYMMETRIC\n   | BOTH\n   | CASE\n   | CAST\n   | CHECK\n   | COLLATE\n   | COLUMN\n   | CONSTRAINT\n   | CREATE\n   | CURRENT_CATALOG\n   | CURRENT_DATE\n   | CURRENT_ROLE\n   | CURRENT_TIME\n   | CURRENT_TIMESTAMP\n   | CURRENT_USER\n   //                 | DEFAULT\n   | DEFERRABLE\n   | DESC\n   | DISTINCT\n   | DO\n   | ELSE\n   | END_P\n   | EXCEPT\n   | FALSE_P\n   | FETCH\n   | FOR\n   | FOREIGN\n   | FROM\n   | GRANT\n   | GROUP_P\n   | HAVING\n   | IN_P\n   | INITIALLY\n   | INTERSECT\n/*\nfrom pl_gram.y, line ~2982\n\t * Fortunately, INTO is a fully reserved word in the main grammar, so\n\t * at least we need not worry about it appearing as an identifier.\n*/\n\n\n   //                 | INTO\n   | LATERAL_P\n   | LEADING\n   | LIMIT\n   | LOCALTIME\n   | LOCALTIMESTAMP\n   | NOT\n   | NULL_P\n   | OFFSET\n   | ON\n   | ONLY\n   | OR\n   | ORDER\n   | PLACING\n   | PRIMARY\n   | REFERENCES\n   | RETURNING\n   | SELECT\n   | SESSION_USER\n   | SOME\n   | SYMMETRIC\n   | TABLE\n   | THEN\n   | TO\n   | TRAILING\n   | TRUE_P\n   | UNION\n   | UNIQUE\n   | USER\n   | USING\n   | VARIADIC\n   | WHEN\n   | WHERE\n   | WINDOW\n   | WITH\n   ;\n\nbuiltin_function_name\n   : XMLCOMMENT\n   | XML_IS_WELL_FORMED\n   | XML_IS_WELL_FORMED_DOCUMENT\n   | XML_IS_WELL_FORMED_CONTENT\n   | XMLAGG\n   | XPATH\n   | XPATH_EXISTS\n   | ABS\n   | CBRT\n   | CEIL\n   | CEILING\n   | DEGREES\n   | DIV\n   | EXP\n   | FACTORIAL\n   | FLOOR\n   | GCD\n   | LCM\n   | LN\n   | LOG\n   | LOG10\n   | MIN_SCALE\n   | MOD\n   | PI\n   | POWER\n   | RADIANS\n   | ROUND\n   | SCALE\n   | SIGN\n   | SQRT\n   | TRIM_SCALE\n   | TRUNC\n   | WIDTH_BUCKET\n   | RANDOM\n   | SETSEED\n   | ACOS\n   | ACOSD\n   | ACOSH\n   | ASIN\n   | ASIND\n   | ASINH\n   | ATAN\n   | ATAND\n   | ATANH\n   | ATAN2\n   | ATAN2D\n   | COS\n   | COSD\n   | COSH\n   | COT\n   | COTD\n   | SIN\n   | SIND\n   | SINH\n   | TAN\n   | TAND\n   | TANH\n   | BIT_LENGTH\n   | CHAR_LENGTH\n   | CHARACTER_LENGTH\n   | LOWER\n   | OCTET_LENGTH\n   | OCTET_LENGTH\n   | UPPER\n   | ASCII\n   | BTRIM\n   | CHR\n   | CONCAT\n   | CONCAT_WS\n   | FORMAT\n   | INITCAP\n   | LENGTH\n   | LPAD\n   | LTRIM\n   | MD5\n   | PARSE_IDENT\n   | PG_CLIENT_ENCODING\n   | QUOTE_IDENT\n   | QUOTE_LITERAL\n   | QUOTE_NULLABLE\n   | REGEXP_COUNT\n   | REGEXP_INSTR\n   | REGEXP_LIKE\n   | REGEXP_MATCH\n   | REGEXP_MATCHES\n   | REGEXP_REPLACE\n   | REGEXP_SPLIT_TO_ARRAY\n   | REGEXP_SPLIT_TO_TABLE\n   | REGEXP_SUBSTR\n   | REPEAT\n   | REPLACE\n   | REVERSE\n   | RPAD\n   | RTRIM\n   | SPLIT_PART\n   | STARTS_WITH\n   | STRING_TO_ARRAY\n   | STRING_TO_TABLE\n   | STRPOS\n   | SUBSTR\n   | TO_ASCII\n   | TO_HEX\n   | TRANSLATE\n   | UNISTR\n   | AGE\n   | DATE_BIN\n   | DATE_PART\n   | DATE_TRUNC\n   | ISFINITE\n   | JUSTIFY_DAYS\n   | JUSTIFY_HOURS\n   | JUSTIFY_INTERVAL\n   | MAKE_DATE\n   | MAKE_INTERVAL\n   | MAKE_TIME\n   | MAKE_TIMESTAMP\n   | MAKE_TIMESTAMPTZ\n   | CLOCK_TIMESTAMP\n   | NOW\n   | STATEMENT_TIMESTAMP\n   | TIMEOFDAY\n   | TRANSACTION_TIMESTAMP\n   | TO_TIMESTAMP\n   | JUSTIFY_INTERVAL\n   | JUSTIFY_INTERVAL\n   | TO_CHAR\n   | TO_DATE\n   | TO_NUMBER\n   ;\n\n/************************************************************************************************************************************************************/\n/*PL/SQL GRAMMAR */\n\n\n/*PLSQL grammar */\n\n/************************************************************************************************************************************************************/\npl_function\n   : comp_options pl_block opt_semi\n   ;\n\ncomp_options\n   : comp_option*\n   ;\n\ncomp_option\n   : sharp OPTION DUMP\n   | sharp PRINT_STRICT_PARAMS option_value\n   | sharp VARIABLE_CONFLICT ERROR\n   | sharp VARIABLE_CONFLICT USE_VARIABLE\n   | sharp VARIABLE_CONFLICT USE_COLUMN\n   ;\n\nsharp\n   : Operator\n   ;\n\noption_value\n   : sconst\n   | reserved_keyword\n   | plsql_unreserved_keyword\n   | unreserved_keyword\n   ;\n\nopt_semi\n   :\n   | SEMI\n   ;\n   // exception_sect means opt_exception_sect in original grammar, don't be confused!\n\npl_block\n   : decl_sect BEGIN_P proc_sect exception_sect END_P opt_label\n   ;\n\ndecl_sect\n   : opt_block_label (decl_start decl_stmts?)?\n   ;\n\ndecl_start\n   : DECLARE\n   ;\n\ndecl_stmts\n   : decl_stmt+\n   ;\n\nlabel_decl\n   : LESS_LESS any_identifier GREATER_GREATER\n   ;\n\ndecl_stmt\n   : decl_statement\n   | DECLARE\n   | label_decl\n   ;\n\ndecl_statement\n   : decl_varname\n     (\n          ALIAS FOR decl_aliasitem\n        | decl_const decl_datatype decl_collate decl_notnull decl_defval\n        | opt_scrollable CURSOR decl_cursor_args decl_is_for decl_cursor_query\n     ) SEMI\n   ;\n\nopt_scrollable\n   :\n   | NO SCROLL\n   | SCROLL\n   ;\n\ndecl_cursor_query\n   : selectstmt\n   ;\n\ndecl_cursor_args\n   :\n   | OPEN_PAREN decl_cursor_arglist CLOSE_PAREN\n   ;\n\ndecl_cursor_arglist\n   : decl_cursor_arg (COMMA decl_cursor_arg)*\n   ;\n\ndecl_cursor_arg\n   : decl_varname decl_datatype\n   ;\n\ndecl_is_for\n   : IS\n   | FOR\n   ;\n\ndecl_aliasitem\n   : PARAM\n   | colid\n   ;\n\ndecl_varname\n   : any_identifier\n   ;\n\ndecl_const\n   :\n   | CONSTANT\n   ;\n\ndecl_datatype\n   : typename\n   ; //TODO: $$ = read_datatype(yychar);\n\ndecl_collate\n   :\n   | COLLATE any_name\n   ;\n\ndecl_notnull\n   :\n   | NOT NULL_P\n   ;\n\ndecl_defval\n   :\n   | decl_defkey sql_expression\n   ;\n\ndecl_defkey\n   : assign_operator\n   | DEFAULT\n   ;\n\nassign_operator\n   : EQUAL\n   | COLON_EQUALS\n   ;\n\nproc_sect\n   : proc_stmt*\n   ;\n\nproc_stmt\n   : pl_block SEMI\n   | stmt_return\n   | stmt_raise\n   | stmt_assign\n   | stmt_if\n   | stmt_case\n   | stmt_loop\n   | stmt_while\n   | stmt_for\n   | stmt_foreach_a\n   | stmt_exit\n   | stmt_assert\n   | stmt_execsql\n   | stmt_dynexecute\n   | stmt_perform\n   | stmt_call\n   | stmt_getdiag\n   | stmt_open\n   | stmt_fetch\n   | stmt_move\n   | stmt_close\n   | stmt_null\n   | stmt_commit\n   | stmt_rollback\n   | stmt_set\n   ;\n\nstmt_perform\n   : PERFORM expr_until_semi SEMI\n   ;\n\nstmt_call\n   : CALL any_identifier OPEN_PAREN opt_expr_list CLOSE_PAREN SEMI\n   | DO any_identifier OPEN_PAREN opt_expr_list CLOSE_PAREN SEMI\n   ;\n\nopt_expr_list\n   :\n   | expr_list\n   ;\n\nstmt_assign\n   : assign_var assign_operator sql_expression SEMI\n   ;\n\nstmt_getdiag\n   : GET getdiag_area_opt DIAGNOSTICS getdiag_list SEMI\n   ;\n\ngetdiag_area_opt\n   :\n   | CURRENT_P\n   | STACKED\n   ;\n\ngetdiag_list\n   : getdiag_list_item (COMMA getdiag_list_item)*\n   ;\n\ngetdiag_list_item\n   : getdiag_target assign_operator getdiag_item\n   ;\n\ngetdiag_item\n   : colid\n   ;\n\ngetdiag_target\n   : assign_var\n   ;\n\nassign_var\n   : (any_name | PARAM) (OPEN_BRACKET expr_until_rightbracket CLOSE_BRACKET)*\n   ;\n\nstmt_if\n   : IF_P expr_until_then THEN proc_sect stmt_elsifs stmt_else END_P IF_P SEMI\n   ;\n\nstmt_elsifs\n   : (ELSIF a_expr THEN proc_sect)*\n   ;\n\nstmt_else\n   :\n   | ELSE proc_sect\n   ;\n\nstmt_case\n   : CASE opt_expr_until_when case_when_list opt_case_else END_P CASE SEMI\n   ;\n\nopt_expr_until_when\n   :\n   | sql_expression\n   ;\n\ncase_when_list\n   : case_when+\n   ;\n\ncase_when\n   : WHEN expr_list THEN proc_sect\n   ;\n\nopt_case_else\n   :\n   | ELSE proc_sect\n   ;\n\nstmt_loop\n   : opt_loop_label loop_body\n   ;\n\nstmt_while\n   : opt_loop_label WHILE expr_until_loop loop_body\n   ;\n\nstmt_for\n   : opt_loop_label FOR for_control loop_body\n   ;\n   //TODO: rewrite using read_sql_expression logic?\n\nfor_control\n   : for_variable IN_P\n     (\n          cursor_name opt_cursor_parameters\n        | selectstmt\n        | explainstmt\n        | EXECUTE a_expr opt_for_using_expression\n        | opt_reverse a_expr DOT_DOT a_expr opt_by_expression\n     )\n   ;\n\nopt_for_using_expression\n   :\n   | USING expr_list\n   ;\n\nopt_cursor_parameters\n   :\n   | OPEN_PAREN a_expr (COMMA a_expr)* CLOSE_PAREN\n   ;\n\nopt_reverse\n   :\n   | REVERSE\n   ;\n\nopt_by_expression\n   :\n   | BY a_expr\n   ;\n\nfor_variable\n   : any_name_list\n   ;\n\nstmt_foreach_a\n   : opt_loop_label FOREACH for_variable foreach_slice IN_P ARRAY a_expr loop_body\n   ;\n\nforeach_slice\n   :\n   | SLICE iconst\n   ;\n\nstmt_exit\n   : exit_type opt_label opt_exitcond SEMI\n   ;\n\nexit_type\n   : EXIT\n   | CONTINUE_P\n   ;\n   //todo implement RETURN statement according to initial grammar line 1754\n\nstmt_return\n   : RETURN (NEXT sql_expression | QUERY (EXECUTE a_expr opt_for_using_expression | selectstmt) | opt_return_result) SEMI\n   ;\n\nopt_return_result\n   :\n   | sql_expression\n   ;\n   //https://www.postgresql.org/docs/current/plpgsql-errors-and-messages.html\n\n   //RAISE [ level ] 'format' [, expression [, ... ]] [ USING option = expression [, ... ] ];\n\n   //RAISE [ level ] condition_name [ USING option = expression [, ... ] ];\n\n   //RAISE [ level ] SQLSTATE 'sqlstate' [ USING option = expression [, ... ] ];\n\n   //RAISE [ level ] USING option = expression [, ... ];\n\n   //RAISE ;\n\nstmt_raise\n   : RAISE opt_stmt_raise_level sconst opt_raise_list opt_raise_using SEMI\n   | RAISE opt_stmt_raise_level identifier opt_raise_using SEMI\n   | RAISE opt_stmt_raise_level SQLSTATE sconst opt_raise_using SEMI\n   | RAISE opt_stmt_raise_level opt_raise_using SEMI\n   | RAISE\n   ;\n\nopt_stmt_raise_level\n   :\n   |\n   | DEBUG\n   | LOG\n   | INFO\n   | NOTICE\n   | WARNING\n   | EXCEPTION\n   ;\n\nopt_raise_list\n   :\n   | (COMMA a_expr)+\n   ;\n\nopt_raise_using\n   :\n   | USING opt_raise_using_elem_list\n   ;\n\nopt_raise_using_elem\n   : identifier EQUAL a_expr\n   ;\n\nopt_raise_using_elem_list\n   : opt_raise_using_elem (COMMA opt_raise_using_elem)*\n   ;\n   //todo imnplement\n\nstmt_assert\n   : ASSERT sql_expression opt_stmt_assert_message SEMI\n   ;\n\nopt_stmt_assert_message\n   :\n   | COMMA sql_expression\n   ;\n\nloop_body\n   : LOOP proc_sect END_P LOOP opt_label SEMI\n   ;\n   //TODO: looks like all other statements like INSERT/SELECT/UPDATE/DELETE are handled here;\n\n   //pls take a look at original grammar\n\nstmt_execsql\n   : make_execsql_stmt SEMI\n/*K_IMPORT\n            | K_INSERT\n            | t_word\n            | t_cword\n*/\n\n\n   ;\n   //https://www.postgresql.org/docs/current/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-NORESULT\n\n   //EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];\n\nstmt_dynexecute\n   : EXECUTE a_expr (\n/*this is silly, but i have to time to find nice way to code */\n\n   opt_execute_into opt_execute_using | opt_execute_using opt_execute_into |) SEMI\n   ;\n\nopt_execute_using\n   :\n   | USING opt_execute_using_list\n   ;\n\nopt_execute_using_list\n   : a_expr (COMMA a_expr)*\n   ;\n\nopt_execute_into\n   :\n   | INTO STRICT_P? into_target\n   ;\n   //https://www.postgresql.org/docs/current/plpgsql-cursors.html#PLPGSQL-CURSOR-OPENING\n\n   //OPEN unbound_cursorvar [ [ NO ] SCROLL ] FOR query;\n\n   //OPEN unbound_cursorvar [ [ NO ] SCROLL ] FOR EXECUTE query_string\n\n   //                                     [ USING expression [, ... ] ];\n\n   //OPEN bound_cursorvar [ ( [ argument_name := ] argument_value [, ...] ) ];\n\nstmt_open\n   : OPEN\n     (\n          cursor_variable opt_scroll_option FOR (selectstmt | EXECUTE sql_expression opt_open_using)\n        | colid (OPEN_PAREN opt_open_bound_list CLOSE_PAREN)?\n     ) SEMI\n   ;\n\nopt_open_bound_list_item\n   : colid COLON_EQUALS a_expr\n   | a_expr\n   ;\n\nopt_open_bound_list\n   : opt_open_bound_list_item (COMMA opt_open_bound_list_item)*\n   ;\n\nopt_open_using\n   :\n   | USING expr_list\n   ;\n\nopt_scroll_option\n   :\n   | opt_scroll_option_no SCROLL\n   ;\n\nopt_scroll_option_no\n   :\n   | NO\n   ;\n   //https://www.postgresql.org/docs/current/plpgsql-cursors.html#PLPGSQL-CURSOR-OPENING\n\n   //FETCH [ direction { FROM | IN } ] cursor INTO target;\n\nstmt_fetch\n   : FETCH direction = opt_fetch_direction opt_cursor_from cursor_variable INTO into_target SEMI\n   ;\n\ninto_target\n   : expr_list\n   ;\n\nopt_cursor_from\n   :\n   | FROM\n   | IN_P\n   ;\n\nopt_fetch_direction\n   :\n   |\n   | NEXT\n   | PRIOR\n   | FIRST_P\n   | LAST_P\n   | ABSOLUTE_P a_expr\n   | RELATIVE_P a_expr\n   | a_expr\n   | ALL\n   | (FORWARD | BACKWARD) (a_expr | ALL)?\n   ;\n   //https://www.postgresql.org/docs/current/plpgsql-cursors.html#PLPGSQL-CURSOR-OPENING\n\n   //MOVE [ direction { FROM | IN } ] cursor;\n\nstmt_move\n   : MOVE opt_fetch_direction cursor_variable SEMI\n   ;\n\nstmt_close\n   : CLOSE cursor_variable SEMI\n   ;\n\nstmt_null\n   : NULL_P SEMI\n   ;\n\nstmt_commit\n   : COMMIT plsql_opt_transaction_chain SEMI\n   ;\n\nstmt_rollback\n   : ROLLBACK plsql_opt_transaction_chain SEMI\n   ;\n\nplsql_opt_transaction_chain\n   : AND NO? CHAIN\n   |\n   ;\n\nstmt_set\n   : SET any_name TO DEFAULT SEMI\n   | RESET (any_name | ALL) SEMI\n   ;\n\ncursor_variable\n   : colid\n   | PARAM\n   ;\n\nexception_sect\n   :\n   | EXCEPTION proc_exceptions\n   ;\n\nproc_exceptions\n   : proc_exception+\n   ;\n\nproc_exception\n   : WHEN proc_conditions THEN proc_sect\n   ;\n\nproc_conditions\n   : proc_condition (OR proc_condition)*\n   ;\n\nproc_condition\n   : any_identifier\n   | SQLSTATE sconst\n   ;\n   //expr_until_semi:\n\n   //;\n\n   //expr_until_rightbracket:\n\n   //;\n\n   //expr_until_loop:\n\n   //;\n\nopt_block_label\n   :\n   | label_decl\n   ;\n\nopt_loop_label\n   :\n   | label_decl\n   ;\n\nopt_label\n   :\n   | any_identifier\n   ;\n\nopt_exitcond\n   : WHEN expr_until_semi\n   |\n   ;\n\nany_identifier\n   : colid\n   | plsql_unreserved_keyword\n   ;\n\nplsql_unreserved_keyword\n   : ABSOLUTE_P\n   | ALIAS\n   | AND\n   | ARRAY\n   | ASSERT\n   | BACKWARD\n   | CALL\n   | CHAIN\n   | CLOSE\n   | COLLATE\n   | COLUMN\n   //| COLUMN_NAME\n   | COMMIT\n   | CONSTANT\n   | CONSTRAINT\n   //| CONSTRAINT_NAME\n   | CONTINUE_P\n   | CURRENT_P\n   | CURSOR\n   //| DATATYPE\n   | DEBUG\n   | DEFAULT\n   //| DETAIL\n   | DIAGNOSTICS\n   | DO\n   | DUMP\n   | ELSIF\n   //| ERRCODE\n   | ERROR\n   | EXCEPTION\n   | EXIT\n   | FETCH\n   | FIRST_P\n   | FORWARD\n   | GET\n   //| HINT\n\n   //| IMPORT\n   | INFO\n   | INSERT\n   | IS\n   | LAST_P\n   //| MESSAGE\n\n   //| MESSAGE_TEXT\n   | MOVE\n   | NEXT\n   | NO\n   | NOTICE\n   | OPEN\n   | OPTION\n   | PERFORM\n   //| PG_CONTEXT\n\n   //| PG_DATATYPE_NAME\n\n   //| PG_EXCEPTION_CONTEXT\n\n   //| PG_EXCEPTION_DETAIL\n\n   //| PG_EXCEPTION_HINT\n   | PRINT_STRICT_PARAMS\n   | PRIOR\n   | QUERY\n   | RAISE\n   | RELATIVE_P\n   | RESET\n   | RETURN\n   //| RETURNED_SQLSTATE\n   | ROLLBACK\n   //| ROW_COUNT\n   | ROWTYPE\n   | SCHEMA\n   //| SCHEMA_NAME\n   | SCROLL\n   | SET\n   | SLICE\n   | SQLSTATE\n   | STACKED\n   | TABLE\n   //| TABLE_NAME\n   | TYPE_P\n   | USE_COLUMN\n   | USE_VARIABLE\n   | VARIABLE_CONFLICT\n   | WARNING\n   | OUTER_P\n   ;\n\nsql_expression\n   : opt_target_list into_clause from_clause where_clause group_clause having_clause window_clause\n   ;\n\nexpr_until_then\n   : sql_expression\n   ;\n\nexpr_until_semi\n   : sql_expression\n   ;\n\nexpr_until_rightbracket\n   : a_expr\n   ;\n\nexpr_until_loop\n   : a_expr\n   ;\n\nmake_execsql_stmt\n   : stmt opt_returning_clause_into\n   ;\n\nopt_returning_clause_into\n   : INTO opt_strict into_target\n   |\n   ;"
  },
  {
    "path": "superior-postgres-parser/src/main/java/io/github/melin/superior/parser/postgre/antlr4/LexerDispatchingErrorListener.java",
    "content": "package io.github.melin.superior.parser.postgre.antlr4;\n\nimport java.util.BitSet;\nimport org.antlr.v4.runtime.*;\nimport org.antlr.v4.runtime.atn.*;\nimport org.antlr.v4.runtime.dfa.*;\n\npublic class LexerDispatchingErrorListener implements ANTLRErrorListener {\n    Lexer _parent;\n\n    public LexerDispatchingErrorListener(Lexer parent) {\n        _parent = parent;\n    }\n\n    public void syntaxError(\n            Recognizer<?, ?> recognizer,\n            Object offendingSymbol,\n            int line,\n            int charPositionInLine,\n            String msg,\n            RecognitionException e) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);\n    }\n\n    public void reportAmbiguity(\n            Parser recognizer,\n            DFA dfa,\n            int startIndex,\n            int stopIndex,\n            boolean exact,\n            BitSet ambigAlts,\n            ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs);\n    }\n\n    public void reportAttemptingFullContext(\n            Parser recognizer, DFA dfa, int startIndex, int stopIndex, BitSet conflictingAlts, ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs);\n    }\n\n    public void reportContextSensitivity(\n            Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs);\n    }\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/java/io/github/melin/superior/parser/postgre/antlr4/ParserDispatchingErrorListener.java",
    "content": "package io.github.melin.superior.parser.postgre.antlr4;\n\nimport java.util.BitSet;\nimport org.antlr.v4.runtime.*;\nimport org.antlr.v4.runtime.atn.*;\nimport org.antlr.v4.runtime.dfa.*;\n\npublic class ParserDispatchingErrorListener implements ANTLRErrorListener {\n    Parser _parent;\n\n    public ParserDispatchingErrorListener(Parser parent) {\n        _parent = parent;\n    }\n\n    public void syntaxError(\n            Recognizer<?, ?> recognizer,\n            Object offendingSymbol,\n            int line,\n            int charPositionInLine,\n            String msg,\n            RecognitionException e) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);\n    }\n\n    public void reportAmbiguity(\n            Parser recognizer,\n            DFA dfa,\n            int startIndex,\n            int stopIndex,\n            boolean exact,\n            BitSet ambigAlts,\n            ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs);\n    }\n\n    public void reportAttemptingFullContext(\n            Parser recognizer, DFA dfa, int startIndex, int stopIndex, BitSet conflictingAlts, ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs);\n    }\n\n    public void reportContextSensitivity(\n            Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs);\n    }\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/java/io/github/melin/superior/parser/postgre/antlr4/PostgreSqlLexerBase.java",
    "content": "package io.github.melin.superior.parser.postgre.antlr4;\n\nimport java.util.ArrayDeque;\nimport java.util.Deque;\nimport org.antlr.v4.runtime.CharStream;\nimport org.antlr.v4.runtime.Lexer;\n\npublic abstract class PostgreSqlLexerBase extends Lexer {\n    protected final Deque<String> tags = new ArrayDeque<>();\n\n    protected PostgreSqlLexerBase(CharStream input) {\n        super(input);\n    }\n\n    public void pushTag() {\n        tags.push(getText());\n    }\n\n    public boolean isTag() {\n        return getText().equals(tags.peek());\n    }\n\n    public void popTag() {\n        tags.pop();\n    }\n\n    public boolean checkLA(int c) {\n        return getInputStream().LA(1) != c;\n    }\n\n    public boolean charIsLetter() {\n        return Character.isLetter(getInputStream().LA(-1));\n    }\n\n    public void HandleNumericFail() {\n        getInputStream().seek(getInputStream().index() - 2);\n        setType(PostgreSqlLexer.Integral);\n    }\n\n    public void HandleLessLessGreaterGreater() {\n        if (getText() == \"<<\") setType(PostgreSqlLexer.LESS_LESS);\n        if (getText() == \">>\") setType(PostgreSqlLexer.GREATER_GREATER);\n    }\n\n    public void UnterminatedBlockCommentDebugAssert() {\n        // Debug.Assert(InputStream.LA(1) == -1 /*EOF*/);\n    }\n\n    public boolean CheckIfUtf32Letter() {\n        int codePoint = getInputStream().LA(-2) << 8 + getInputStream().LA(-1);\n        char[] c;\n        if (codePoint < 0x10000) {\n            c = new char[] {(char) codePoint};\n        } else {\n            codePoint -= 0x10000;\n            c = new char[] {(char) (codePoint / 0x400 + 0xd800), (char) (codePoint % 0x400 + 0xdc00)};\n        }\n        return Character.isLetter(c[0]);\n    }\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/java/io/github/melin/superior/parser/postgre/antlr4/PostgreSqlParserBase.java",
    "content": "package io.github.melin.superior.parser.postgre.antlr4;\n\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream;\nimport java.util.List;\nimport org.antlr.v4.runtime.*;\nimport org.apache.commons.lang3.StringUtils;\n\npublic abstract class PostgreSqlParserBase extends Parser {\n\n    public PostgreSqlParserBase(TokenStream input) {\n        super(input);\n    }\n\n    ParserRuleContext GetParsedSqlTree(String script, int line) {\n        PostgreSqlParser ph = getPostgreSQLParser(script);\n        ParserRuleContext result = ph.root();\n        return result;\n    }\n\n    public void ParseRoutineBody(PostgreSqlParser.Createfunc_opt_listContext _localctx) {\n        String lang = null;\n        for (PostgreSqlParser.Createfunc_opt_itemContext coi : _localctx.createfunc_opt_item()) {\n            if (coi.LANGUAGE() != null) {\n                if (coi.nonreservedword_or_sconst() != null)\n                    if (coi.nonreservedword_or_sconst().nonreservedword() != null)\n                        if (coi.nonreservedword_or_sconst().nonreservedword().identifier() != null)\n                            if (coi.nonreservedword_or_sconst()\n                                            .nonreservedword()\n                                            .identifier()\n                                            .Identifier()\n                                    != null) {\n                                lang = coi.nonreservedword_or_sconst()\n                                        .nonreservedword()\n                                        .identifier()\n                                        .Identifier()\n                                        .getText();\n                                break;\n                            }\n            }\n        }\n        if (null == lang) return;\n        PostgreSqlParser.Createfunc_opt_itemContext func_as = null;\n        for (PostgreSqlParser.Createfunc_opt_itemContext a : _localctx.createfunc_opt_item()) {\n            if (a.func_as() != null) {\n                func_as = a;\n                break;\n            }\n        }\n\n        lang = StringUtils.trim(lang);\n        if (func_as != null) {\n            String txt = GetRoutineBodyString(func_as.func_as().sconst(0));\n            PostgreSqlParser ph = getPostgreSQLParser(StringUtils.trim(txt));\n            switch (lang) {\n                case \"plpgsql\":\n                    func_as.func_as().Definition = ph.plsqlroot();\n                    break;\n                case \"sql\":\n                    func_as.func_as().Definition = ph.root();\n                    break;\n            }\n        }\n    }\n\n    private String TrimQuotes(String s) {\n        return (s == null || s.isEmpty()) ? s : s.substring(1, s.length() - 1);\n    }\n\n    public String unquote(String s) {\n        int slength = s.length();\n        StringBuilder r = new StringBuilder(slength);\n        int i = 0;\n        while (i < slength) {\n            Character c = s.charAt(i);\n            r.append(c);\n            if (c == '\\'' && i < slength - 1 && (s.charAt(i + 1) == '\\'')) i++;\n            i++;\n        }\n        return r.toString();\n    }\n\n    public String GetRoutineBodyString(PostgreSqlParser.SconstContext rule) {\n        PostgreSqlParser.AnysconstContext anysconst = rule.anysconst();\n        org.antlr.v4.runtime.tree.TerminalNode StringConstant = anysconst.StringConstant();\n        if (null != StringConstant) return unquote(TrimQuotes(StringConstant.getText()));\n        org.antlr.v4.runtime.tree.TerminalNode UnicodeEscapeStringConstant = anysconst.UnicodeEscapeStringConstant();\n        if (null != UnicodeEscapeStringConstant) return TrimQuotes(UnicodeEscapeStringConstant.getText());\n        org.antlr.v4.runtime.tree.TerminalNode EscapeStringConstant = anysconst.EscapeStringConstant();\n        if (null != EscapeStringConstant) return TrimQuotes(EscapeStringConstant.getText());\n        String result = \"\";\n        List<org.antlr.v4.runtime.tree.TerminalNode> dollartext = anysconst.DollarText();\n        for (org.antlr.v4.runtime.tree.TerminalNode s : dollartext) {\n            result += s.getText();\n        }\n        return result;\n    }\n\n    public PostgreSqlParser getPostgreSQLParser(String script) {\n        UpperCaseCharStream charStream = new UpperCaseCharStream(CharStreams.fromString(script));\n        Lexer lexer = new PostgreSqlLexer(charStream);\n        CommonTokenStream tokens = new CommonTokenStream(lexer);\n        PostgreSqlParser parser = new PostgreSqlParser(tokens);\n        lexer.removeErrorListeners();\n        parser.removeErrorListeners();\n        LexerDispatchingErrorListener listener_lexer = new LexerDispatchingErrorListener(\n                (Lexer) (((CommonTokenStream) (this.getInputStream())).getTokenSource()));\n        ParserDispatchingErrorListener listener_parser = new ParserDispatchingErrorListener(this);\n        lexer.addErrorListener(listener_lexer);\n        parser.addErrorListener(listener_parser);\n        return parser;\n    }\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/AbstractSqlParser.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(PostgreSqlParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: PostgreSqlParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(PostgreSqlParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/PostgreSqlAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport com.google.common.collect.Lists\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.AlterActionType.*\nimport io.github.melin.superior.common.StatementType.*\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.*\nimport io.github.melin.superior.common.relational.alter.*\nimport io.github.melin.superior.common.relational.common.CommentStatement\nimport io.github.melin.superior.common.relational.common.RefreshMaterializedView\nimport io.github.melin.superior.common.relational.common.ShowStatement\nimport io.github.melin.superior.common.relational.create.*\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.drop.DropDatabase\nimport io.github.melin.superior.common.relational.drop.DropMaterializedView\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport io.github.melin.superior.common.relational.drop.DropView\nimport io.github.melin.superior.common.relational.table.ColumnRel\nimport io.github.melin.superior.common.relational.table.TruncateTable\nimport io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser\nimport io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser.ColconstraintelemContext\nimport io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser.Indirection_elContext\nimport io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser.OpttempTableNameContext\nimport io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser.PlsqlrootContext\nimport io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParserBaseVisitor\nimport io.github.melin.superior.parser.postgre.relational.CreatePartitionTable\nimport org.antlr.v4.runtime.tree.RuleNode\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2020/6/30 9:57 上午 */\nclass PostgreSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) :\n    PostgreSqlParserBaseVisitor<Statement>() {\n\n    private var currentOptType: StatementType = StatementType.UNKOWN\n\n    private var limit: Int? = null\n    private var offset: Int? = null\n    private var inputTables: ArrayList<TableId> = arrayListOf()\n    private var outputTables: ArrayList<TableId> = arrayListOf()\n    private var cteTempTables: ArrayList<TableId> = arrayListOf()\n\n    // 多语句解析结果\n    private var statements: ArrayList<Statement> = arrayListOf()\n    // 存储过程和函数中包含的子语句\n    private var childStatements: ArrayList<Statement> = arrayListOf()\n    private val sqls: ArrayList<String> = arrayListOf()\n\n    fun getSqlStatements(): List<Statement> {\n        return statements\n    }\n\n    fun getSplitSqls(): List<String> {\n        return sqls\n    }\n\n    override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {\n        return if (currentResult == null) true else false\n    }\n\n    override fun visitDecl_cursor_query(ctx: PostgreSqlParser.Decl_cursor_queryContext): Statement? {\n        val statement = visitSelectstmt(ctx.selectstmt())\n        statement.setSql(source(ctx))\n        childStatements.add(statement)\n        return null\n    }\n\n    override fun visitStmtmulti(ctx: PostgreSqlParser.StmtmultiContext): Statement? {\n        ctx.stmt().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else {\n                        var statement = this.visitStmt(it)\n                        if (statement == null) {\n                            statement = DefaultStatement(StatementType.UNKOWN)\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n\n                currentOptType = StatementType.UNKOWN\n                clean()\n            }\n        }\n        return null\n    }\n\n    override fun visitStmt(ctx: PostgreSqlParser.StmtContext): Statement? {\n        val stmt: Statement? = super.visitStmt(ctx)\n        if (stmt != null) {\n            if (currentOptType != CREATE_FUNCTION && currentOptType != CREATE_PROCEDURE) {\n                stmt.setSql(source(ctx))\n                childStatements.add(stmt)\n            }\n        }\n        clean()\n        return stmt\n    }\n\n    private fun clean() {\n        limit = null\n        offset = null\n        inputTables = arrayListOf()\n        outputTables = arrayListOf()\n        cteTempTables = arrayListOf()\n    }\n\n    private fun addOutputTableId(tableId: TableId) {\n        if (!outputTables.contains(tableId)) {\n            outputTables.add(tableId)\n        }\n    }\n\n    // -----------------------------------database-------------------------------------------------\n\n    override fun visitCreatedbstmt(ctx: PostgreSqlParser.CreatedbstmtContext): Statement {\n        val databaseName = CommonUtils.cleanQuote(ctx.name().text)\n        return CreateDatabase(databaseName)\n    }\n\n    override fun visitDropdbstmt(ctx: PostgreSqlParser.DropdbstmtContext): Statement {\n        val databaseName = CommonUtils.cleanQuote(ctx.name().text)\n        return DropDatabase(databaseName)\n    }\n\n    // -----------------------------------schema-------------------------------------------------\n\n    override fun visitCreateschemastmt(ctx: PostgreSqlParser.CreateschemastmtContext): Statement {\n        val schemaName = CommonUtils.cleanQuote(ctx.colid().text)\n        return CreateSchema(schemaName)\n    }\n\n    // -----------------------------------table-------------------------------------------------\n\n    override fun visitCreatestmt(ctx: PostgreSqlParser.CreatestmtContext): Statement {\n        currentOptType = CREATE_TABLE\n\n        if (ctx.PARTITION() != null) {\n            val partitionTableId = parseTableName(ctx.qualified_name(0))\n            val tableId = parseTableName(ctx.qualified_name(1))\n            return CreatePartitionTable(tableId, partitionTableId)\n        }\n\n        val tableId = parseTableName(ctx.qualified_name(0))\n        val columns =\n            ctx.opttableelementlist()?.tableelementlist()?.tableelement()?.map {\n                val colDef = it.columnDef()\n                val colName = colDef.colid().text\n                val dataType = colDef.typename().text\n                val columnRel = ColumnRel(colName, dataType)\n\n                colDef.colquallist().colconstraint().forEach { colconstraint ->\n                    val child = colconstraint.getChild(0)\n                    if (child is ColconstraintelemContext) {\n                        if (child.NOT() != null) {\n                            columnRel.nullable = false\n                        } else if (child.PRIMARY() != null) {\n                            columnRel.primaryKey = true\n                        }\n                    }\n                }\n                columnRel\n            }\n\n        val createTable = CreateTable(tableId, TableType.POSTGRES, columnRels = columns)\n        if (ctx.opttemp().TEMP() != null || ctx.opttemp().TEMPORARY() != null) {\n            createTable.temporary = true\n        }\n\n        val partitionspec = ctx.optpartitionspec()?.partitionspec()\n        val tablePartition = ctx.gaussextension()?.tablePartition()\n        if (partitionspec != null) {\n            val partitionType = partitionspec.colid().text.uppercase()\n            val partitionColumns = partitionspec.part_params().part_elem().map { it.text }\n\n            createTable.partitionColumnNames.addAll(partitionColumns)\n            if (\"RANGE\" == partitionType) {\n                createTable.partitionType = PartitionType.RANGE\n            } else {\n                createTable.partitionType = PartitionType.LIST\n            }\n        } else if (tablePartition != null) {\n            var partitionType: PartitionType? = null\n            val partitionColumns = mutableListOf<String>()\n\n            val ptSpec = tablePartition.partition_list()\n            if (ptSpec.list_partition_stmt() != null) {\n                partitionType = PartitionType.LIST\n                partitionColumns.add(ptSpec.list_partition_stmt().partition_key().colid().text)\n            } else if (ptSpec.value_partition_stmt() != null) {\n                partitionType = PartitionType.VALUES\n                partitionColumns.add(ptSpec.value_partition_stmt().partition_key().colid().text)\n            } else if (ptSpec.range_partition_stmt() != null) {\n                partitionType = PartitionType.RANGE\n                partitionColumns.add(ptSpec.range_partition_stmt().partition_key().colid().text)\n            } else if (ptSpec.normal_partition_stmt() != null) {\n                partitionType = PartitionType.NORMAL\n            }\n\n            createTable.partitionColumnNames.addAll(partitionColumns)\n            createTable.partitionType = partitionType\n        }\n\n        return createTable\n    }\n\n    override fun visitFunc_as(ctx: PostgreSqlParser.Func_asContext): Statement? {\n        if (ctx.Definition != null) {\n            visitPlsqlroot(ctx.Definition as PlsqlrootContext)\n        }\n        return super.visitFunc_as(ctx)\n    }\n\n    override fun visitCreatefunctionstmt(ctx: PostgreSqlParser.CreatefunctionstmtContext): Statement {\n        currentOptType = if (ctx.FUNCTION() != null) CREATE_FUNCTION else CREATE_PROCEDURE\n        childStatements = arrayListOf()\n\n        super.visitCreatefunctionstmt(ctx)\n\n        val replace = if (ctx.opt_or_replace().REPLACE() != null) true else false\n        val funcName = ctx.func_name()\n\n        if (ctx.FUNCTION() != null) {\n            val functionId =\n                if (funcName.type_function_name() != null) {\n                    FunctionId(funcName.text)\n                } else {\n                    FunctionId(funcName.colid().text, funcName.indirection().indirection_el()[0].attr_name().text)\n                }\n\n            currentOptType = if (ctx.FUNCTION() != null) CREATE_FUNCTION else CREATE_PROCEDURE\n            return CreateFunction(functionId, childStatements, replace)\n        } else {\n            val procedureId =\n                if (funcName.type_function_name() != null) {\n                    ProcedureId(funcName.text)\n                } else {\n                    ProcedureId(funcName.colid().text, funcName.indirection().indirection_el()[0].attr_name().text)\n                }\n\n            currentOptType = if (ctx.FUNCTION() != null) CREATE_FUNCTION else CREATE_PROCEDURE\n            return CreateProcedure(procedureId, childStatements, replace)\n        }\n    }\n\n    override fun visitProc_stmt(ctx: PostgreSqlParser.Proc_stmtContext): Statement? {\n        super.visitProc_stmt(ctx)\n        return null\n    }\n\n    override fun visitViewstmt(ctx: PostgreSqlParser.ViewstmtContext): Statement {\n        currentOptType = CREATE_VIEW\n        val tableId = parseTableName(ctx.qualified_name())\n        val replace = if (ctx.REPLACE() != null) true else false\n        val queryStmt = this.visitSelectstmt(ctx.selectstmt()) as QueryStmt\n        val createView = CreateView(tableId, queryStmt)\n        createView.replace = replace\n\n        if (ctx.opttemp().TEMP() != null || ctx.opttemp().TEMPORARY() != null) {\n            createView.temporary = true\n        }\n        return createView\n    }\n\n    override fun visitCreatematviewstmt(ctx: PostgreSqlParser.CreatematviewstmtContext): Statement {\n        currentOptType = CREATE_MATERIALIZED_VIEW\n        val tableId = parseTableName(ctx.create_mv_target().qualified_name())\n        val ifNotExists = if (ctx.IF_P() != null) true else false\n        val queryStmt = this.visitSelectstmt(ctx.selectstmt()) as QueryStmt\n        val createView = CreateMaterializedView(tableId, queryStmt)\n        createView.ifNotExists = ifNotExists\n        return createView\n    }\n\n    override fun visitRefreshmatviewstmt(ctx: PostgreSqlParser.RefreshmatviewstmtContext): Statement {\n        val tableId = parseTableName(ctx.qualified_name())\n        return RefreshMaterializedView(tableId)\n    }\n\n    override fun visitRenamestmt(ctx: PostgreSqlParser.RenamestmtContext): Statement? {\n        if (ctx.TABLE() != null) {\n            val tableId = parseTableName(ctx.qualified_name())\n            val newTable = ctx.name().get(0).text\n            val ifexists = ctx.EXISTS() != null\n            val action = RenameAction(TableId(newTable), ifexists)\n            return AlterTable(tableId, action)\n        } else if (ctx.VIEW() != null) {\n            if (ctx.MATERIALIZED() == null) {\n                val tableId = parseTableName(ctx.qualified_name())\n                val newTable = ctx.name().get(0).text\n                val ifexists = ctx.EXISTS() != null\n                val action = RenameAction(TableId(newTable), ifexists)\n                return AlterView(tableId, action)\n            } else {\n                val tableId = parseTableName(ctx.qualified_name())\n                val newTable = ctx.name().get(0).text\n                val ifexists = ctx.EXISTS() != null\n                val action = RenameAction(TableId(newTable), ifexists)\n                return AlterMaterializedView(tableId, action)\n            }\n        } else {\n\n            return null\n        }\n    }\n\n    override fun visitSelectstmt(ctx: PostgreSqlParser.SelectstmtContext): Statement {\n        currentOptType = SELECT\n        super.visitSelectstmt(ctx)\n\n        return QueryStmt(inputTables, limit, offset)\n    }\n\n    override fun visitCreateasstmt(ctx: PostgreSqlParser.CreateasstmtContext): Statement {\n        currentOptType = CREATE_TABLE_AS_SELECT\n        val tableId = parseTableName(ctx.create_as_target().qualified_name())\n        val queryStmt = this.visitSelectstmt(ctx.selectstmt()) as QueryStmt\n        val createTable = CreateTableAsSelect(tableId, queryStmt)\n        return createTable\n    }\n\n    override fun visitUpdatestmt(ctx: PostgreSqlParser.UpdatestmtContext): Statement {\n        currentOptType = UPDATE\n        val tableId = parseTableName(ctx.relation_expr_opt_alias().relation_expr())\n        addOutputTableId(tableId)\n\n        super.visitWhere_or_current_clause(ctx.where_or_current_clause())\n        super.visitFrom_clause(ctx.from_clause())\n\n        return UpdateTable(tableId, inputTables)\n    }\n\n    override fun visitDeletestmt(ctx: PostgreSqlParser.DeletestmtContext): Statement {\n        currentOptType = DELETE\n        val tableId = parseTableName(ctx.relation_expr_opt_alias().relation_expr())\n        addOutputTableId(tableId)\n\n        super.visitWhere_or_current_clause(ctx.where_or_current_clause())\n        super.visitUsing_clause(ctx.using_clause())\n\n        return DeleteTable(tableId, inputTables)\n    }\n\n    override fun visitInsertstmt(ctx: PostgreSqlParser.InsertstmtContext): Statement {\n        currentOptType = INSERT\n        if (ctx.opt_with_clause() != null) {\n            this.visitOpt_with_clause(ctx.opt_with_clause())\n        }\n\n        val tableId = parseTableName(ctx.insert_target().qualified_name())\n        addOutputTableId(tableId)\n\n        val queryStmt = this.visitSelectstmt(ctx.insert_rest().selectstmt()) as QueryStmt\n        val insertTable = InsertTable(InsertMode.INTO, queryStmt, tableId)\n        insertTable.outputTables.addAll(outputTables.subList(1, outputTables.size))\n        insertTable?.setSql(source(ctx))\n        return insertTable\n    }\n\n    override fun visitMergestmt(ctx: PostgreSqlParser.MergestmtContext): Statement {\n        currentOptType = MERGE\n\n        val mergeTableId = parseTableName(ctx.qualified_name(0))\n        val mergeTable = MergeTable(mergeTableId)\n\n        if (ctx.qualified_name().size == 2) {\n            val tableId = parseTableName(ctx.qualified_name(1))\n            inputTables.add(tableId)\n        } else if (ctx.select_with_parens() != null) {\n            super.visitSelect_with_parens(ctx.select_with_parens())\n        }\n        mergeTable.inputTables = inputTables\n        return mergeTable\n    }\n\n    override fun visitCte_list(ctx: PostgreSqlParser.Cte_listContext): Statement {\n        ctx.common_table_expr().forEach { cteTempTables.add(TableId(it.name().text)) }\n        return super.visitCte_list(ctx)\n    }\n\n    override fun visitQualified_name(ctx: PostgreSqlParser.Qualified_nameContext): Statement? {\n        if (\n            currentOptType == SELECT ||\n                currentOptType == CREATE_VIEW ||\n                currentOptType == CREATE_MATERIALIZED_VIEW ||\n                currentOptType == CREATE_TABLE_AS_SELECT ||\n                currentOptType == UPDATE ||\n                currentOptType == DELETE ||\n                currentOptType == MERGE ||\n                currentOptType == INSERT ||\n                currentOptType == CREATE_FUNCTION ||\n                currentOptType == CREATE_PROCEDURE\n        ) {\n\n            if (ctx.parent is OpttempTableNameContext) {\n                return null\n            }\n\n            val tableId = parseTableName(ctx)\n\n            if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {\n                inputTables.add(tableId)\n            }\n            return null\n        } else {\n            throw SQLParserException(\"not support\")\n        }\n    }\n\n    // create index\n    override fun visitIndexstmt(ctx: PostgreSqlParser.IndexstmtContext): Statement {\n        val tableId = parseTableName(ctx.relation_expr())\n        val indexName =\n            if (ctx.opt_index_name() != null) {\n                ctx.opt_index_name().text\n            } else {\n                ctx.name().text\n            }\n        val createIndex = CreateIndex(indexName)\n        return AlterTable(tableId, createIndex)\n    }\n\n    override fun visitDropstmt(ctx: PostgreSqlParser.DropstmtContext): Statement {\n        if (ctx.object_type_any_name() != null) {\n            val ifExists = ctx.IF_P() != null\n            if (ctx.object_type_any_name().INDEX() != null) {\n                val actions = ctx.any_name_list().any_name().map { indexName -> DropIndex(indexName.text, ifExists) }\n                val tableId = TableId(\"\")\n                val alterTable = AlterTable(tableId)\n                alterTable.ifExists = ifExists\n                alterTable.addActions(actions)\n                return alterTable\n            } else if (ctx.object_type_any_name().TABLE() != null) {\n                val tableIds = ctx.any_name_list().any_name().map { tableName -> parseTableName(tableName) }\n                val dropTable = DropTable(tableIds.first(), ifExists)\n                dropTable.tableIds.addAll(tableIds)\n                return dropTable\n            } else if (ctx.object_type_any_name().VIEW() != null) {\n                val isMaterialized =\n                    if (ctx.object_type_any_name().MATERIALIZED() != null) {\n                        true\n                    } else {\n                        false\n                    }\n                val tableIds = ctx.any_name_list().any_name().map { tableName -> parseTableName(tableName) }\n                if (isMaterialized) {\n                    val dropView = DropMaterializedView(tableIds.first(), ifExists)\n                    dropView.tableIds.addAll(tableIds)\n                    return dropView\n                } else {\n                    val dropView = DropView(tableIds.first(), ifExists)\n                    dropView.tableIds.addAll(tableIds)\n                    return dropView\n                }\n            } else if (ctx.object_type_any_name().SEQUENCE() != null) {\n                val tableIds = ctx.any_name_list().any_name().map { tableName -> parseTableName(tableName) }\n                val dropSequence =\n                    io.github.melin.superior.common.relational.drop.DropSequence(tableIds.first(), ifExists)\n                dropSequence.tableIds.addAll(tableIds)\n                return dropSequence\n            }\n        }\n\n        throw SQLParserException(\"not support\")\n    }\n\n    override fun visitTruncatestmt(ctx: PostgreSqlParser.TruncatestmtContext): Statement {\n        val tableIds = ctx.relation_expr_list().relation_expr().map { parseTableName(it) }\n        return TruncateTable(Lists.newArrayList(tableIds))\n    }\n\n    override fun visitAltertablestmt(ctx: PostgreSqlParser.AltertablestmtContext): Statement? {\n        if (ctx.TABLE() != null) {\n            if (ctx.relation_expr() != null) {\n                val tableId = parseTableName(ctx.relation_expr())\n\n                if (ctx.alter_table_cmds() != null) {\n                    val alterTable = AlterTable(tableId)\n                    val cmds = ctx.alter_table_cmds().alter_table_cmd()\n                    for (cmdContext in cmds) {\n                        if (cmdContext.ADD_P() != null && cmdContext.columnDef() != null) {\n                            val columnDef = cmdContext.columnDef()\n                            val columnName = columnDef.colid().text\n                            val dataType = source(columnDef.typename())\n                            val action = AlterColumnAction(ADD_COLUMN, columnName, dataType)\n                            action.ifNotExists = cmdContext.EXISTS() != null\n\n                            alterTable.actions.add(action)\n                        } else if (cmdContext.alter_column_default() != null) {\n                            val columnDefaultDef = cmdContext.alter_column_default()\n                            val columnName = cmdContext.colid().get(0).text\n\n                            if (columnDefaultDef.DROP() != null) {\n                                val action = AlterColumnAction(DROP_COLUMN_DRFAULT, columnName)\n                                alterTable.actions.add(action)\n                            } else {\n                                val value = source(columnDefaultDef.a_expr())\n                                val action = AlterColumnAction(SET_COLUMN_DEFAULT, columnName)\n                                action.defaultExpression = CommonUtils.cleanQuote(value)\n                                alterTable.actions.add(action)\n                            }\n                        }\n                    }\n\n                    return alterTable\n                } else {\n                    var alterTable: AlterTable? = null\n                    val partitionCmd = ctx.partition_cmd()\n                    if (partitionCmd.ATTACH() != null) {\n                        alterTable = AlterTable(tableId, AlterTableAction(ATTACH_PARTITION))\n                    } else {\n                        alterTable = AlterTable(tableId, AlterTableAction(DETACH_PARTITION))\n                    }\n\n                    return alterTable\n                }\n\n                return null\n            }\n        }\n\n        return null\n    }\n\n    override fun visitCommentstmt(ctx: PostgreSqlParser.CommentstmtContext): Statement {\n        val objType: String? =\n            if (ctx.object_type_any_name() != null) {\n                ctx.object_type_any_name().children.map { it.text }.joinToString(\" \")\n            } else if (ctx.object_type_name() != null) {\n                ctx.object_type_name().children.map { it.text }.joinToString(\" \")\n            } else if (ctx.object_type_name_on_any_name() != null) {\n                ctx.object_type_name_on_any_name().children.map { it.text }.joinToString(\" \")\n            } else if (ctx.COLUMN() != null) {\n                ctx.COLUMN().text\n            } else if (ctx.FUNCTION() != null) {\n                ctx.FUNCTION().text\n            } else {\n                null\n            }\n\n        val objValue = if (ctx.any_name() != null) ctx.any_name().text else null\n\n        val isNull = if (ctx.comment_text().NULL_P() != null) true else false\n        val text: String? =\n            if (ctx.comment_text().text != null) CommonUtils.cleanQuote(ctx.comment_text().sconst().text) else null\n        return CommentStatement(text, isNull, objType, objValue)\n    }\n\n    override fun visitStmt_dynexecute(ctx: PostgreSqlParser.Stmt_dynexecuteContext): Statement? {\n        var execSql = StringUtils.substringAfter(ctx.a_expr().text, \"'\")\n        execSql = StringUtils.substringBeforeLast(execSql, \"'\")\n        execSql = StringUtils.trim(execSql)\n        execSql = StringUtils.replace(execSql, \"''\", \"'\")\n\n        val statements = PostgreSqlHelper.parseMultiStatement(execSql)\n        childStatements.addAll(statements)\n        return null\n    }\n\n    override fun visitSelect_limit(ctx: PostgreSqlParser.Select_limitContext): Statement? {\n        val limitClause = ctx.limit_clause()\n        val offsetClause = ctx.offset_clause()\n        if (limitClause != null) {\n            if (limitClause.LIMIT() != null) {\n                if (limitClause.select_limit_value().a_expr() != null) {\n                    limit = limitClause.select_limit_value().a_expr().text.toInt()\n                }\n\n                if (limitClause.select_offset_value() != null) {\n                    offset = limitClause.select_offset_value().a_expr().text.toInt()\n                }\n            }\n\n            if (limitClause.FETCH() != null && limitClause.select_fetch_first_value() != null) {\n                if (limitClause.select_fetch_first_value().c_expr() != null) {\n                    limit = limitClause.select_fetch_first_value().c_expr().text.toInt()\n                }\n            }\n        }\n\n        if (offsetClause != null) {\n            if (offsetClause.select_offset_value() != null) {\n                offset = offsetClause.select_offset_value().text.toInt()\n            }\n\n            if (offsetClause.select_fetch_first_value() != null) {\n                if (offsetClause.select_fetch_first_value().c_expr() != null) {\n                    offset = offsetClause.select_fetch_first_value().c_expr().text.toInt()\n                }\n            }\n        }\n        return super.visitSelect_limit(ctx)\n    }\n\n    // ----------------------------------------private methods------------------------------------\n\n    fun parseTableName(ctx: PostgreSqlParser.Any_nameContext): TableId {\n        val attrNames = ctx.attrs()?.attr_name()\n        if (attrNames == null) {\n            return TableId(null, null, ctx.colid().text)\n        }\n\n        if (attrNames.size == 2) {\n            return TableId(ctx.colid().text, attrNames.get(0).text, attrNames.get(1).text)\n        } else if (attrNames.size == 1) {\n            return TableId(null, ctx.colid().text, attrNames.get(0).text)\n        }\n\n        throw SQLParserException(\"parse schema qualified name error\")\n    }\n\n    fun parseTableName(ctx: PostgreSqlParser.Relation_exprContext): TableId {\n        return parseTableName(ctx.qualified_name())\n    }\n\n    fun parseTableName(ctx: PostgreSqlParser.Qualified_nameContext): TableId {\n        if (ctx.childCount == 2) {\n            val obj = ctx.getChild(1)\n            if (obj.childCount == 2) {\n                return TableId(ctx.getChild(0).text, obj.getChild(0).getChild(1).text, obj.getChild(1).getChild(1).text)\n            } else if (obj.childCount == 1) {\n                val inEl = obj.getChild(0) as Indirection_elContext\n                return TableId(ctx.colid().text, inEl.attr_name().text)\n            }\n        } else if (ctx.childCount == 1) {\n            return TableId(ctx.getChild(0).text)\n        }\n\n        throw SQLParserException(\"parse schema qualified name error\")\n    }\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/PostgreSqlHelper.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.postgre.antlr4.PostgreSqlLexer\nimport io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser\nimport io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParserBaseVisitor\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2020/6/30 9:58 上午 */\nobject PostgreSqlHelper {\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until PostgreSqlLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = PostgreSqlLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement {\n        val statements = this.parseMultiStatement(command)\n        if (statements.size != 1) {\n            throw IllegalStateException(\"only parser one sql, sql count: \" + statements.size)\n        } else {\n            return statements.get(0)\n        }\n    }\n\n    @JvmStatic\n    fun parseMultiStatement(command: String): List<Statement> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = PostgreSqlAntlr4Visitor(false, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSqlStatements()\n    }\n\n    @JvmStatic\n    fun splitSql(command: String): List<String> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = PostgreSqlAntlr4Visitor(true, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSplitSqls()\n    }\n\n    @JvmStatic\n    fun checkSqlSyntax(command: String) {\n        val sqlVisitor = PostgreSqlParserBaseVisitor<Statement>()\n        innerParseStatement(command, sqlVisitor)\n    }\n\n    private fun innerParseStatement(command: String, sqlVisitor: PostgreSqlParserBaseVisitor<Statement>) {\n        val charStream = UpperCaseCharStream(CharStreams.fromString(command))\n        val lexer = PostgreSqlLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = PostgreSqlParser(tokenStream)\n        AbstractSqlParser.installCaches(parser)\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n\n        // parser.interpreter.predictionMode = PredictionMode.SLL\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visit(parser.root())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                sqlVisitor.visit(parser.root())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(command)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/relational/CreatePartitionTable.kt",
    "content": "package io.github.melin.superior.parser.postgre.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class CreatePartitionTable(override val tableId: TableId, val partitionTableId: TableId) :\n    AbsTableStatement() { // 是否存在 if exists 关键字\n    override val statementType = StatementType.CREATE_TABLE\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DDL\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/BooleanType.kt",
    "content": "package io.github.melin.superior.parser.postgre.type\n\nimport io.github.melin.superior.common.type.AbsType\n\nclass BooleanType : AbsType() {\n    override val name: String = \"boolean\"\n    override val alias: String = \"bool\"\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/JsonType.kt",
    "content": "package io.github.melin.superior.parser.postgre.type\n\nimport io.github.melin.superior.common.type.AbsType\n\nclass JsonType : AbsType() {\n    override val name: String = \"json\"\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/datetime.kt",
    "content": "package io.github.melin.superior.parser.postgre.type\n\nimport io.github.melin.superior.common.type.AbsDataTimeType\n\nclass DateType : AbsDataTimeType() {\n    override val name: String = \"date\"\n}\n\ndata class TimeType(val precision: Int = 0, val timezone: Boolean = false) : AbsDataTimeType() {\n    override val name: String = \"time\"\n    override val alias: String = \"timez\"\n}\n\ndata class TimeStampType(val precision: Int = 0, val timezone: Boolean = false) : AbsDataTimeType() {\n    override val name: String = \"timestamp\"\n    override val alias: String = \"timestampz\"\n}\n\nclass IntervalType : AbsDataTimeType() {\n    override val name: String = \"interval\"\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/numeric.kt",
    "content": "package io.github.melin.superior.parser.postgre.type\n\nimport io.github.melin.superior.common.type.AbsNumericType\n\ndata class SmallIntType(val length: Int) : AbsNumericType() {\n    override val name: String = \"smallint\"\n    override val alias: String = \"int2\"\n\n    companion object {\n        const val MIN_VALUE: Int = -32768\n        const val MAX_VALUE: Int = 32767\n    }\n}\n\ndata class IntegerType(val length: Int) : AbsNumericType() {\n    override val name: String = \"integer\"\n    override val alias: String = \"int\"\n    override val alias2: String = \"int4\"\n\n    companion object {\n        const val MIN_VALUE: Long = -2147483648L\n        const val MAX_VALUE: Long = 2147483647L\n    }\n}\n\ndata class BigIntType(val length: Int) : AbsNumericType() {\n    override val name: String = \"bigint\"\n    override val alias: String = \"int8\"\n}\n\ndata class NumericType(val precision: Int = 10, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"numeric\"\n    override val alias: String = \"decimal\"\n}\n\ndata class FloatType(val precision: Int, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"float\"\n}\n\ndata class DoubleType(val precision: Int, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"double precision\"\n    override val alias: String = \"float8\"\n}\n\ndata class RealType(val precision: Int, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"real\"\n    override val alias: String = \"float4\"\n}\n\ndata class SmallserialType(val length: Int) : AbsNumericType() {\n    override val name: String = \"smallserial\"\n    override val alias: String = \"serial2\"\n\n    companion object {\n        const val MIN_VALUE: Int = 1\n        const val MAX_VALUE: Int = 32767\n    }\n}\n\ndata class SerialType(val length: Int) : AbsNumericType() {\n    override val name: String = \"serial\"\n    override val alias: String = \"serial4\"\n\n    companion object {\n        const val MIN_VALUE: Long = 1\n        const val MAX_VALUE: Long = 2147483647L\n    }\n}\n\ndata class BigserialType(val length: Int) : AbsNumericType() {\n    override val name: String = \"bigserial\"\n    override val alias: String = \"serial8\"\n}\n\ndata class BitType(val length: Int) : AbsNumericType() {\n    override val name: String = \"bit\"\n}\n\ndata class VarbitType(val length: Int) : AbsNumericType() {\n    override val name: String = \"bit varying\"\n    override val alias: String = \"varbit\"\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/string.kt",
    "content": "package io.github.melin.superior.parser.postgre.type\n\nimport io.github.melin.superior.common.type.AbsStringType\n\ndata class CharType(val length: Int) : AbsStringType() {\n    override val name: String = \"char\"\n    override val alias: String = \"character\"\n\n    companion object {\n        const val MAX_LENGTH: Int = 255\n    }\n}\n\ndata class VarcharType(val length: Int) : AbsStringType() {\n    override val name: String = \"varchar\"\n    override val alias: String = \"character varying\"\n\n    companion object {\n        const val MAX_LENGTH: Int = 65535\n    }\n}\n\nclass TextType : AbsStringType() {\n    override val name: String = \"text\"\n}\n\nclass ByteaType : AbsStringType() {\n    override val name: String = \"bytea\"\n}\n\ndata class EnumType(val typeName: String, val values: List<String>) : AbsStringType() {\n    override val name: String = \"enum\"\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/test/java/io/github/melin/superior/parser/postgre/PostgreSqlParserDdlTest.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport io.github.melin.superior.common.AlterActionType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.*\nimport io.github.melin.superior.common.relational.alter.*\nimport io.github.melin.superior.common.relational.common.CommentStatement\nimport io.github.melin.superior.common.relational.common.RefreshMaterializedView\nimport io.github.melin.superior.common.relational.create.*\nimport io.github.melin.superior.common.relational.drop.DropDatabase\nimport io.github.melin.superior.common.relational.drop.DropMaterializedView\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport io.github.melin.superior.parser.postgre.relational.CreatePartitionTable\nimport org.junit.Assert\nimport org.junit.Test\n\n/**\n * Created by libinsong on 2020/6/30 11:04 上午\n */\nclass PostgreSqlParserDdlTest {\n\n    @Test\n    fun createDatabaseTest() {\n        val sql = \"\"\"\n            CREATE DATABASE bigdata1;\n            drop DATABASE bigdata2\n        \"\"\".trimIndent()\n\n        val statements = PostgreSqlHelper.parseMultiStatement(sql)\n\n        val createDatabse = statements.get(0)\n        val dropDatabase = statements.get(1)\n        if (createDatabse is CreateDatabase) {\n            Assert.assertEquals(\"bigdata1\", createDatabse.databaseName)\n        } else {\n            Assert.fail()\n        }\n        if (dropDatabase is DropDatabase) {\n            Assert.assertEquals(\"bigdata2\", dropDatabase.databaseName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createSchemaTest() {\n        val sql = \"\"\"\n            CREATE schema bigdata1;\n            CREATE schema bigdata2;\n        \"\"\".trimIndent()\n\n        val statements = PostgreSqlHelper.parseMultiStatement(sql)\n\n        val createSchema1 = statements.get(0)\n        val createSchema2 = statements.get(1)\n        if (createSchema1 is CreateSchema) {\n            Assert.assertEquals(\"bigdata1\", createSchema1.schemaName)\n        } else {\n            Assert.fail()\n        }\n        if (createSchema2 is CreateSchema) {\n            Assert.assertEquals(\"bigdata2\", createSchema2.schemaName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTable0() {\n        val sql = \"\"\"\n            CREATE TEMPORARY TABLE test.public.authors (\n                id INTEGER NOT NULL PRIMARY KEY,\n                last_name TEXT,\n                first_name TEXT,\n                age int not null\n            ) PARTITION BY RANGE (age); \n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertTrue(statement.temporary)\n            Assert.assertEquals(TableId(\"test\", \"public\", \"authors\"), statement.tableId)\n            Assert.assertEquals(4, statement.columnRels?.size)\n            Assert.assertTrue(statement.columnRels?.get(0)?.primaryKey!!)\n\n            Assert.assertEquals(PartitionType.RANGE, statement.partitionType)\n            Assert.assertEquals(1, statement.partitionColumnNames.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTable1() {\n        val sql = \"\"\"\n            CREATE TABLE IF NOT EXISTS sales_range_partitioned3 (\n                id INT,\n                sales_date DATE,\n                amount DECIMAL(10, 2)\n            )\n            PARTITION BY RANGE (sales_date) (\n                PARTITION p2022 VALUES LESS THAN ('2023-01-01'),\n                PARTITION p2023 VALUES LESS THAN ('2024-01-01'),\n                PARTITION p2024 VALUES LESS THAN ('2025-01-01')\n            );\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(TableId(\"sales_range_partitioned3\"), statement.tableId)\n            Assert.assertEquals(3, statement.columnRels?.size)\n            Assert.assertEquals(PartitionType.RANGE, statement.partitionType)\n            Assert.assertEquals(1, statement.partitionColumnNames.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createView0() {\n        val sql = \"\"\"\n            CREATE OR REPLACE VIEW comedies AS\n            SELECT f.*,\n                   country_code_to_name(f.country_code) AS country,\n                   (SELECT avg(r.rating)\n                    FROM user_ratings r\n                    WHERE r.film_id = f.id) AS avg_rating\n            FROM films f\n            WHERE f.kind = 'Comedy'\n            WITH CASCADED CHECK OPTION;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateView) {\n            Assert.assertEquals(StatementType.CREATE_VIEW, statement.statementType)\n            Assert.assertEquals(\"comedies\", statement.tableId.tableName)\n\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createMatView0() {\n        val sql = \"\"\"\n            CREATE MATERIALIZED VIEW sales_summary AS\n              SELECT\n                  seller_no,\n                  invoice_date,\n                  sum(invoice_amt)::numeric(13,2) as sales_amt\n                FROM invoice\n                WHERE invoice_date < CURRENT_DATE\n                GROUP BY\n                  seller_no,\n                  invoice_date;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateMaterializedView) {\n            Assert.assertEquals(StatementType.CREATE_MATERIALIZED_VIEW, statement.statementType)\n            Assert.assertEquals(\"sales_summary\", statement.tableId.tableName)\n\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropMvTest() {\n        val sql = \"\"\"\n            DROP MATERIALIZED VIEW tickets_mv;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n\n        if (statement is DropMaterializedView) {\n            Assert.assertEquals(StatementType.DROP_MATERIALIZED_VIEW, statement.statementType)\n            Assert.assertEquals(TableId(\"tickets_mv\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun refreshMvTest() {\n        val sql = \"\"\"\n            REFRESH MATERIALIZED VIEW tickets_mv;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n\n        if (statement is RefreshMaterializedView) {\n            Assert.assertEquals(StatementType.REFRESH_MV, statement.statementType)\n            Assert.assertEquals(TableId(\"tickets_mv\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun renameMvTest() {\n        val sql = \"\"\"\n            ALTER MATERIALIZED VIEW tickets_mv RENAME TO tickets_mv_1;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n\n        if (statement is AlterMaterializedView) {\n            Assert.assertEquals(StatementType.ALTER_MATERIALIZED_VIEW, statement.statementType)\n            Assert.assertEquals(TableId(\"tickets_mv\"), statement.tableId)\n            Assert.assertEquals(AlterActionType.RENAME, statement.firstAction().alterType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropTable0() {\n        val sql = \"\"\"\n            drop TABLE test.public.authors\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is DropTable) {\n            Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)\n            Assert.assertEquals(TableId(\"test\", \"public\", \"authors\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropTable1() {\n        val sql = \"\"\"\n            drop TABLE authors, tests\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is DropTable) {\n            Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)\n            Assert.assertEquals(TableId(\"authors\"), statement.tableId)\n            Assert.assertEquals(2, statement.tableIds.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createIndexTest() {\n        val sql = \"CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating);\\n\"\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        \n        if (statement is AlterTable) {\n            Assert.assertEquals(TableId(\"films\"), statement.tableId)\n            val createIndex = statement.firstAction() as CreateIndex\n            Assert.assertEquals(AlterActionType.ADD_INDEX, createIndex.alterType)\n            Assert.assertEquals(\"title_idx\", createIndex.indexName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropIndexTest() {\n        val sql = \"DROP INDEX title_idx\"\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        \n        if (statement is AlterTable) {\n            val dropIndex = statement.firstAction() as DropIndex\n            Assert.assertEquals(AlterActionType.DROP_INDEX, dropIndex.alterType)\n            Assert.assertEquals(\"title_idx\", dropIndex.indexName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createPartitonTableTest() {\n        val sql = \"create table pkslow_person_r1 partition of pkslow_person_r for values from (MINVALUE) to (10);  \\n\"\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n\n        if (statement is CreatePartitionTable) {\n            Assert.assertEquals(\"pkslow_person_r\", statement.tableId.tableName)\n            Assert.assertEquals(\"pkslow_person_r1\", statement.partitionTableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun commentTest0() {\n        val sql = \"\"\"\n            COMMENT ON TABLE my_schema.my_table IS 'Employee Information';\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is CommentStatement) {\n            Assert.assertEquals(StatementType.COMMENT, statement.statementType)\n            Assert.assertEquals(\"Employee Information\", statement.comment)\n            Assert.assertFalse(statement.isNull)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun alterTableTest() {\n        val sql = \"\"\"\n            ALTER TABLE distributors ADD COLUMN address varchar(30),\n            ALTER COLUMN status SET default 'current';\n        \"\"\".trimIndent()\n        val statements = PostgreSqlHelper.parseMultiStatement(sql)\n\n        val alterTable1 = statements.get(0) as AlterTable\n        Assert.assertEquals(\"distributors\", alterTable1.tableId.tableName)\n        var action = alterTable1.actions.get(0) as AlterColumnAction\n        Assert.assertEquals(AlterActionType.ADD_COLUMN, action.alterType)\n        Assert.assertEquals(\"address\", action.columName)\n        Assert.assertEquals(\"varchar(30)\", action.dataType)\n\n        action = alterTable1.actions.get(1) as AlterColumnAction\n        Assert.assertEquals(AlterActionType.SET_COLUMN_DEFAULT, action.alterType)\n        Assert.assertEquals(\"status\", action.columName)\n        Assert.assertEquals(\"current\", action.defaultExpression)\n    }\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/test/java/io/github/melin/superior/parser/postgre/PostgreSqlParserDmlTest.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.create.CreateTableAsSelect\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.table.TruncateTable\nimport org.junit.Assert\nimport org.junit.Test\n\n/**\n * Created by libinsong on 2020/6/30 11:04 上午\n */\nclass PostgreSqlParserDmlTest {\n\n    @Test\n    fun queryTest0() {\n        val sql = \"\"\"\n            select a.* from datacompute1.datacompute.dc_job a left join datacompute1.datacompute.dc_job_scheduler b on a.id=b.job_id\n            LIMIT 3, 2\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(2, statement.inputTables.size)\n            Assert.assertEquals(3, statement.limit)\n            Assert.assertEquals(2, statement.offset)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest1() {\n        val sql = \"\"\"\n            SELECT * FROM public.usertest LIMIT 3 OFFSET 2;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(3, statement.limit)\n            Assert.assertEquals(2, statement.offset)\n            Assert.assertEquals(TableId(\"public\", \"usertest\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest2() {\n        val sql = \"\"\"\n            SELECT * FROM public.usertest FETCH FIRST 5 ROWS ONLY;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(5, statement.limit)\n            Assert.assertEquals(TableId(\"public\", \"usertest\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest3() {\n        val sql = \"\"\"\n            SELECT * FROM public.usertest \n            OFFSET 10\n            FETCH FIRST 10 ROWS ONLY;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(10, statement.limit)\n            Assert.assertEquals(10, statement.offset)\n            Assert.assertEquals(TableId(\"public\", \"usertest\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun cteSqlTest0() {\n        val sql = \"\"\"\n            WITH regional_sales AS (\n                SELECT region, SUM(amount) AS total_sales\n                FROM orders\n                GROUP BY region\n            ), \n            top_regions AS (\n                SELECT region\n                FROM regional_sales\n                WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)\n            )\n            SELECT region,\n                   product,\n                   SUM(quantity) AS product_units,\n                   SUM(amount) AS product_sales\n            FROM orders\n            WHERE region IN (SELECT region FROM top_regions)\n            GROUP BY region, product;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(TableId(\"orders\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createAsQueryTest0() {\n        val sql = \"\"\"\n            CREATE TABLE films_recent AS\n            SELECT * FROM films WHERE date_prod >= '2002-01-01';\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateTableAsSelect) {\n            Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n            Assert.assertEquals(\"films_recent\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(\"films\", statement.queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest0() {\n        val sql = \"\"\"\n            DELETE FROM films\n            WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest1() {\n        val sql = \"\"\"\n            DELETE FROM films USING producers\n            WHERE producer_id = producers.id AND producers.name = 'foo';\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n\n            Assert.assertEquals(\"producers\", statement.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest0() {\n        val sql = \"\"\"\n            UPDATE employees SET sales_count = sales_count + 1 WHERE id =\n            (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest1() {\n        val sql = \"\"\"\n            UPDATE product p\n            SET net_price = price - price * discount\n            FROM product_segment s\n            WHERE p.segment_id = s.id;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"product\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n\n            Assert.assertEquals(\"product_segment\", statement.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest0() {\n        val sql = \"\"\"\n            INSERT INTO films (code, title, did, date_prod, kind) VALUES\n            ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),\n            ('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(0, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest1() {\n        val sql = \"\"\"\n            WITH upd AS (\n              UPDATE employees SET sales_count = sales_count + 1 WHERE id =\n                (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation')\n                RETURNING *\n            )\n            INSERT INTO employees_log SELECT *, current_timestamp FROM upd;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"employees_log\", statement.tableId?.tableName)\n            Assert.assertEquals(2, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest2() {\n        val sql = \"\"\"\n            truncate table films\n            INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';\n        \"\"\".trimIndent()\n\n        val statements = PostgreSqlHelper.parseMultiStatement(sql)\n        var statement = statements.get(0)\n        if (statement is TruncateTable) {\n            Assert.assertEquals(StatementType.TRUNCATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n\n        statement = statements.get(1)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deltaMergeTest() {\n        val sql = \"\"\"\n            MERGE INTO wines w\n            USING wine_stock_changes s\n            ON s.winename = w.winename\n            WHEN NOT MATCHED AND s.stock_delta > 0 THEN\n              INSERT VALUES(s.winename, s.stock_delta)\n            WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN\n              UPDATE SET stock = w.stock + s.stock_delta\n            WHEN MATCHED THEN\n              DELETE;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is MergeTable) {\n            Assert.assertEquals(StatementType.MERGE, statement.statementType)\n            Assert.assertEquals(\"wines\", statement.targetTable.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-postgres-parser/src/test/java/io/github/melin/superior/parser/postgre/PostgreSqlProcessParserTest.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.ProcedureId\nimport io.github.melin.superior.common.relational.create.CreateFunction\nimport io.github.melin.superior.common.relational.create.CreateProcedure\nimport org.junit.Assert\nimport org.junit.Test\n\nclass PostgreSqlProcessParserTest {\n    @Test\n    fun createFunctionTest() {\n        val sql = \"\"\"\n            CREATE FUNCTION public.myadd(integer, integer) RETURNS integer\n            AS 'select ${'$'}1 + ${'$'}2;'\n            LANGUAGE SQL\n            IMMUTABLE\n            RETURNS NULL ON NULL INPUT;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateFunction) {\n            Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId(\"public\", \"myadd\"), statement.functionId)\n            Assert.assertEquals(\"myadd\", statement.functionId.functionName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFunctionTest1() {\n        val sql = \"\"\"\n            CREATE FUNCTION myadd(integer, integer) RETURNS integer\n            AS 'select ${'$'}1 + ${'$'}2;'\n            LANGUAGE SQL\n            IMMUTABLE\n            RETURNS NULL ON NULL INPUT;\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateFunction) {\n            Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId(\"myadd\"), statement.functionId)\n            Assert.assertEquals(\"myadd\", statement.functionId.functionName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFunctionTest2() {\n        val sql = \"\"\"\n            CREATE FUNCTION check_password(uname TEXT, pass TEXT)\n            RETURNS BOOLEAN AS ${'$'}${'$'}\n            DECLARE passed BOOLEAN;\n            BEGIN\n                SELECT  (pwd = ${'$'}2) INTO passed\n                FROM    pwds\n                WHERE   username = ${'$'}1;\n                RETURN passed;\n                \n                update accounts_2\n                set balance = balance + amount \n                where id = receiver;\n            END;\n            ${'$'}${'$'}  LANGUAGE plpgsql\n                SECURITY DEFINER\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateFunction) {\n            Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId( \"check_password\"), statement.functionId)\n            Assert.assertEquals(2, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n\n\n    @Test\n    fun createFunctionTest3() {\n        val sql = \"\"\"\n            create or replace procedure prac_transfer(\n               sender int,\n               receiver int, \n               amount dec\n            )\n            LANGUAGE plpgsql\n            as ${'$'}${'$'}\n            DECLARE\n               max_rk int;\n               max_trade_time_length int;\n               max_trade_time character varying;\n            BEGIN\n                update accounts_1\n                set balance = balance - amount \n                where id = sender;\n            \n                update accounts_2\n                set balance = balance + amount \n                where id = receiver;\n            \n                commit;\n            END;${'$'}${'$'};\n            \n            create or replace procedure prac_transfer1(\n                           sender int,\n                           receiver int, \n                           amount dec\n                        )\n                        LANGUAGE plpgsql\n                        as ${'$'}${'$'}\n                        DECLARE\n                           max_rk int;\n                           max_trade_time_length int;\n                           max_trade_time character varying;\n                        BEGIN\n                            update accounts_1\n                            set balance = balance - amount \n                            where id = sender;\n                        \n                            update accounts_2\n                            set balance = balance + amount \n                            where id = receiver;\n                        \n                            commit;\n                        END;${'$'}${'$'};\n        \"\"\".trimIndent()\n\n        val statements = PostgreSqlHelper.parseMultiStatement(sql)\n        val statement = statements.get(0)\n        \n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(ProcedureId( \"prac_transfer\"), statement.procedureId)\n            Assert.assertEquals(2, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFunctionTest4() {\n        val sql = \"\"\"\n            create or replace procedure prac_transfer(\n               sender int,\n               receiver int, \n               amount dec\n            )\n             RETURNS SETOF record\n             LANGUAGE plpgsql\n             NOT FENCED NOT SHIPPABLE\n            as ${'$'}${'$'}\n            BEGIN\n                update accounts\n                set balance = balance - amount \n                where id = sender;\n            \n                update accounts\n                set balance = balance + amount \n                where id = receiver;\n            \n                commit;\n            END;${'$'}${'$'};\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(ProcedureId( \"prac_transfer\"), statement.procedureId)\n            Assert.assertEquals(2, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFunctionTest5() {\n        val sql = \"\"\"\n            CREATE OR REPLACE FUNCTION fetch_film_titles_and_years(\n               OUT p_title VARCHAR(255), \n               OUT p_release_year INTEGER\n            )\n            RETURNS SETOF RECORD \n            LANGUAGE plpgsql\n            AS ${'$'}${'$'}\n            DECLARE\n                film_cursor CURSOR FOR\n                    SELECT title, release_year\n                    FROM film;\n                film_record RECORD;\n            BEGIN\n                -- Open cursor\n                OPEN film_cursor;\n            \n                -- Fetch rows and return\n                LOOP\n                    FETCH NEXT FROM film_cursor INTO film_record;\n                    EXIT WHEN NOT FOUND;\n            \n                    p_title = film_record.title;\n                    p_release_year = film_record.release_year;\n                    RETURN NEXT;\n                END LOOP;\n            \n                -- Close cursor\n                CLOSE film_cursor;\n                \n                update accounts\n                set balance = balance + amount \n                where id = receiver;\n            END;\n            ${'$'}${'$'}\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n\n        if (statement is CreateFunction) {\n            Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId( \"fetch_film_titles_and_years\"), statement.functionId)\n            Assert.assertEquals(2, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFunctionTest6() {\n        val sql = \"\"\"\n            create or replace procedure prac_transfer(\n               sender int,\n               receiver int, \n               amount dec\n            )\n             RETURNS SETOF record\n             LANGUAGE plpgsql\n             NOT FENCED NOT SHIPPABLE\n            as ${'$'}${'$'}\n            BEGIN\n                update accounts\n                set balance = balance - amount \n                where id = sender;            \n                commit;\n            END;${'$'}${'$'};\n            \n            create or replace procedure prac_transfer1(\n               sender int,\n               receiver int, \n               amount dec\n            )\n             RETURNS SETOF record\n             LANGUAGE plpgsql\n             NOT FENCED NOT SHIPPABLE\n            as ${'$'}${'$'}\n            BEGIN\n                update accounts_1\n                set balance = balance - amount \n                where id = sender;            \n                commit;\n            END;${'$'}${'$'};\n        \"\"\".trimIndent()\n\n        val statements = PostgreSqlHelper.parseMultiStatement(sql)\n        Assert.assertEquals(2, statements.size)\n        var statement = statements.get(0)\n\n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(ProcedureId( \"prac_transfer\"), statement.procedureId)\n            Assert.assertEquals(1, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n\n        statement = statements.get(1)\n\n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(ProcedureId( \"prac_transfer1\"), statement.procedureId)\n            Assert.assertEquals(1, statement.childStatements.size)\n            Assert.assertEquals(\"update accounts_1\\n\" +\n                    \"    set balance = balance - amount \\n\" +\n                    \"    where id = sender\", statement.childStatements.get(0).getSql())\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun processTest5() {\n        val sql = \"\"\"\n            CREATE FUNCTION get_bal(acc_no IN NUMBER) \n            RETURNS SETOF record\n             LANGUAGE plpgsql\n             NOT FENCED NOT SHIPPABLE\n            as ${'$'}${'$'}\n            BEGIN \n               INSERT INTO widgets(map_id,widget_name)\n                SELECT mt.map_id, 'Bupo'\n                FROM map_tags mt\n                WHERE mt.map_license = '12345';\n             END ${'$'}${'$'};\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n\n        if (statement is CreateFunction) {\n            Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId(\"get_bal\"), statement.functionId)\n            Assert.assertEquals(1, statement.childStatements.size)\n            Assert.assertEquals(StatementType.INSERT, statement.childStatements.get(0).statementType)\n        } else {\n            Assert.fail()\n        }\n\n    }\n\n    @Test\n    fun processTest6() {\n        val sql = \"\"\"\n            create or replace procedure prac_transfer(\n               sender int,\n               receiver int, \n               amount dec\n            )\n            LANGUAGE plpgsql\n            as ${'$'}${'$'}\n            BEGIN \n               EXECUTE IMMEDIATE '\n                    CREATE TABLE schema1.test_table_s1 (\n                        id NUMBER PRIMARY KEY,\n                        name VARCHAR2(100)\n                    )\n                ';\n\n               EXECUTE IMMEDIATE 'INSERT INTO schema1.test_table_s1 (id, name) VALUES (1, ''Alice'')';        \n             END ${'$'}${'$'};\n        \"\"\".trimIndent()\n\n        val statement = PostgreSqlHelper.parseStatement(sql)\n\n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(ProcedureId(\"prac_transfer\"), statement.procedureId)\n            Assert.assertEquals(2, statement.childStatements.size)\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.childStatements.get(0).statementType)\n            Assert.assertEquals(StatementType.INSERT, statement.childStatements.get(1).statementType)\n            Assert.assertEquals(\"INSERT INTO schema1.test_table_s1 (id, name) VALUES (1, 'Alice')\", statement.childStatements.get(1).getSql())\n        } else {\n            Assert.fail()\n        }\n\n    }\n}"
  },
  {
    "path": "superior-postgres-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-presto-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-presto-parser</artifactId>\n    <name>superior-presto-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "superior-presto-parser/src/main/antlr4/io/github/melin/superior/parser/presto/antlr4/PrestoSqlBase.g4",
    "content": "/*\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ngrammar PrestoSqlBase;\n\ntokens {\n    DELIMITER\n}\n\nsqlStatements\n    : singleStatement* EOF\n    ;\n\nsingleStatement\n    : statement ';'?\n    ;\n\nstandaloneExpression\n    : expression EOF\n    ;\n\nstandaloneRoutineBody\n    : routineBody EOF\n    ;\n\nstatement\n    : query                                                            #statementDefault\n    | USE schema=identifier                                            #use\n    | USE catalog=identifier '.' schema=identifier                     #use\n    | CREATE SCHEMA (IF NOT EXISTS)? qualifiedName\n        (WITH properties)?                                             #createSchema\n    | DROP SCHEMA (IF EXISTS)? qualifiedName (CASCADE | RESTRICT)?     #dropSchema\n    | ALTER SCHEMA qualifiedName RENAME TO identifier                  #renameSchema\n    | CREATE TABLE (IF NOT EXISTS)? qualifiedName columnAliases?\n        (COMMENT string)?\n        (WITH properties)? AS (query | '('query')')\n        (WITH (NO)? DATA)?                                             #createTableAsSelect\n    | CREATE TABLE (IF NOT EXISTS)? qualifiedName\n        '(' tableElement (',' tableElement)* ')'\n         (COMMENT string)?\n         (WITH properties)?                                            #createTable\n    | DROP TABLE (IF EXISTS)? qualifiedName                            #dropTable\n    | INSERT INTO qualifiedName columnAliases? query                   #insertInto\n    | DELETE FROM qualifiedName whereClause?                           #delete\n    | TRUNCATE TABLE qualifiedName                                     #truncateTable\n    | ALTER TABLE (IF EXISTS)? from=qualifiedName\n        RENAME TO to=qualifiedName                                     #renameTable\n    | ALTER TABLE (IF EXISTS)? tableName=qualifiedName\n        RENAME COLUMN (IF EXISTS)? from=identifier TO to=identifier    #renameColumn\n    | ALTER TABLE (IF EXISTS)? tableName=qualifiedName\n        DROP COLUMN (IF EXISTS)? column=qualifiedName                  #dropColumn\n    | ALTER TABLE (IF EXISTS)? tableName=qualifiedName\n        ADD COLUMN (IF NOT EXISTS)? column=columnDefinition            #addColumn\n    | ANALYZE qualifiedName (WITH properties)?                         #analyze\n    | CREATE TYPE qualifiedName AS (\n        '(' sqlParameterDeclaration (',' sqlParameterDeclaration)* ')'\n        | type)                                                        #createType\n    | CREATE (OR REPLACE)? VIEW qualifiedName\n            (SECURITY (DEFINER | INVOKER))? AS query                   #createView\n    | DROP VIEW (IF EXISTS)? qualifiedName                             #dropView\n    | CREATE MATERIALIZED VIEW (IF NOT EXISTS)? qualifiedName\n        (COMMENT string)?\n        (WITH properties)? AS (query | '('query')')                    #createMaterializedView\n    | DROP MATERIALIZED VIEW (IF EXISTS)? qualifiedName                #dropMaterializedView\n    | REFRESH MATERIALIZED VIEW qualifiedName WHERE booleanExpression  #refreshMaterializedView\n    | CREATE (OR REPLACE)? TEMPORARY? FUNCTION functionName=qualifiedName\n        '(' (sqlParameterDeclaration (',' sqlParameterDeclaration)*)? ')'\n        RETURNS returnType=type\n        (COMMENT string)?\n        routineCharacteristics routineBody                             #createFunction\n    | ALTER FUNCTION qualifiedName types?\n      alterRoutineCharacteristics                                      #alterFunction\n    | DROP TEMPORARY? FUNCTION (IF EXISTS)? qualifiedName types?       #dropFunction\n    | CALL qualifiedName '(' (callArgument (',' callArgument)*)? ')'   #call\n    | CREATE ROLE name=identifier\n        (WITH ADMIN grantor)?                                          #createRole\n    | DROP ROLE name=identifier                                        #dropRole\n    | GRANT\n        roles\n        TO principal (',' principal)*\n        (WITH ADMIN OPTION)?\n        (GRANTED BY grantor)?                                          #grantRoles\n    | REVOKE\n        (ADMIN OPTION FOR)?\n        roles\n        FROM principal (',' principal)*\n        (GRANTED BY grantor)?                                          #revokeRoles\n    | SET ROLE (ALL | NONE | role=identifier)                          #setRole\n    | GRANT\n        (privilege (',' privilege)* | ALL PRIVILEGES)\n        ON TABLE? qualifiedName TO grantee=principal\n        (WITH GRANT OPTION)?                                           #grant\n    | REVOKE\n        (GRANT OPTION FOR)?\n        (privilege (',' privilege)* | ALL PRIVILEGES)\n        ON TABLE? qualifiedName FROM grantee=principal                #revoke\n    | SHOW GRANTS\n        (ON TABLE? qualifiedName)?                                     #showGrants\n    | EXPLAIN ANALYZE? VERBOSE?\n        ('(' explainOption (',' explainOption)* ')')? statement        #explain\n    | SHOW CREATE TABLE qualifiedName                                  #showCreateTable\n    | SHOW CREATE VIEW qualifiedName                                   #showCreateView\n    | SHOW CREATE MATERIALIZED VIEW qualifiedName                      #showCreateMaterializedView\n    | SHOW CREATE FUNCTION qualifiedName types?                        #showCreateFunction\n    | SHOW TABLES ((FROM | IN) qualifiedName)?\n        (LIKE pattern=string (ESCAPE escape=string)?)?                 #showTables\n    | SHOW SCHEMAS ((FROM | IN) identifier)?\n        (LIKE pattern=string (ESCAPE escape=string)?)?                 #showSchemas\n    | SHOW CATALOGS\n        (LIKE pattern=string (ESCAPE escape=string)?)?                 #showCatalogs\n    | SHOW COLUMNS (FROM | IN) qualifiedName                           #showColumns\n    | SHOW STATS FOR qualifiedName                                     #showStats\n    | SHOW STATS FOR '(' querySpecification ')'                        #showStatsForQuery\n    | SHOW CURRENT? ROLES ((FROM | IN) identifier)?                    #showRoles\n    | SHOW ROLE GRANTS ((FROM | IN) identifier)?                       #showRoleGrants\n    | DESCRIBE qualifiedName                                           #showColumns\n    | DESC qualifiedName                                               #showColumns\n    | SHOW FUNCTIONS\n        (LIKE pattern=string (ESCAPE escape=string)?)?                 #showFunctions\n    | SHOW SESSION\n        (LIKE pattern=string (ESCAPE escape=string)?)?                 #showSession\n    | SET SESSION qualifiedName EQ expression                          #setSession\n    | RESET SESSION qualifiedName                                      #resetSession\n    | START TRANSACTION (transactionMode (',' transactionMode)*)?      #startTransaction\n    | COMMIT WORK?                                                     #commit\n    | ROLLBACK WORK?                                                   #rollback\n    | PREPARE identifier FROM statement                                #prepare\n    | DEALLOCATE PREPARE identifier                                    #deallocate\n    | EXECUTE identifier (USING expression (',' expression)*)?         #execute\n    | DESCRIBE INPUT identifier                                        #describeInput\n    | DESCRIBE OUTPUT identifier                                       #describeOutput\n    ;\n\nquery\n    :  with? queryNoWith\n    ;\n\nwith\n    : WITH RECURSIVE? namedQuery (',' namedQuery)*\n    ;\n\ntableElement\n    : columnDefinition\n    | likeClause\n    ;\n\ncolumnDefinition\n    : identifier type (NOT NULL)? (COMMENT string)? (WITH properties)?\n    ;\n\nlikeClause\n    : LIKE qualifiedName (optionType=(INCLUDING | EXCLUDING) PROPERTIES)?\n    ;\n\nproperties\n    : '(' property (',' property)* ')'\n    ;\n\nproperty\n    : identifier EQ expression\n    ;\n\nsqlParameterDeclaration\n    : identifier type\n    ;\n\nroutineCharacteristics\n    : routineCharacteristic*\n    ;\n\nroutineCharacteristic\n    : LANGUAGE language\n    | determinism\n    | nullCallClause\n    ;\n\nalterRoutineCharacteristics\n    : alterRoutineCharacteristic*\n    ;\n\nalterRoutineCharacteristic\n    : nullCallClause\n    ;\n\nroutineBody\n    : returnStatement\n    | externalBodyReference\n    ;\n\nreturnStatement\n    : RETURN expression\n    ;\n\nexternalBodyReference\n    : EXTERNAL (NAME externalRoutineName)?\n    ;\n\nlanguage\n    : SQL\n    | identifier\n    ;\n\ndeterminism\n    : DETERMINISTIC\n    | NOT DETERMINISTIC;\n\nnullCallClause\n    : RETURNS NULL ON NULL INPUT\n    | CALLED ON NULL INPUT\n    ;\n\nexternalRoutineName\n    : identifier\n    ;\n\nqueryNoWith:\n      queryTerm\n      (ORDER BY sortItem (',' sortItem)*)?\n      (OFFSET offset=INTEGER_VALUE (ROW | ROWS)?)?\n      ((LIMIT limit=(INTEGER_VALUE | ALL) | (FETCH FIRST fetchFirstNRows=INTEGER_VALUE ROWS ONLY))?)?\n    ;\n\nqueryTerm\n    : queryPrimary                                                             #queryTermDefault\n    | left=queryTerm operator=INTERSECT setQuantifier? right=queryTerm         #setOperation\n    | left=queryTerm operator=(UNION | EXCEPT) setQuantifier? right=queryTerm  #setOperation\n    ;\n\nqueryPrimary\n    : querySpecification                   #queryPrimaryDefault\n    | TABLE qualifiedName                  #table\n    | VALUES expression (',' expression)*  #inlineTable\n    | '(' queryNoWith  ')'                 #subquery\n    ;\n\nsortItem\n    : expression ordering=(ASC | DESC)? (NULLS nullOrdering=(FIRST | LAST))?\n    ;\n\nquerySpecification\n    : SELECT setQuantifier? selectItem (',' selectItem)*\n      (FROM relation (',' relation)*)?\n      (WHERE where=booleanExpression)?\n      (GROUP BY groupBy)?\n      (HAVING having=booleanExpression)?\n    ;\n\ngroupBy\n    : setQuantifier? groupingElement (',' groupingElement)*\n    ;\n\ngroupingElement\n    : groupingSet                                            #singleGroupingSet\n    | ROLLUP '(' (expression (',' expression)*)? ')'         #rollup\n    | CUBE '(' (expression (',' expression)*)? ')'           #cube\n    | GROUPING SETS '(' groupingSet (',' groupingSet)* ')'   #multipleGroupingSets\n    ;\n\ngroupingSet\n    : '(' (expression (',' expression)*)? ')'\n    | expression\n    ;\n\nnamedQuery\n    : name=identifier (columnAliases)? AS '(' query ')'\n    ;\n\nsetQuantifier\n    : DISTINCT\n    | ALL\n    ;\n\nselectItem\n    : expression (AS? identifier)?  #selectSingle\n    | qualifiedName '.' ASTERISK    #selectAll\n    | ASTERISK                      #selectAll\n    ;\n\nrelation\n    : left=relation\n      ( CROSS JOIN right=sampledRelation\n      | joinType JOIN rightRelation=relation joinCriteria\n      | NATURAL joinType JOIN right=sampledRelation\n      )                                           #joinRelation\n    | sampledRelation                             #relationDefault\n    ;\n\njoinType\n    : INNER?\n    | LEFT OUTER?\n    | RIGHT OUTER?\n    | FULL OUTER?\n    ;\n\njoinCriteria\n    : ON booleanExpression\n    | USING '(' identifier (',' identifier)* ')'\n    ;\n\nsampledRelation\n    : aliasedRelation (\n        TABLESAMPLE sampleType '(' percentage=expression ')'\n      )?\n    ;\n\nsampleType\n    : BERNOULLI\n    | SYSTEM\n    ;\n\naliasedRelation\n    : relationPrimary (AS? identifier columnAliases?)?\n    ;\n\ncolumnAliases\n    : '(' identifier (',' identifier)* ')'\n    ;\n\nrelationPrimary\n    : qualifiedName                                                   #tableName\n    | '(' query ')'                                                   #subqueryRelation\n    | UNNEST '(' expression (',' expression)* ')' (WITH ORDINALITY)?  #unnest\n    | LATERAL '(' query ')'                                           #lateral\n    | '(' relation ')'                                                #parenthesizedRelation\n    ;\n\nexpression\n    : booleanExpression\n    ;\n\nwhereClause\n    : WHERE booleanExpression\n    ;\n\nbooleanExpression\n    : valueExpression predicate[$valueExpression.ctx]?             #predicated\n    | NOT booleanExpression                                        #logicalNot\n    | left=booleanExpression operator=AND right=booleanExpression  #logicalBinary\n    | left=booleanExpression operator=OR right=booleanExpression   #logicalBinary\n    ;\n\n// workaround for https://github.com/antlr/antlr4/issues/780\npredicate[ParserRuleContext value]\n    : comparisonOperator right=valueExpression                            #comparison\n    | comparisonOperator comparisonQuantifier '(' query ')'               #quantifiedComparison\n    | NOT? BETWEEN lower=valueExpression AND upper=valueExpression        #between\n    | NOT? IN '(' expression (',' expression)* ')'                        #inList\n    | NOT? IN '(' query ')'                                               #inSubquery\n    | NOT? LIKE pattern=valueExpression (ESCAPE escape=valueExpression)?  #like\n    | IS NOT? NULL                                                        #nullPredicate\n    | IS NOT? DISTINCT FROM right=valueExpression                         #distinctFrom\n    ;\n\nvalueExpression\n    : primaryExpression                                                                 #valueExpressionDefault\n    | valueExpression AT timeZoneSpecifier                                              #atTimeZone\n    | operator=(MINUS | PLUS) valueExpression                                           #arithmeticUnary\n    | left=valueExpression operator=(ASTERISK | SLASH | PERCENT) right=valueExpression  #arithmeticBinary\n    | left=valueExpression operator=(PLUS | MINUS) right=valueExpression                #arithmeticBinary\n    | left=valueExpression CONCAT right=valueExpression                                 #concatenation\n    ;\n\nprimaryExpression\n    : NULL                                                                                #nullLiteral\n    | interval                                                                            #intervalLiteral\n    | identifier string                                                                   #typeConstructor\n    | DOUBLE_PRECISION string                                                             #typeConstructor\n    | number                                                                              #numericLiteral\n    | booleanValue                                                                        #booleanLiteral\n    | string                                                                              #stringLiteral\n    | BINARY_LITERAL                                                                      #binaryLiteral\n    | '?'                                                                                 #parameter\n    | POSITION '(' valueExpression IN valueExpression ')'                                 #position\n    | '(' expression (',' expression)+ ')'                                                #rowConstructor\n    | ROW '(' expression (',' expression)* ')'                                            #rowConstructor\n    | qualifiedName '(' ASTERISK ')' filter? over?                                        #functionCall\n    | qualifiedName '(' (setQuantifier? expression (',' expression)*)?\n        (ORDER BY sortItem (',' sortItem)*)? ')' filter? (nullTreatment? over)?           #functionCall\n    | identifier '->' expression                                                          #lambda\n    | '(' (identifier (',' identifier)*)? ')' '->' expression                             #lambda\n    | '(' query ')'                                                                       #subqueryExpression\n    // This is an extension to ANSI SQL, which considers EXISTS to be a <boolean expression>\n    | EXISTS '(' query ')'                                                                #exists\n    | CASE valueExpression whenClause+ (ELSE elseExpression=expression)? END              #simpleCase\n    | CASE whenClause+ (ELSE elseExpression=expression)? END                              #searchedCase\n    | CAST '(' expression AS type ')'                                                     #cast\n    | TRY_CAST '(' expression AS type ')'                                                 #cast\n    | ARRAY '[' (expression (',' expression)*)? ']'                                       #arrayConstructor\n    | value=primaryExpression '[' index=valueExpression ']'                               #subscript\n    | identifier                                                                          #columnReference\n    | base=primaryExpression '.' fieldName=identifier                                     #dereference\n    | name=CURRENT_DATE                                                                   #specialDateTimeFunction\n    | name=CURRENT_TIME ('(' precision=INTEGER_VALUE ')')?                                #specialDateTimeFunction\n    | name=CURRENT_TIMESTAMP ('(' precision=INTEGER_VALUE ')')?                           #specialDateTimeFunction\n    | name=LOCALTIME ('(' precision=INTEGER_VALUE ')')?                                   #specialDateTimeFunction\n    | name=LOCALTIMESTAMP ('(' precision=INTEGER_VALUE ')')?                              #specialDateTimeFunction\n    | name=CURRENT_USER                                                                   #currentUser\n    | SUBSTRING '(' valueExpression FROM valueExpression (FOR valueExpression)? ')'       #substring\n    | NORMALIZE '(' valueExpression (',' normalForm)? ')'                                 #normalize\n    | EXTRACT '(' identifier FROM valueExpression ')'                                     #extract\n    | '(' expression ')'                                                                  #parenthesizedExpression\n    | GROUPING '(' (qualifiedName (',' qualifiedName)*)? ')'                              #groupingOperation\n    ;\n\nstring\n    : STRING                                #basicStringLiteral\n    | UNICODE_STRING (UESCAPE STRING)?      #unicodeStringLiteral\n    ;\n\nnullTreatment\n    : IGNORE NULLS\n    | RESPECT NULLS\n    ;\n\ntimeZoneSpecifier\n    : TIME ZONE interval  #timeZoneInterval\n    | TIME ZONE string    #timeZoneString\n    ;\n\ncomparisonOperator\n    : EQ | NEQ | LT | LTE | GT | GTE\n    ;\n\ncomparisonQuantifier\n    : ALL | SOME | ANY\n    ;\n\nbooleanValue\n    : TRUE | FALSE\n    ;\n\ninterval\n    : INTERVAL sign=(PLUS | MINUS)? string from=intervalField (TO to=intervalField)?\n    ;\n\nintervalField\n    : YEAR | MONTH | DAY | HOUR | MINUTE | SECOND\n    ;\n\nnormalForm\n    : NFD | NFC | NFKD | NFKC\n    ;\n\ntypes\n    : '(' (type (',' type)*)? ')'\n    ;\n\ntype\n    : type ARRAY\n    | ARRAY '<' type '>'\n    | MAP '<' type ',' type '>'\n    | ROW '(' identifier type (',' identifier type)* ')'\n    | baseType ('(' typeParameter (',' typeParameter)* ')')?\n    | INTERVAL from=intervalField TO to=intervalField\n    ;\n\ntypeParameter\n    : INTEGER_VALUE | type\n    ;\n\nbaseType\n    : TIME_WITH_TIME_ZONE\n    | TIMESTAMP_WITH_TIME_ZONE\n    | DOUBLE_PRECISION\n    | qualifiedName\n    ;\n\nwhenClause\n    : WHEN condition=expression THEN result=expression\n    ;\n\nfilter\n    : FILTER '(' WHERE booleanExpression ')'\n    ;\n\nover\n    : OVER '('\n        (PARTITION BY partition+=expression (',' partition+=expression)*)?\n        (ORDER BY sortItem (',' sortItem)*)?\n        windowFrame?\n      ')'\n    ;\n\nwindowFrame\n    : frameType=RANGE start=frameBound\n    | frameType=ROWS start=frameBound\n    | frameType=GROUPS start=frameBound\n    | frameType=RANGE BETWEEN start=frameBound AND end=frameBound\n    | frameType=ROWS BETWEEN start=frameBound AND end=frameBound\n    | frameType=GROUPS BETWEEN start=frameBound AND end=frameBound\n    ;\n\nframeBound\n    : UNBOUNDED boundType=PRECEDING                 #unboundedFrame\n    | UNBOUNDED boundType=FOLLOWING                 #unboundedFrame\n    | CURRENT ROW                                   #currentRowBound\n    | expression boundType=(PRECEDING | FOLLOWING)  #boundedFrame // expression should be unsignedLiteral\n    ;\n\n\nexplainOption\n    : FORMAT value=(TEXT | GRAPHVIZ | JSON)                 #explainFormat\n    | TYPE value=(LOGICAL | DISTRIBUTED | VALIDATE | IO)    #explainType\n    ;\n\ntransactionMode\n    : ISOLATION LEVEL levelOfIsolation    #isolationLevel\n    | READ accessMode=(ONLY | WRITE)      #transactionAccessMode\n    ;\n\nlevelOfIsolation\n    : READ UNCOMMITTED                    #readUncommitted\n    | READ COMMITTED                      #readCommitted\n    | REPEATABLE READ                     #repeatableRead\n    | SERIALIZABLE                        #serializable\n    ;\n\ncallArgument\n    : expression                    #positionalArgument\n    | identifier '=>' expression    #namedArgument\n    ;\n\nprivilege\n    : SELECT | DELETE | INSERT | identifier\n    ;\n\nqualifiedName\n    : identifier ('.' identifier)*\n    ;\n\ngrantor\n    : CURRENT_USER          #currentUserGrantor\n    | CURRENT_ROLE          #currentRoleGrantor\n    | principal             #specifiedPrincipal\n    ;\n\nprincipal\n    : USER identifier       #userPrincipal\n    | ROLE identifier       #rolePrincipal\n    | identifier            #unspecifiedPrincipal\n    ;\n\nroles\n    : identifier (',' identifier)*\n    ;\n\nidentifier\n    : IDENTIFIER             #unquotedIdentifier\n    | QUOTED_IDENTIFIER      #quotedIdentifier\n    | nonReserved            #unquotedIdentifier\n    | BACKQUOTED_IDENTIFIER  #backQuotedIdentifier\n    | DIGIT_IDENTIFIER       #digitIdentifier\n    ;\n\nnumber\n    : DECIMAL_VALUE  #decimalLiteral\n    | DOUBLE_VALUE   #doubleLiteral\n    | INTEGER_VALUE  #integerLiteral\n    ;\n\nnonReserved\n    // IMPORTANT: this rule must only contain tokens. Nested rules are not supported. See SqlParser.exitNonReserved\n    : ADD | ADMIN | ALL | ANALYZE | ANY | ARRAY | ASC | AT\n    | BERNOULLI\n    | CALL | CALLED | CASCADE | CATALOGS | COLUMN | COLUMNS | COMMENT | COMMIT | COMMITTED | CURRENT | CURRENT_ROLE\n    | DATA | DATE | DAY | DEFINER | DESC | DETERMINISTIC | DISTRIBUTED\n    | EXCLUDING | EXPLAIN | EXTERNAL\n    | FETCH | FILTER | FIRST | FOLLOWING | FORMAT | FUNCTION | FUNCTIONS\n    | GRANT | GRANTED | GRANTS | GRAPHVIZ | GROUPS\n    | HOUR\n    | IF | IGNORE | INCLUDING | INPUT | INTERVAL | INVOKER | IO | ISOLATION\n    | JSON\n    | LANGUAGE | LAST | LATERAL | LEVEL | LIMIT | LOGICAL\n    | MAP | MATERIALIZED | MINUTE | MONTH\n    | NAME | NFC | NFD | NFKC | NFKD | NO | NONE | NULLIF | NULLS\n    | OFFSET | ONLY | OPTION | ORDINALITY | OUTPUT | OVER\n    | PARTITION | PARTITIONS | POSITION | PRECEDING | PRIVILEGES | PROPERTIES\n    | RANGE | READ | REFRESH | RENAME | REPEATABLE | REPLACE | RESET | RESPECT | RESTRICT | RETURN | RETURNS | REVOKE | ROLE | ROLES | ROLLBACK | ROW | ROWS\n    | SCHEMA | SCHEMAS | SECOND | SECURITY | SERIALIZABLE | SESSION | SET | SETS | SQL\n    | SHOW | SOME | START | STATS | SUBSTRING | SYSTEM\n    | TABLES | TABLESAMPLE | TEMPORARY | TEXT | TIME | TIMESTAMP | TO | TRANSACTION | TRUNCATE | TRY_CAST | TYPE\n    | UNBOUNDED | UNCOMMITTED | USE | USER\n    | VALIDATE | VERBOSE | VIEW\n    | WORK | WRITE\n    | YEAR\n    | ZONE\n    ;\n\nADD: 'ADD';\nADMIN: 'ADMIN';\nALL: 'ALL';\nALTER: 'ALTER';\nANALYZE: 'ANALYZE';\nAND: 'AND';\nANY: 'ANY';\nARRAY: 'ARRAY';\nAS: 'AS';\nASC: 'ASC';\nAT: 'AT';\nBERNOULLI: 'BERNOULLI';\nBETWEEN: 'BETWEEN';\nBY: 'BY';\nCALL: 'CALL';\nCALLED: 'CALLED';\nCASCADE: 'CASCADE';\nCASE: 'CASE';\nCAST: 'CAST';\nCATALOGS: 'CATALOGS';\nCOLUMN: 'COLUMN';\nCOLUMNS: 'COLUMNS';\nCOMMENT: 'COMMENT';\nCOMMIT: 'COMMIT';\nCOMMITTED: 'COMMITTED';\nCONSTRAINT: 'CONSTRAINT';\nCREATE: 'CREATE';\nCROSS: 'CROSS';\nCUBE: 'CUBE';\nCURRENT: 'CURRENT';\nCURRENT_DATE: 'CURRENT_DATE';\nCURRENT_ROLE: 'CURRENT_ROLE';\nCURRENT_TIME: 'CURRENT_TIME';\nCURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP';\nCURRENT_USER: 'CURRENT_USER';\nDATA: 'DATA';\nDATE: 'DATE';\nDAY: 'DAY';\nDEALLOCATE: 'DEALLOCATE';\nDEFINER: 'DEFINER';\nDELETE: 'DELETE';\nDESC: 'DESC';\nDESCRIBE: 'DESCRIBE';\nDETERMINISTIC: 'DETERMINISTIC';\nDISTINCT: 'DISTINCT';\nDISTRIBUTED: 'DISTRIBUTED';\nDROP: 'DROP';\nELSE: 'ELSE';\nEND: 'END';\nESCAPE: 'ESCAPE';\nEXCEPT: 'EXCEPT';\nEXCLUDING: 'EXCLUDING';\nEXECUTE: 'EXECUTE';\nEXISTS: 'EXISTS';\nEXPLAIN: 'EXPLAIN';\nEXTRACT: 'EXTRACT';\nEXTERNAL: 'EXTERNAL';\nFALSE: 'FALSE';\nFETCH: 'FETCH';\nFILTER: 'FILTER';\nFIRST: 'FIRST';\nFOLLOWING: 'FOLLOWING';\nFOR: 'FOR';\nFORMAT: 'FORMAT';\nFROM: 'FROM';\nFULL: 'FULL';\nFUNCTION: 'FUNCTION';\nFUNCTIONS: 'FUNCTIONS';\nGRANT: 'GRANT';\nGRANTED: 'GRANTED';\nGRANTS: 'GRANTS';\nGRAPHVIZ: 'GRAPHVIZ';\nGROUP: 'GROUP';\nGROUPING: 'GROUPING';\nGROUPS: 'GROUPS';\nHAVING: 'HAVING';\nHOUR: 'HOUR';\nIF: 'IF';\nIGNORE: 'IGNORE';\nIN: 'IN';\nINCLUDING: 'INCLUDING';\nINNER: 'INNER';\nINPUT: 'INPUT';\nINSERT: 'INSERT';\nINTERSECT: 'INTERSECT';\nINTERVAL: 'INTERVAL';\nINTO: 'INTO';\nINVOKER: 'INVOKER';\nIO: 'IO';\nIS: 'IS';\nISOLATION: 'ISOLATION';\nJSON: 'JSON';\nJOIN: 'JOIN';\nLANGUAGE: 'LANGUAGE';\nLAST: 'LAST';\nLATERAL: 'LATERAL';\nLEFT: 'LEFT';\nLEVEL: 'LEVEL';\nLIKE: 'LIKE';\nLIMIT: 'LIMIT';\nLOCALTIME: 'LOCALTIME';\nLOCALTIMESTAMP: 'LOCALTIMESTAMP';\nLOGICAL: 'LOGICAL';\nMAP: 'MAP';\nMATERIALIZED: 'MATERIALIZED';\nMINUTE: 'MINUTE';\nMONTH: 'MONTH';\nNAME: 'NAME';\nNATURAL: 'NATURAL';\nNFC : 'NFC';\nNFD : 'NFD';\nNFKC : 'NFKC';\nNFKD : 'NFKD';\nNO: 'NO';\nNONE: 'NONE';\nNORMALIZE: 'NORMALIZE';\nNOT: 'NOT';\nNULL: 'NULL';\nNULLIF: 'NULLIF';\nNULLS: 'NULLS';\nOFFSET: 'OFFSET';\nON: 'ON';\nONLY: 'ONLY';\nOPTION: 'OPTION';\nOR: 'OR';\nORDER: 'ORDER';\nORDINALITY: 'ORDINALITY';\nOUTER: 'OUTER';\nOUTPUT: 'OUTPUT';\nOVER: 'OVER';\nPARTITION: 'PARTITION';\nPARTITIONS: 'PARTITIONS';\nPOSITION: 'POSITION';\nPRECEDING: 'PRECEDING';\nPREPARE: 'PREPARE';\nPRIVILEGES: 'PRIVILEGES';\nPROPERTIES: 'PROPERTIES';\nRANGE: 'RANGE';\nREAD: 'READ';\nRECURSIVE: 'RECURSIVE';\nREFRESH: 'REFRESH';\nRENAME: 'RENAME';\nREPEATABLE: 'REPEATABLE';\nREPLACE: 'REPLACE';\nRESET: 'RESET';\nRESPECT: 'RESPECT';\nRESTRICT: 'RESTRICT';\nRETURN: 'RETURN';\nRETURNS: 'RETURNS';\nREVOKE: 'REVOKE';\nRIGHT: 'RIGHT';\nROLE: 'ROLE';\nROLES: 'ROLES';\nROLLBACK: 'ROLLBACK';\nROLLUP: 'ROLLUP';\nROW: 'ROW';\nROWS: 'ROWS';\nSCHEMA: 'SCHEMA';\nSCHEMAS: 'SCHEMAS';\nSECOND: 'SECOND';\nSECURITY: 'SECURITY';\nSELECT: 'SELECT';\nSERIALIZABLE: 'SERIALIZABLE';\nSESSION: 'SESSION';\nSET: 'SET';\nSETS: 'SETS';\nSHOW: 'SHOW';\nSOME: 'SOME';\nSQL: 'SQL';\nSTART: 'START';\nSTATS: 'STATS';\nSUBSTRING: 'SUBSTRING';\nSYSTEM: 'SYSTEM';\nTABLE: 'TABLE';\nTABLES: 'TABLES';\nTABLESAMPLE: 'TABLESAMPLE';\nTEMPORARY: 'TEMPORARY';\nTEXT: 'TEXT';\nTHEN: 'THEN';\nTIME: 'TIME';\nTIMESTAMP: 'TIMESTAMP';\nTO: 'TO';\nTRANSACTION: 'TRANSACTION';\nTRUE: 'TRUE';\nTRUNCATE: 'TRUNCATE';\nTRY_CAST: 'TRY_CAST';\nTYPE: 'TYPE';\nUESCAPE: 'UESCAPE';\nUNBOUNDED: 'UNBOUNDED';\nUNCOMMITTED: 'UNCOMMITTED';\nUNION: 'UNION';\nUNNEST: 'UNNEST';\nUSE: 'USE';\nUSER: 'USER';\nUSING: 'USING';\nVALIDATE: 'VALIDATE';\nVALUES: 'VALUES';\nVERBOSE: 'VERBOSE';\nVIEW: 'VIEW';\nWHEN: 'WHEN';\nWHERE: 'WHERE';\nWITH: 'WITH';\nWORK: 'WORK';\nWRITE: 'WRITE';\nYEAR: 'YEAR';\nZONE: 'ZONE';\n\nEQ  : '=';\nNEQ : '<>' | '!=';\nLT  : '<';\nLTE : '<=';\nGT  : '>';\nGTE : '>=';\n\nPLUS: '+';\nMINUS: '-';\nASTERISK: '*';\nSLASH: '/';\nPERCENT: '%';\nCONCAT: '||';\n\nSTRING\n    : '\\'' ( ~'\\'' | '\\'\\'' )* '\\''\n    ;\n\nUNICODE_STRING\n    : 'U&\\'' ( ~'\\'' | '\\'\\'' )* '\\''\n    ;\n\n// Note: we allow any character inside the binary literal and validate\n// its a correct literal when the AST is being constructed. This\n// allows us to provide more meaningful error messages to the user\nBINARY_LITERAL\n    :  'X\\'' (~'\\'')* '\\''\n    ;\n\nINTEGER_VALUE\n    : DIGIT+\n    ;\n\nDECIMAL_VALUE\n    : DIGIT+ '.' DIGIT*\n    | '.' DIGIT+\n    ;\n\nDOUBLE_VALUE\n    : DIGIT+ ('.' DIGIT*)? EXPONENT\n    | '.' DIGIT+ EXPONENT\n    ;\n\nIDENTIFIER\n    : (LETTER | '_') (LETTER | DIGIT | '_' | '@' | ':')*\n    ;\n\nDIGIT_IDENTIFIER\n    : DIGIT (LETTER | DIGIT | '_' | '@' | ':')+\n    ;\n\nQUOTED_IDENTIFIER\n    : '\"' ( ~'\"' | '\"\"' )* '\"'\n    ;\n\nBACKQUOTED_IDENTIFIER\n    : '`' ( ~'`' | '``' )* '`'\n    ;\n\nTIME_WITH_TIME_ZONE\n    : 'TIME' WS 'WITH' WS 'TIME' WS 'ZONE'\n    ;\n\nTIMESTAMP_WITH_TIME_ZONE\n    : 'TIMESTAMP' WS 'WITH' WS 'TIME' WS 'ZONE'\n    ;\n\nDOUBLE_PRECISION\n    : 'DOUBLE' WS 'PRECISION'\n    ;\n\nfragment EXPONENT\n    : 'E' [+-]? DIGIT+\n    ;\n\nfragment DIGIT\n    : [0-9]\n    ;\n\nfragment LETTER\n    : [A-Z]\n    ;\n\nSIMPLE_COMMENT\n    : '--' ~[\\r\\n]* '\\r'? '\\n'? -> channel(HIDDEN)\n    ;\n\nBRACKETED_COMMENT\n    : '/*' .*? '*/' -> channel(HIDDEN)\n    ;\n\nWS\n    : [ \\r\\n\\t]+ -> channel(HIDDEN)\n    ;\n\n// Catch-all for anything we can't recognize.\n// We use this to be able to ignore and recover all the text\n// when splitting statements with DelimiterLexer\nUNRECOGNIZED\n    : .\n    ;"
  },
  {
    "path": "superior-presto-parser/src/main/java/io/github/melin/superior/parser/presto/CaseInsensitiveStream.java",
    "content": "/*\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage io.github.melin.superior.parser.presto;\n\nimport org.antlr.v4.runtime.CharStream;\nimport org.antlr.v4.runtime.IntStream;\nimport org.antlr.v4.runtime.misc.Interval;\n\npublic class CaseInsensitiveStream implements CharStream {\n    private final CharStream stream;\n\n    public CaseInsensitiveStream(CharStream stream) {\n        this.stream = stream;\n    }\n\n    @Override\n    public String getText(Interval interval) {\n        return stream.getText(interval);\n    }\n\n    @Override\n    public void consume() {\n        stream.consume();\n    }\n\n    @Override\n    public int LA(int i) {\n        int result = stream.LA(i);\n\n        switch (result) {\n            case 0:\n            case IntStream.EOF:\n                return result;\n            default:\n                return Character.toUpperCase(result);\n        }\n    }\n\n    @Override\n    public int mark() {\n        return stream.mark();\n    }\n\n    @Override\n    public void release(int marker) {\n        stream.release(marker);\n    }\n\n    @Override\n    public int index() {\n        return stream.index();\n    }\n\n    @Override\n    public void seek(int index) {\n        stream.seek(index);\n    }\n\n    @Override\n    public int size() {\n        return stream.size();\n    }\n\n    @Override\n    public String getSourceName() {\n        return stream.getSourceName();\n    }\n}\n"
  },
  {
    "path": "superior-presto-parser/src/main/kotlin/io/github/melin/superior/parser/presto/AbstractSqlParser.kt",
    "content": "package io.github.melin.superior.parser.presto\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(PrestoSqlBaseParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: PrestoSqlBaseParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(PrestoSqlBaseParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-presto-parser/src/main/kotlin/io/github/melin/superior/parser/presto/PrestoSqlAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.presto\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.DefaultStatement\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.common.ShowStatement\nimport io.github.melin.superior.common.relational.create.CreateTableAsSelect\nimport io.github.melin.superior.common.relational.dml.DeleteTable\nimport io.github.melin.superior.common.relational.dml.InsertMode\nimport io.github.melin.superior.common.relational.dml.InsertTable\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseBaseVisitor\nimport io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseParser\nimport org.antlr.v4.runtime.tree.RuleNode\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/1/10. */\nclass PrestoSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) :\n    PrestoSqlBaseBaseVisitor<Statement>() {\n\n    private var currentOptType: StatementType = StatementType.UNKOWN\n\n    private var limit: Int? = null\n    private var offset: Int? = null\n    private var inputTables: ArrayList<TableId> = arrayListOf()\n    private var cteTempTables: ArrayList<TableId> = arrayListOf()\n    private var functionNames: HashSet<FunctionId> = hashSetOf()\n\n    private var statements: ArrayList<Statement> = arrayListOf()\n    private val sqls: ArrayList<String> = arrayListOf()\n\n    fun getSqlStatements(): List<Statement> {\n        return statements\n    }\n\n    fun getSplitSqls(): List<String> {\n        return sqls\n    }\n\n    override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {\n        return if (currentResult == null) true else false\n    }\n\n    override fun visitSqlStatements(ctx: PrestoSqlBaseParser.SqlStatementsContext): Statement? {\n        ctx.singleStatement().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else {\n                        var statement = this.visitSingleStatement(it)\n                        if (statement == null) {\n                            statement = DefaultStatement(StatementType.UNKOWN)\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n\n                clean()\n            }\n        }\n        return null\n    }\n\n    private fun clean() {\n        currentOptType = StatementType.UNKOWN\n\n        limit = null\n        offset = null\n        inputTables = arrayListOf()\n        cteTempTables = arrayListOf()\n    }\n\n    override fun visitStatementDefault(ctx: PrestoSqlBaseParser.StatementDefaultContext): Statement? {\n        if (StringUtils.equalsIgnoreCase(\"select\", ctx.start.text)) {\n            currentOptType = StatementType.SELECT\n            super.visitQuery(ctx.query())\n\n            val limit = ctx.query()?.queryNoWith()?.limit?.text?.toInt()\n            return QueryStmt(inputTables, limit)\n        } else {\n            return null\n        }\n    }\n\n    private fun parseQuery(ctx: PrestoSqlBaseParser.QueryContext): QueryStmt {\n        currentOptType = StatementType.SELECT\n        this.visitQuery(ctx)\n\n        val queryStmt = QueryStmt(inputTables, limit, offset)\n        queryStmt.functionNames.addAll(functionNames)\n        val querySql = source(ctx)\n        queryStmt.setSql(querySql)\n        return queryStmt\n    }\n\n    override fun visitCreateTableAsSelect(ctx: PrestoSqlBaseParser.CreateTableAsSelectContext): Statement? {\n        currentOptType = StatementType.CREATE_TABLE_AS_SELECT\n        val tableId = parseTableName(ctx.qualifiedName())\n        val queryStmt = parseQuery(ctx.query())\n        val createTable = CreateTableAsSelect(tableId, queryStmt)\n        createTable.lifeCycle = 7\n        return createTable\n    }\n\n    override fun visitInsertInto(ctx: PrestoSqlBaseParser.InsertIntoContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val queryStmt = parseQuery(ctx.query())\n        val stmt = InsertTable(InsertMode.INTO, queryStmt, tableId)\n        return stmt\n    }\n\n    override fun visitDelete(ctx: PrestoSqlBaseParser.DeleteContext): Statement {\n        currentOptType = StatementType.DELETE\n        val tableId = parseTableName(ctx.qualifiedName())\n        if (ctx.whereClause() != null) {\n            super.visitWhereClause(ctx.whereClause())\n        }\n\n        return DeleteTable(tableId, inputTables)\n    }\n\n    override fun visitDropTable(ctx: PrestoSqlBaseParser.DropTableContext): Statement? {\n        val tableId = parseTableName(ctx.qualifiedName())\n\n        val dropTable = DropTable(tableId)\n        dropTable.ifExists = ctx.EXISTS() != null\n        return dropTable\n    }\n\n    override fun visitExplain(ctx: PrestoSqlBaseParser.ExplainContext): Statement? {\n        return DefaultStatement(StatementType.EXPLAIN)\n    }\n\n    override fun visitQualifiedName(ctx: PrestoSqlBaseParser.QualifiedNameContext): Statement? {\n        if (!(ctx.parent is PrestoSqlBaseParser.TableNameContext)) {\n            return null\n        }\n\n        if (\n            currentOptType == StatementType.SELECT ||\n                currentOptType == StatementType.INSERT ||\n                currentOptType == StatementType.UPDATE ||\n                currentOptType == StatementType.DELETE ||\n                currentOptType == StatementType.CREATE_TABLE_AS_SELECT\n        ) {\n\n            val tableName = parseTableName(ctx)\n            inputTables.add(tableName)\n        }\n        return null\n    }\n\n    private fun parseTableName(ctx: PrestoSqlBaseParser.QualifiedNameContext): TableId {\n        val list = ctx.identifier()\n\n        var catalogName: String? = null\n        var databaseName: String? = null\n        val tableName =\n            if (list.size == 1) {\n                ctx.text\n            } else if (list.size == 2) {\n                val index = StringUtils.lastIndexOf(ctx.text, \".\")\n                databaseName = StringUtils.substring(ctx.text, 0, index)\n\n                StringUtils.substring(ctx.text, index + 1)\n            } else {\n                val items = StringUtils.split(ctx.text, \".\")\n                catalogName = items[0]\n                databaseName = items[1]\n                items[2]\n            }\n\n        return TableId(catalogName, databaseName, tableName)\n    }\n}\n"
  },
  {
    "path": "superior-presto-parser/src/main/kotlin/io/github/melin/superior/parser/presto/PrestoSqlHelper.kt",
    "content": "package io.github.melin.superior.parser.presto\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseBaseVisitor\nimport io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseLexer\nimport io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseParser\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/1/10. */\nobject PrestoSqlHelper {\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until PrestoSqlBaseLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = PrestoSqlBaseLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement {\n        val statements = this.parseMultiStatement(command)\n        if (statements.size != 1) {\n            throw IllegalStateException(\"only parser one sql, sql count: \" + statements.size)\n        } else {\n            return statements.get(0)\n        }\n    }\n\n    @JvmStatic\n    fun parseMultiStatement(command: String): List<Statement> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = PrestoSqlAntlr4Visitor(false, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSqlStatements()\n    }\n\n    @JvmStatic\n    fun splitSql(command: String): List<String> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = PrestoSqlAntlr4Visitor(true, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSplitSqls()\n    }\n\n    @JvmStatic\n    fun checkSqlSyntax(command: String) {\n        val sqlVisitor = PrestoSqlBaseBaseVisitor<Statement>()\n        innerParseStatement(command, sqlVisitor)\n    }\n\n    private fun innerParseStatement(command: String, sqlVisitor: PrestoSqlBaseBaseVisitor<Statement>) {\n        val charStream = CaseInsensitiveStream(CharStreams.fromString(command))\n        val lexer = PrestoSqlBaseLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = PrestoSqlBaseParser(tokenStream)\n        AbstractSqlParser.installCaches(parser)\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n\n        parser.interpreter.predictionMode = PredictionMode.SLL\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visit(parser.sqlStatements())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                sqlVisitor.visit(parser.sqlStatements())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(command)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-presto-parser/src/test/kotlin/io/github/melin/superior/parser/presto/PrestoSqlParserTest.kt",
    "content": "package io.github.melin.superior.parser.presto\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.create.CreateTableAsSelect\nimport io.github.melin.superior.common.relational.dml.DeleteTable\nimport io.github.melin.superior.common.relational.dml.InsertTable\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2018/1/10. */\nclass PrestoSqlParserTest {\n\n    @Test\n    fun queryTest0() {\n        val sql =\n            \"\"\"\n            select a.* from datacompute1.datacompute.dc_job a left join datacompute1.datacompute.dc_job_scheduler b on a.id=b.job_id\n        \"\"\"\n                .trimIndent()\n\n        val statement = PrestoSqlHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(2, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest1() {\n        val sql =\n            \"\"\"\n            SELECT COUNT(app_name) AS \"应用名\" FROM (SELECT * FROM ops.dwd_app_to_container_wt \n            WHERE ds=date_format(CURRENT_DATE - interval '1' DAY, \"%Y%m%d\") ) tdbi_view\n        \"\"\"\n                .trimIndent()\n\n        val statement = PrestoSqlHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryLimitTest() {\n        val sql =\n            \"\"\"\n            select * from preso_table limit 10\n        \"\"\"\n                .trimIndent()\n\n        val statement = PrestoSqlHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(10, statement.limit)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableSelectTest() {\n        val sql =\n            \"\"\"\n            create table dd_s_s as select * from bigdata.test_demo_test limit 1\n        \"\"\"\n                .trimIndent()\n\n        val statement = PrestoSqlHelper.parseStatement(sql)\n        if (statement is CreateTableAsSelect) {\n            Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n            Assert.assertEquals(\"dd_s_s\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropTableTest() {\n        val sql =\n            \"\"\"\n            drop table if exists bigdata.tdl_small_files_2\n        \"\"\"\n                .trimIndent()\n\n        val statement = PrestoSqlHelper.parseStatement(sql)\n        if (statement is DropTable) {\n            Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)\n            Assert.assertEquals(\"bigdata\", statement.tableId.schemaName)\n            Assert.assertEquals(\"tdl_small_files_2\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest() {\n        val sql =\n            \"\"\"\n            insert into orders select * from new_orders;\n        \"\"\"\n                .trimIndent()\n\n        val statement = PrestoSqlHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"orders\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest() {\n        val sql =\n            \"\"\"\n            DELETE FROM lineitem WHERE orderkey IN (SELECT orderkey FROM orders WHERE priority = 'LOW');\n        \"\"\"\n                .trimIndent()\n\n        val statement = PrestoSqlHelper.parseStatement(sql)\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"lineitem\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-presto-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-redshift-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-redshift-parser</artifactId>\n    <name>superior-redshift-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "superior-redshift-parser/src/main/antlr4/io/github/melin/superior/parser/redshift/antlr4/RedshiftLexer.g4",
    "content": "/*\nbased on\nhttps://github.com/tunnelvisionlabs/antlr4-grammar-postgresql/blob/master/src/com/tunnelvisionlabs/postgresql/PostgreSqlLexer.g4\n*/\n\n/*\n * [The \"MIT license\"]\n * Copyright (C) 2014 Sam Harwell, Tunnel Vision Laboratories, LLC\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * 1. The above copyright notice and this permission notice shall be included in\n *    all copies or substantial portions of the Software.\n * 2. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n *    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n *    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n *    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n *    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n *    DEALINGS IN THE SOFTWARE.\n * 3. Except as contained in this notice, the name of Tunnel Vision\n *    Laboratories, LLC. shall not be used in advertising or otherwise to\n *    promote the sale, use or other dealings in this Software without prior\n *    written authorization from Tunnel Vision Laboratories, LLC.\n */\nlexer grammar RedshiftLexer;\n/* Reference:\n * http://www.postgresql.org/docs/9.3/static/sql-syntax-lexical.html\n */\n\noptions {\n   superClass = RedshiftLexerBase;\n}\n\n@ header\n{\n}\n@ members\n{\n/* This field stores the tags which are used to detect the end of a dollar-quoted string literal.\n */\n}\n//\n\n// SPECIAL CHARACTERS (4.1.4)\n\n//\n\n// Note that Asterisk is a valid operator, but does not have the type Operator due to its syntactic use in locations\n\n// that are not expressions.\n\nDollar\n   : '$'\n   ;\n\nOPEN_PAREN\n   : '('\n   ;\n\nCLOSE_PAREN\n   : ')'\n   ;\n\nOPEN_BRACKET\n   : '['\n   ;\n\nCLOSE_BRACKET\n   : ']'\n   ;\n\nCOMMA\n   : ','\n   ;\n\nSEMI\n   : ';'\n   ;\n\nCOLON\n   : ':'\n   ;\n\nSTAR\n   : '*'\n   ;\n\nEQUAL\n   : '='\n   ;\n\nDOT\n   : '.'\n   ;\n   //NamedArgument\t: ':=';\n\nPLUS\n   : '+'\n   ;\n\nMINUS\n   : '-'\n   ;\n\nSLASH\n   : '/'\n   ;\n\nCARET\n   : '^'\n   ;\n\nLT\n   : '<'\n   ;\n\nGT\n   : '>'\n   ;\n\nLESS_LESS\n   : '<<'\n   ;\n\nGREATER_GREATER\n   : '>>'\n   ;\n\nCOLON_EQUALS\n   : ':='\n   ;\n\nLESS_EQUALS\n   : '<='\n   ;\n\nEQUALS_GREATER\n   : '=>'\n   ;\n\nGREATER_EQUALS\n   : '>='\n   ;\n\nDOT_DOT\n   : '..'\n   ;\n\nNOT_EQUALS\n   : '<>'\n   ;\n\nTYPECAST\n   : '::'\n   ;\n\nPERCENT\n   : '%'\n   ;\n\nPARAM\n   : '$' ([0-9])+\n   ;\n   //\n\n   // OPERATORS (4.1.3)\n\n   //\n\n   // this rule does not allow + or - at the end of a multi-character operator\n\nOperator\n   : ((OperatorCharacter | ('+' | '-'\n   {checkLA('-')}?)+ (OperatorCharacter | '/'\n   {checkLA('*')}?) | '/'\n   {checkLA('*')}?)+ | // special handling for the single-character operators + and -\n   [+-])\n   //TODO somehow rewrite this part without using Actions\n\n   {\n    HandleLessLessGreaterGreater();\n   }\n   ;\n/* This rule handles operators which end with + or -, and sets the token type to Operator. It is comprised of four\n * parts, in order:\n *\n *   1. A prefix, which does not contain a character from the required set which allows + or - to appear at the end of\n *      the operator.\n *   2. A character from the required set which allows + or - to appear at the end of the operator.\n *   3. An optional sub-token which takes the form of an operator which does not include a + or - at the end of the\n *      sub-token.\n *   4. A suffix sequence of + and - characters.\n */\n\n\nOperatorEndingWithPlusMinus\n   : (OperatorCharacterNotAllowPlusMinusAtEnd | '-'\n   {checkLA('-')}? | '/'\n   {checkLA('*')}?)* OperatorCharacterAllowPlusMinusAtEnd Operator? ('+' | '-'\n   {checkLA('-')}?)+ -> type (Operator)\n   ;\n   // Each of the following fragment rules omits the +, -, and / characters, which must always be handled in a special way\n\n   // by the operator rules above.\n\nfragment OperatorCharacter\n   : [*<>=~!@%^&|`?#]\n   ;\n   // these are the operator characters that don't count towards one ending with + or -\n\nfragment OperatorCharacterNotAllowPlusMinusAtEnd\n   : [*<>=+]\n   ;\n   // an operator may end with + or - if it contains one of these characters\n\nfragment OperatorCharacterAllowPlusMinusAtEnd\n   : [~!@%^&|`?#]\n   ;\n   //\n\n   // KEYWORDS (Appendix C)\n\n   //\n\n   //\n\n   // reserved keywords\n\n   //\n\nALL\n   : 'ALL'\n   ;\n\nANALYSE\n   : 'ANALYSE'\n   ;\n\nANALYZE\n   : 'ANALYZE'\n   ;\n\nAND\n   : 'AND'\n   ;\n\nANY\n   : 'ANY'\n   ;\n\nARRAY\n   : 'ARRAY'\n   ;\n\nAS\n   : 'AS'\n   ;\n\nASC\n   : 'ASC'\n   ;\n\nASYMMETRIC\n   : 'ASYMMETRIC'\n   ;\n\nBOTH\n   : 'BOTH'\n   ;\n\nCASE\n   : 'CASE'\n   ;\n\nCAST\n   : 'CAST'\n   ;\n\nCHECK\n   : 'CHECK'\n   ;\n\nCOLLATE\n   : 'COLLATE'\n   ;\n\nCOLUMN\n   : 'COLUMN'\n   ;\n\n CONSTRAINT\n   : 'CONSTRAINT'\n   ;\n\nCREATE\n   : 'CREATE'\n   ;\n\nCURRENT_CATALOG\n   : 'CURRENT_CATALOG'\n   ;\n\nCURRENT_DATE\n   : 'CURRENT_DATE'\n   ;\n\nCURRENT_ROLE\n   : 'CURRENT_ROLE'\n   ;\n\nCURRENT_TIME\n   : 'CURRENT_TIME'\n   ;\n\nCURRENT_TIMESTAMP\n   : 'CURRENT_TIMESTAMP'\n   ;\n\nCURRENT_USER\n   : 'CURRENT_USER'\n   ;\n\nDEFAULT\n   : 'DEFAULT'\n   ;\n\nDEFERRABLE\n   : 'DEFERRABLE'\n   ;\n\nDESC\n   : 'DESC'\n   ;\n\nDISTINCT\n   : 'DISTINCT'\n   ;\n\nDO\n   : 'DO'\n   ;\n\nELSE\n   : 'ELSE'\n   ;\n\nEXCEPT\n   : 'EXCEPT'\n   ;\n\nFALSE_P\n   : 'FALSE'\n   ;\n\nFETCH\n   : 'FETCH'\n   ;\n\nFOR\n   : 'FOR'\n   ;\n\nFOREIGN\n   : 'FOREIGN'\n   ;\n\nFROM\n   : 'FROM'\n   ;\n\nGRANT\n   : 'GRANT'\n   ;\n\nGROUP_P\n   : 'GROUP'\n   ;\n\nHAVING\n   : 'HAVING'\n   ;\n\nIN_P\n   : 'IN'\n   ;\n\nINITIALLY\n   : 'INITIALLY'\n   ;\n\nINTERSECT\n   : 'INTERSECT'\n   ;\n\nINTO\n   : 'INTO'\n   ;\n\nLATERAL_P\n   : 'LATERAL'\n   ;\n\nLEADING\n   : 'LEADING'\n   ;\n\nLIMIT\n   : 'LIMIT'\n   ;\n\nLOCALTIME\n   : 'LOCALTIME'\n   ;\n\nLOCALTIMESTAMP\n   : 'LOCALTIMESTAMP'\n   ;\n\nNOT\n   : 'NOT'\n   ;\n\nNULL_P\n   : 'NULL'\n   ;\n\nOFFSET\n   : 'OFFSET'\n   ;\n\nON\n   : 'ON'\n   ;\n\nONLY\n   : 'ONLY'\n   ;\n\nOR\n   : 'OR'\n   ;\n\nORDER\n   : 'ORDER'\n   ;\n\nPLACING\n   : 'PLACING'\n   ;\n\nPRIMARY\n   : 'PRIMARY'\n   ;\n\nREFERENCES\n   : 'REFERENCES'\n   ;\n\nRETURNING\n   : 'RETURNING'\n   ;\n\nSELECT\n   : 'SELECT'\n   ;\n\nSESSION_USER\n   : 'SESSION_USER'\n   ;\n\nSOME\n   : 'SOME'\n   ;\n\nSYMMETRIC\n   : 'SYMMETRIC'\n   ;\n\nTABLE\n   : 'TABLE'\n   ;\n\nTHEN\n   : 'THEN'\n   ;\n\nTO\n   : 'TO'\n   ;\n\nTRAILING\n   : 'TRAILING'\n   ;\n\nTRUE_P\n   : 'TRUE'\n   ;\n\nUNION\n   : 'UNION'\n   ;\n\nUNIQUE\n   : 'UNIQUE'\n   ;\n\nUSER\n   : 'USER'\n   ;\n\nUSING\n   : 'USING'\n   ;\n\nVARIADIC\n   : 'VARIADIC'\n   ;\n\nWHEN\n   : 'WHEN'\n   ;\n\nWHERE\n   : 'WHERE'\n   ;\n\nWINDOW\n   : 'WINDOW'\n   ;\n\nWITH\n   : 'WITH'\n   ;\n\n   //\n\n   // reserved keywords (can be function or type)\n\n   //\n\nAUTHORIZATION\n   : 'AUTHORIZATION'\n   ;\n\nBINARY\n   : 'BINARY'\n   ;\n\nCOLLATION\n   : 'COLLATION'\n   ;\n\nCONCURRENTLY\n   : 'CONCURRENTLY'\n   ;\n\nCROSS\n   : 'CROSS'\n   ;\n\nCURRENT_SCHEMA\n   : 'CURRENT_SCHEMA'\n   ;\n\nFREEZE\n   : 'FREEZE'\n   ;\n\nFULL\n   : 'FULL'\n   ;\n\nILIKE\n   : 'ILIKE'\n   ;\n\nINNER_P\n   : 'INNER'\n   ;\n\nIS\n   : 'IS'\n   ;\n\nISNULL\n   : 'ISNULL'\n   ;\n\nJOIN\n   : 'JOIN'\n   ;\n\nLEFT\n   : 'LEFT'\n   ;\n\nLIKE\n   : 'LIKE'\n   ;\n\nNATURAL\n   : 'NATURAL'\n   ;\n\nNOTNULL\n   : 'NOTNULL'\n   ;\n\nOUTER_P\n   : 'OUTER'\n   ;\n\nOVER\n   : 'OVER'\n   ;\n\nOVERLAPS\n   : 'OVERLAPS'\n   ;\n\nRIGHT\n   : 'RIGHT'\n   ;\n\nSIMILAR\n   : 'SIMILAR'\n   ;\n\nVERBOSE\n   : 'VERBOSE'\n   ;\n   //\n\n   // non-reserved keywords\n\n   //\n\nABORT_P\n   : 'ABORT'\n   ;\n\nABSOLUTE_P\n   : 'ABSOLUTE'\n   ;\n\nACCESS\n   : 'ACCESS'\n   ;\n\nACTION\n   : 'ACTION'\n   ;\n\nADD_P\n   : 'ADD'\n   ;\n\nADMIN\n   : 'ADMIN'\n   ;\n\nAFTER\n   : 'AFTER'\n   ;\n\nAGGREGATE\n   : 'AGGREGATE'\n   ;\n\nALSO\n   : 'ALSO'\n   ;\n\nALTER\n   : 'ALTER'\n   ;\n\nALWAYS\n   : 'ALWAYS'\n   ;\n\nASSERTION\n   : 'ASSERTION'\n   ;\n\nASSIGNMENT\n   : 'ASSIGNMENT'\n   ;\n\nAT\n   : 'AT'\n   ;\n\nATTRIBUTE\n   : 'ATTRIBUTE'\n   ;\n\nBACKWARD\n   : 'BACKWARD'\n   ;\n\nBEFORE\n   : 'BEFORE'\n   ;\n\nBEGIN_P\n   : 'BEGIN'\n   ;\n\nBY\n   : 'BY'\n   ;\n\nCACHE\n   : 'CACHE'\n   ;\n\nCALLED\n   : 'CALLED'\n   ;\n\nCASCADE\n   : 'CASCADE'\n   ;\n\nCASCADED\n   : 'CASCADED'\n   ;\n\nCATALOG\n   : 'CATALOG'\n   ;\n\nCHAIN\n   : 'CHAIN'\n   ;\n\nCHARACTERISTICS\n   : 'CHARACTERISTICS'\n   ;\n\nCHECKPOINT\n   : 'CHECKPOINT'\n   ;\n\nCLASS\n   : 'CLASS'\n   ;\n\nCLOSE\n   : 'CLOSE'\n   ;\n\nCLUSTER\n   : 'CLUSTER'\n   ;\n\nCOMMENT\n   : 'COMMENT'\n   ;\n\nCOMMENTS\n   : 'COMMENTS'\n   ;\n\nCOMMIT\n   : 'COMMIT'\n   ;\n\nCOMMITTED\n   : 'COMMITTED'\n   ;\n\nCONFIGURATION\n   : 'CONFIGURATION'\n   ;\n\nCONNECTION\n   : 'CONNECTION'\n   ;\n\nCONSTRAINTS\n   : 'CONSTRAINTS'\n   ;\n\nCONTENT_P\n   : 'CONTENT'\n   ;\n\nCONTINUE_P\n   : 'CONTINUE'\n   ;\n\nCONVERSION_P\n   : 'CONVERSION'\n   ;\n\nCOPY\n   : 'COPY'\n   ;\n\nCOST\n   : 'COST'\n   ;\n\nCSV\n   : 'CSV'\n   ;\n\nCURSOR\n   : 'CURSOR'\n   ;\n\nCYCLE\n   : 'CYCLE'\n   ;\n\nDATA_P\n   : 'DATA'\n   ;\n\nDATABASE\n   : 'DATABASE'\n   ;\n\nDAY_P\n   : 'DAY'\n   ;\n\nDEALLOCATE\n   : 'DEALLOCATE'\n   ;\n\nDECLARE\n   : 'DECLARE'\n   ;\n\nDEFAULTS\n   : 'DEFAULTS'\n   ;\n\nDEFERRED\n   : 'DEFERRED'\n   ;\n\nDEFINER\n   : 'DEFINER'\n   ;\n\nDELETE_P\n   : 'DELETE'\n   ;\n\nDELIMITER\n   : 'DELIMITER'\n   ;\n\nDELIMITERS\n   : 'DELIMITERS'\n   ;\n\nDICTIONARY\n   : 'DICTIONARY'\n   ;\n\nDISABLE_P\n   : 'DISABLE'\n   ;\n\nDISCARD\n   : 'DISCARD'\n   ;\n\nDOCUMENT_P\n   : 'DOCUMENT'\n   ;\n\nDOMAIN_P\n   : 'DOMAIN'\n   ;\n\nDOUBLE_P\n   : 'DOUBLE'\n   ;\n\nDROP\n   : 'DROP'\n   ;\n\nEACH\n   : 'EACH'\n   ;\n\nENABLE_P\n   : 'ENABLE'\n   ;\n\nENCODING\n   : 'ENCODING'\n   ;\n\nENCRYPTED\n   : 'ENCRYPTED'\n   ;\n\nENUM_P\n   : 'ENUM'\n   ;\n\nESCAPE\n   : 'ESCAPE'\n   ;\n\nEVENT\n   : 'EVENT'\n   ;\n\nEXCLUDE\n   : 'EXCLUDE'\n   ;\n\nEXCLUDING\n   : 'EXCLUDING'\n   ;\n\nEXCLUSIVE\n   : 'EXCLUSIVE'\n   ;\n\nEXECUTE\n   : 'EXECUTE'\n   ;\n\nEXPLAIN\n   : 'EXPLAIN'\n   ;\n\nEXTENSION\n   : 'EXTENSION'\n   ;\n\nEXTERNAL\n   : 'EXTERNAL'\n   ;\n\nFAMILY\n   : 'FAMILY'\n   ;\n\nFIRST_P\n   : 'FIRST'\n   ;\n\nFOLLOWING\n   : 'FOLLOWING'\n   ;\n\nFORCE\n   : 'FORCE'\n   ;\n\nFORWARD\n   : 'FORWARD'\n   ;\n\nFUNCTION\n   : 'FUNCTION'\n   ;\n\nFUNCTIONS\n   : 'FUNCTIONS'\n   ;\n\nGLOBAL\n   : 'GLOBAL'\n   ;\n\nGRANTED\n   : 'GRANTED'\n   ;\n\nHANDLER\n   : 'HANDLER'\n   ;\n\nHEADER_P\n   : 'HEADER'\n   ;\n\nHOLD\n   : 'HOLD'\n   ;\n\nHOUR_P\n   : 'HOUR'\n   ;\n\nIDENTITY_P\n   : 'IDENTITY'\n   ;\n\nIF_P\n   : 'IF'\n   ;\n\nIMMEDIATE\n   : 'IMMEDIATE'\n   ;\n\nIMMUTABLE\n   : 'IMMUTABLE'\n   ;\n\nIMPLICIT_P\n   : 'IMPLICIT'\n   ;\n\nINCLUDING\n   : 'INCLUDING'\n   ;\n\nINCREMENT\n   : 'INCREMENT'\n   ;\n\nINDEX\n   : 'INDEX'\n   ;\n\nINDEXES\n   : 'INDEXES'\n   ;\n\nINHERIT\n   : 'INHERIT'\n   ;\n\nINHERITS\n   : 'INHERITS'\n   ;\n\nINLINE_P\n   : 'INLINE'\n   ;\n\nINSENSITIVE\n   : 'INSENSITIVE'\n   ;\n\nINSERT\n   : 'INSERT'\n   ;\n\nINSTEAD\n   : 'INSTEAD'\n   ;\n\nINVOKER\n   : 'INVOKER'\n   ;\n\nISOLATION\n   : 'ISOLATION'\n   ;\n\nKEY\n   : 'KEY'\n   ;\n\nLABEL\n   : 'LABEL'\n   ;\n\nLANGUAGE\n   : 'LANGUAGE'\n   ;\n\nLARGE_P\n   : 'LARGE'\n   ;\n\nLAST_P\n   : 'LAST'\n   ;\n   //LC_COLLATE\t\t\t: 'LC'_'COLLATE;\n\n   //LC_CTYPE\t\t\t: 'LC'_'CTYPE;\n\nLEAKPROOF\n   : 'LEAKPROOF'\n   ;\n\nLEVEL\n   : 'LEVEL'\n   ;\n\nLISTEN\n   : 'LISTEN'\n   ;\n\nLOAD\n   : 'LOAD'\n   ;\n\nLOCAL\n   : 'LOCAL'\n   ;\n\nLOCATION\n   : 'LOCATION'\n   ;\n\nLOCK_P\n   : 'LOCK'\n   ;\n\nMAPPING\n   : 'MAPPING'\n   ;\n\nMATCH\n   : 'MATCH'\n   ;\n\nMATCHED\n   : 'MATCHED'\n   ;\n\nMATERIALIZED\n   : 'MATERIALIZED'\n   ;\n\nMAXVALUE\n   : 'MAXVALUE'\n   ;\n\nMERGE\n   : 'MERGE'\n   ;\n\nMINUTE_P\n   : 'MINUTE'\n   ;\n\nMINVALUE\n   : 'MINVALUE'\n   ;\n\nMODE\n   : 'MODE'\n   ;\n\nMONTH_P\n   : 'MONTH'\n   ;\n\nMOVE\n   : 'MOVE'\n   ;\n\nNAME_P\n   : 'NAME'\n   ;\n\nNAMES\n   : 'NAMES'\n   ;\n\nNEXT\n   : 'NEXT'\n   ;\n\nNO\n   : 'NO'\n   ;\n\nNOTHING\n   : 'NOTHING'\n   ;\n\nNOTIFY\n   : 'NOTIFY'\n   ;\n\nNOWAIT\n   : 'NOWAIT'\n   ;\n\nNULLS_P\n   : 'NULLS'\n   ;\n\nOBJECT_P\n   : 'OBJECT'\n   ;\n\nOF\n   : 'OF'\n   ;\n\nOFF\n   : 'OFF'\n   ;\n\nOIDS\n   : 'OIDS'\n   ;\n\nOPERATOR\n   : 'OPERATOR'\n   ;\n\nOPTION\n   : 'OPTION'\n   ;\n\nOPTIONS\n   : 'OPTIONS'\n   ;\n\nOWNED\n   : 'OWNED'\n   ;\n\nOWNER\n   : 'OWNER'\n   ;\n\nPARSER\n   : 'PARSER'\n   ;\n\nPARTIAL\n   : 'PARTIAL'\n   ;\n\nPARTITION\n   : 'PARTITION'\n   ;\n\nPASSING\n   : 'PASSING'\n   ;\n\nPASSWORD\n   : 'PASSWORD'\n   ;\n\nPLANS\n   : 'PLANS'\n   ;\n\nPRECEDING\n   : 'PRECEDING'\n   ;\n\nPREPARE\n   : 'PREPARE'\n   ;\n\nPREPARED\n   : 'PREPARED'\n   ;\n\nPRESERVE\n   : 'PRESERVE'\n   ;\n\nPRIOR\n   : 'PRIOR'\n   ;\n\nPRIVILEGES\n   : 'PRIVILEGES'\n   ;\n\nPROCEDURAL\n   : 'PROCEDURAL'\n   ;\n\nPROCEDURE\n   : 'PROCEDURE'\n   ;\n\nPROGRAM\n   : 'PROGRAM'\n   ;\n\nQUOTE\n   : 'QUOTE'\n   ;\n\nRANGE\n   : 'RANGE'\n   ;\n\nREAD\n   : 'READ'\n   ;\n\nREASSIGN\n   : 'REASSIGN'\n   ;\n\nRECHECK\n   : 'RECHECK'\n   ;\n\nRECURSIVE\n   : 'RECURSIVE'\n   ;\n\nREF\n   : 'REF'\n   ;\n\nREFRESH\n   : 'REFRESH'\n   ;\n\nREINDEX\n   : 'REINDEX'\n   ;\n\nRELATIVE_P\n   : 'RELATIVE'\n   ;\n\nRELEASE\n   : 'RELEASE'\n   ;\n\nRENAME\n   : 'RENAME'\n   ;\n\nREPEATABLE\n   : 'REPEATABLE'\n   ;\n\nREPLACE\n   : 'REPLACE'\n   ;\n\nREPLICA\n   : 'REPLICA'\n   ;\n\nRESET\n   : 'RESET'\n   ;\n\nRESTART\n   : 'RESTART'\n   ;\n\nRESTRICT\n   : 'RESTRICT'\n   ;\n\nRETURNS\n   : 'RETURNS'\n   ;\n\nREVOKE\n   : 'REVOKE'\n   ;\n\nROLE\n   : 'ROLE'\n   ;\n\nROLLBACK\n   : 'ROLLBACK'\n   ;\n\nROWS\n   : 'ROWS'\n   ;\n\nRULE\n   : 'RULE'\n   ;\n\nSAVEPOINT\n   : 'SAVEPOINT'\n   ;\n\nSCHEMA\n   : 'SCHEMA'\n   ;\n\nSCROLL\n   : 'SCROLL'\n   ;\n\nSEARCH\n   : 'SEARCH'\n   ;\n\nSECOND_P\n   : 'SECOND'\n   ;\n\nSECURITY\n   : 'SECURITY'\n   ;\n\nSEQUENCE\n   : 'SEQUENCE'\n   ;\n\nSEQUENCES\n   : 'SEQUENCES'\n   ;\n\nSERIALIZABLE\n   : 'SERIALIZABLE'\n   ;\n\nSERVER\n   : 'SERVER'\n   ;\n\nSESSION\n   : 'SESSION'\n   ;\n\nSET\n   : 'SET'\n   ;\n\nSHARE\n   : 'SHARE'\n   ;\n\nSHOW\n   : 'SHOW'\n   ;\n\nSIMPLE\n   : 'SIMPLE'\n   ;\n\nSNAPSHOT\n   : 'SNAPSHOT'\n   ;\n\nSTABLE\n   : 'STABLE'\n   ;\n\nSTANDALONE_P\n   : 'STANDALONE'\n   ;\n\nSTART\n   : 'START'\n   ;\n\nSTATEMENT\n   : 'STATEMENT'\n   ;\n\nSTATISTICS\n   : 'STATISTICS'\n   ;\n\nSTDIN\n   : 'STDIN'\n   ;\n\nSTDOUT\n   : 'STDOUT'\n   ;\n\nSTORAGE\n   : 'STORAGE'\n   ;\n\nSTRICT_P\n   : 'STRICT'\n   ;\n\nSTRIP_P\n   : 'STRIP'\n   ;\n\nSYSID\n   : 'SYSID'\n   ;\n\nSYSTEM_P\n   : 'SYSTEM'\n   ;\n\nTABLES\n   : 'TABLES'\n   ;\n\nTABLESPACE\n   : 'TABLESPACE'\n   ;\n\nTEMP\n   : 'TEMP'\n   ;\n\nTEMPLATE\n   : 'TEMPLATE'\n   ;\n\nTEMPORARY\n   : 'TEMPORARY'\n   ;\n\nTEXT_P\n   : 'TEXT'\n   ;\n\nTRANSACTION\n   : 'TRANSACTION'\n   ;\n\nTRIGGER\n   : 'TRIGGER'\n   ;\n\nTRUNCATE\n   : 'TRUNCATE'\n   ;\n\nTRUSTED\n   : 'TRUSTED'\n   ;\n\nTYPE_P\n   : 'TYPE'\n   ;\n\nTYPES_P\n   : 'TYPES'\n   ;\n\nUNBOUNDED\n   : 'UNBOUNDED'\n   ;\n\nUNCOMMITTED\n   : 'UNCOMMITTED'\n   ;\n\nUNENCRYPTED\n   : 'UNENCRYPTED'\n   ;\n\nUNKNOWN\n   : 'UNKNOWN'\n   ;\n\nUNLISTEN\n   : 'UNLISTEN'\n   ;\n\nUNLOGGED\n   : 'UNLOGGED'\n   ;\n\nUNTIL\n   : 'UNTIL'\n   ;\n\nUPDATE\n   : 'UPDATE'\n   ;\n\nVACUUM\n   : 'VACUUM'\n   ;\n\nVALID\n   : 'VALID'\n   ;\n\nVALIDATE\n   : 'VALIDATE'\n   ;\n\nVALIDATOR\n   : 'VALIDATOR'\n   ;\n   //VALUE\t\t\t\t: 'VALUE;\n\nVARYING\n   : 'VARYING'\n   ;\n\nVERSION_P\n   : 'VERSION'\n   ;\n\nVIEW\n   : 'VIEW'\n   ;\n\nVOLATILE\n   : 'VOLATILE'\n   ;\n\nWHITESPACE_P\n   : 'WHITESPACE'\n   ;\n\nWITHOUT\n   : 'WITHOUT'\n   ;\n\nWORK\n   : 'WORK'\n   ;\n\nWRAPPER\n   : 'WRAPPER'\n   ;\n\nWRITE\n   : 'WRITE'\n   ;\n\nXML_P\n   : 'XML'\n   ;\n\nYEAR_P\n   : 'YEAR'\n   ;\n\nYES_P\n   : 'YES'\n   ;\n\nZONE\n   : 'ZONE'\n   ;\n   //\n\n   // non-reserved keywords (can not be function or type)\n\n   //\n\nBETWEEN\n   : 'BETWEEN'\n   ;\n\nBIGINT\n   : 'BIGINT'\n   ;\n\nBIT\n   : 'BIT'\n   ;\n\nBOOLEAN_P\n   : 'BOOLEAN'\n   ;\n\nCHAR_P\n   : 'CHAR'\n   ;\n\nCHARACTER\n   : 'CHARACTER'\n   ;\n\nCOALESCE\n   : 'COALESCE'\n   ;\n\nDEC\n   : 'DEC'\n   ;\n\nDECIMAL_P\n   : 'DECIMAL'\n   ;\n\nEXISTS\n   : 'EXISTS'\n   ;\n\nEXTRACT\n   : 'EXTRACT'\n   ;\n\nFLOAT_P\n   : 'FLOAT'\n   ;\n\nGREATEST\n   : 'GREATEST'\n   ;\n\nINOUT\n   : 'INOUT'\n   ;\n\nINT_P\n   : 'INT'\n   ;\n\nINTEGER\n   : 'INTEGER'\n   ;\n\nINTERVAL\n   : 'INTERVAL'\n   ;\n\nLEAST\n   : 'LEAST'\n   ;\n\nNATIONAL\n   : 'NATIONAL'\n   ;\n\nNCHAR\n   : 'NCHAR'\n   ;\n\nNONE\n   : 'NONE'\n   ;\n\nNULLIF\n   : 'NULLIF'\n   ;\n\nNUMERIC\n   : 'NUMERIC'\n   ;\n\nOVERLAY\n   : 'OVERLAY'\n   ;\n\nPOSITION\n   : 'POSITION'\n   ;\n\nPRECISION\n   : 'PRECISION'\n   ;\n\nREAL\n   : 'REAL'\n   ;\n\nROW\n   : 'ROW'\n   ;\n\nSETOF\n   : 'SETOF'\n   ;\n\nSMALLINT\n   : 'SMALLINT'\n   ;\n\nSUBSTRING\n   : 'SUBSTRING'\n   ;\n\nTIME\n   : 'TIME'\n   ;\n\nTIMESTAMP\n   : 'TIMESTAMP'\n   ;\n\nTREAT\n   : 'TREAT'\n   ;\n\nTRIM\n   : 'TRIM'\n   ;\n\nVALUES\n   : 'VALUES'\n   ;\n\nVARCHAR\n   : 'VARCHAR'\n   ;\n\nXMLATTRIBUTES\n   : 'XMLATTRIBUTES'\n   ;\n\nXMLCOMMENT\n   : 'XMLCOMMENT'\n   ;\n\nXMLAGG\n   : 'XMLAGG'\n   ;\n\nXML_IS_WELL_FORMED\n   : 'XML_IS_WELL_FORMED'\n   ;\n\nXML_IS_WELL_FORMED_DOCUMENT\n   : 'XML_IS_WELL_FORMED_DOCUMENT'\n   ;\n\nXML_IS_WELL_FORMED_CONTENT\n   : 'XML_IS_WELL_FORMED_CONTENT'\n   ;\n\nXPATH\n   : 'XPATH'\n   ;\n\nXPATH_EXISTS\n   : 'XPATH_EXISTS'\n   ;\n\nXMLCONCAT\n   : 'XMLCONCAT'\n   ;\n\nXMLELEMENT\n   : 'XMLELEMENT'\n   ;\n\nXMLEXISTS\n   : 'XMLEXISTS'\n   ;\n\nXMLFOREST\n   : 'XMLFOREST'\n   ;\n\nXMLPARSE\n   : 'XMLPARSE'\n   ;\n\nXMLPI\n   : 'XMLPI'\n   ;\n\nXMLROOT\n   : 'XMLROOT'\n   ;\n\nXMLSERIALIZE\n   : 'XMLSERIALIZE'\n   ;\n   //MISSED\n\nCALL\n   : 'CALL'\n   ;\n\nCURRENT_P\n   : 'CURRENT'\n   ;\n\nATTACH\n   : 'ATTACH'\n   ;\n\nDETACH\n   : 'DETACH'\n   ;\n\nEXPRESSION\n   : 'EXPRESSION'\n   ;\n\nGENERATED\n   : 'GENERATED'\n   ;\n\nLOGGED\n   : 'LOGGED'\n   ;\n\nSTORED\n   : 'STORED'\n   ;\n\nINCLUDE\n   : 'INCLUDE'\n   ;\n\nROUTINE\n   : 'ROUTINE'\n   ;\n\nTRANSFORM\n   : 'TRANSFORM'\n   ;\n\nIMPORT_P\n   : 'IMPORT'\n   ;\n\nPOLICY\n   : 'POLICY'\n   ;\n\nMETHOD\n   : 'METHOD'\n   ;\n\nREFERENCING\n   : 'REFERENCING'\n   ;\n\nNEW\n   : 'NEW'\n   ;\n\nOLD\n   : 'OLD'\n   ;\n\nVALUE_P\n   : 'VALUE'\n   ;\n\nSUBSCRIPTION\n   : 'SUBSCRIPTION'\n   ;\n\nPUBLICATION\n   : 'PUBLICATION'\n   ;\n\nOUT_P\n   : 'OUT'\n   ;\n\nEND_P\n   : 'END'\n   ;\n\nROUTINES\n   : 'ROUTINES'\n   ;\n\nSCHEMAS\n   : 'SCHEMAS'\n   ;\n\nPROCEDURES\n   : 'PROCEDURES'\n   ;\n\nINPUT_P\n   : 'INPUT'\n   ;\n\nSUPPORT\n   : 'SUPPORT'\n   ;\n\nPARALLEL\n   : 'PARALLEL'\n   ;\n\nSQL_P\n   : 'SQL'\n   ;\n\nDEPENDS\n   : 'DEPENDS'\n   ;\n\nOVERRIDING\n   : 'OVERRIDING'\n   ;\n\n// support gauss start--------------------------------\nAUTOMAPPED\n   : 'AUTOMAPPED'\n   ;\nSAMPLE\n   : 'SAMPLE'\n   ;\nPERCENT_P\n   : 'PERCENT'\n   ;\nSTAT\n   : 'STAT'\n   ;\nCOLLECT\n   : 'COLLECT'\n   ;\n\nMULTISET\n   : 'MULTISET'\n   ;\n\nMINUS_P\n   : 'MINUS'\n   ;\n\nGROUPCONCAT\n   : 'GROUP_CONCAT'\n   ;\n\nSEPARATOR\n   : 'SEPARATOR'\n   ;\n\nIGNORE\n   : 'IGNORE'\n   ;\nOPEN_BRACE\n   : '{'\n   ;\nCLOSE_BRACE\n   : '}'\n   ;\nOVERWRITE\n   : 'OVERWRITE'\n   ;\nDISTRIBUTE\n   : 'DISTRIBUTE'\n   ;\nDISTRIBUTED\n   : 'DISTRIBUTED'\n   ;\nDISTRIBUTION\n   : 'DISTRIBUTION'\n   ;\nREPLICATION\n   : 'REPLICATION'\n   ;\nROUNDROBIN\n   : 'ROUNDROBIN'\n   ;\nHASH\n   : 'HASH'\n   ;\nRANDOMLY\n   : 'RANDOMLY'\n   ;\nNODE_P\n   : 'NODE'\n   ;\n\nLIST_P\n   : 'LIST'\n   ;\n\nLESS\n   : 'LESS'\n   ;\n\nTHAN\n   : 'THAN'\n   ;\n\nEVERY\n   : 'EVERY'\n   ;\n\nMOVEMENT\n   : 'MOVEMENT'\n   ;\n\nTSTag\n   : 'TSTag'\n   ;\n\nTSTime\n   : 'TSTime'\n   ;\n\nTSField\n   : 'TSField'\n   ;\n\nREPLICATED\n   : 'REPLICATED'\n   ;\n\n// support gauss end --------------------------------\n\nCONFLICT\n   : 'CONFLICT'\n   ;\n\nSKIP_P\n   : 'SKIP'\n   ;\n\nLOCKED\n   : 'LOCKED'\n   ;\n\nTIES\n   : 'TIES'\n   ;\n\nROLLUP\n   : 'ROLLUP'\n   ;\n\nCUBE\n   : 'CUBE'\n   ;\n\nGROUPING\n   : 'GROUPING'\n   ;\n\nSETS\n   : 'SETS'\n   ;\n\nTABLESAMPLE\n   : 'TABLESAMPLE'\n   ;\n\nORDINALITY\n   : 'ORDINALITY'\n   ;\n\nXMLTABLE\n   : 'XMLTABLE'\n   ;\n\nCOLUMNS\n   : 'COLUMNS'\n   ;\n\nXMLNAMESPACES\n   : 'XMLNAMESPACES'\n   ;\n\nROWTYPE\n   : 'ROWTYPE'\n   ;\n\nNORMALIZED\n   : 'NORMALIZED'\n   ;\n\nWITHIN\n   : 'WITHIN'\n   ;\n\nFILTER\n   : 'FILTER'\n   ;\n\nGROUPS\n   : 'GROUPS'\n   ;\n\nOTHERS\n   : 'OTHERS'\n   ;\n\nNFC\n   : 'NFC'\n   ;\n\nNFD\n   : 'NFD'\n   ;\n\nNFKC\n   : 'NFKC'\n   ;\n\nNFKD\n   : 'NFKD'\n   ;\n\nUESCAPE\n   : 'UESCAPE'\n   ;\n\nVIEWS\n   : 'VIEWS'\n   ;\n\nNORMALIZE\n   : 'NORMALIZE'\n   ;\n\nDUMP\n   : 'DUMP'\n   ;\n\nPRINT_STRICT_PARAMS\n   : 'PRINT_STRICT_PARAMS'\n   ;\n\nVARIABLE_CONFLICT\n   : 'VARIABLE_CONFLICT'\n   ;\n\nERROR\n   : 'ERROR'\n   ;\n\nUSE_VARIABLE\n   : 'USE_VARIABLE'\n   ;\n\nUSE_COLUMN\n   : 'USE_COLUMN'\n   ;\n\nALIAS\n   : 'ALIAS'\n   ;\n\nCONSTANT\n   : 'CONSTANT'\n   ;\n\nPERFORM\n   : 'PERFORM'\n   ;\n\nGET\n   : 'GET'\n   ;\n\nDIAGNOSTICS\n   : 'DIAGNOSTICS'\n   ;\n\nSTACKED\n   : 'STACKED'\n   ;\n\nELSIF\n   : 'ELSIF'\n   ;\n\nWHILE\n   : 'WHILE'\n   ;\n\nREVERSE\n   : 'REVERSE'\n   ;\n\nFOREACH\n   : 'FOREACH'\n   ;\n\nSLICE\n   : 'SLICE'\n   ;\n\nEXIT\n   : 'EXIT'\n   ;\n\nRETURN\n   : 'RETURN'\n   ;\n\nQUERY\n   : 'QUERY'\n   ;\n\nRAISE\n   : 'RAISE'\n   ;\n\nSQLSTATE\n   : 'SQLSTATE'\n   ;\n\nDEBUG\n   : 'DEBUG'\n   ;\n\nLOG\n   : 'LOG'\n   ;\n\nINFO\n   : 'INFO'\n   ;\n\nNOTICE\n   : 'NOTICE'\n   ;\n\nWARNING\n   : 'WARNING'\n   ;\n\nEXCEPTION\n   : 'EXCEPTION'\n   ;\n\nASSERT\n   : 'ASSERT'\n   ;\n\nLOOP\n   : 'LOOP'\n   ;\n\nOPEN\n   : 'OPEN'\n   ;\n   //\n\n   // IDENTIFIERS (4.1.1)\n\n   //\n\nABS\n   : 'ABS'\n   ;\n\nCBRT\n   : 'CBRT'\n   ;\n\nCEIL\n   : 'CEIL'\n   ;\n\nCEILING\n   : 'CEILING'\n   ;\n\nDEGREES\n   : 'DEGREES'\n   ;\n\nDIV\n   : 'DIV'\n   ;\n\nEXP\n   : 'EXP'\n   ;\n\nFACTORIAL\n   : 'FACTORIAL'\n   ;\n\nFLOOR\n   : 'FLOOR'\n   ;\n\nGCD\n   : 'GCD'\n   ;\n\nLCM\n   : 'LCM'\n   ;\n\nLN\n   : 'LN'\n   ;\n\nLOG10\n   : 'LOG10'\n   ;\n\nMIN_SCALE\n   : 'MIN_SCALE'\n   ;\n\nMOD\n   : 'MOD'\n   ;\n\nPI\n   : 'PI'\n   ;\n\nPOWER\n   : 'POWER'\n   ;\n\nRADIANS\n   : 'RADIANS'\n   ;\n\nROUND\n   : 'ROUND'\n   ;\n\nSCALE\n   : 'SCALE'\n   ;\n\nSIGN\n   : 'SIGN'\n   ;\n\nSQRT\n   : 'SQRT'\n   ;\n\nTRIM_SCALE\n   : 'TRIM_SCALE'\n   ;\n\nTRUNC\n   : 'TRUNC'\n   ;\n\nWIDTH_BUCKET\n   : 'WIDTH_BUCKET'\n   ;\n\nRANDOM\n   : 'RANDOM'\n   ;\n\nSETSEED\n   : 'SETSEED'\n   ;\n\nACOS\n   : 'ACOS'\n   ;\n\nACOSD\n   : 'ACOSD'\n   ;\n\nASIN\n   : 'ASIN'\n   ;\n\nASIND\n   : 'ASIND'\n   ;\n\nATAN\n   : 'ATAN'\n   ;\n\nATAND\n   : 'ATAND'\n   ;\n\nATAN2\n   : 'ATAN2'\n   ;\n\nATAN2D\n   : 'ATAN2D'\n   ;\n\nCOS\n   : 'COS'\n   ;\n\nCOSD\n   : 'COSD'\n   ;\n\nCOT\n   : 'COT'\n   ;\n\nCOTD\n   : 'COTD'\n   ;\n\nSIN\n   : 'SIN'\n   ;\n\nSIND\n   : 'SIND'\n   ;\n\nTAN\n   : 'TAN'\n   ;\n\nTAND\n   : 'TAND'\n   ;\n\nSINH\n   : 'SINH'\n   ;\n\nCOSH\n   : 'COSH'\n   ;\n\nTANH\n   : 'TANH'\n   ;\n\nASINH\n   : 'ASINH'\n   ;\n\nACOSH\n   : 'ACOSH'\n   ;\n\nATANH\n   : 'ATANH'\n   ;\n\nBIT_LENGTH\n   : 'BIT_LENGTH'\n   ;\n\nCHAR_LENGTH\n   : 'CHAR_LENGTH'\n   ;\n\nCHARACTER_LENGTH\n   : 'CHARACTER_LENGTH'\n   ;\n\nLOWER\n   : 'LOWER'\n   ;\n\nOCTET_LENGTH\n   : 'OCTET_LENGTH'\n   ;\n\nUPPER\n   : 'UPPER'\n   ;\n\nASCII\n   : 'ASCII'\n   ;\n\nBTRIM\n   : 'BTRIM'\n   ;\n\nCHR\n   : 'CHR'\n   ;\n\nCONCAT\n   : 'CONCAT'\n   ;\n\nCONCAT_WS\n   : 'CONCAT_WS'\n   ;\n\nFORMAT\n   : 'FORMAT'\n   ;\n\nINITCAP\n   : 'INITCAP'\n   ;\n\nLENGTH\n   : 'LENGTH'\n   ;\n\nLPAD\n   : 'LPAD'\n   ;\n\nLTRIM\n   : 'LTRIM'\n   ;\n\nMD5\n   : 'MD5'\n   ;\n\nPARSE_IDENT\n   : 'PARSE_IDENT'\n   ;\n\nPG_CLIENT_ENCODING\n   : 'PG_CLIENT_ENCODING'\n   ;\n\nQUOTE_IDENT\n   : 'QUOTE_IDENT'\n   ;\n\nQUOTE_LITERAL\n   : 'QUOTE_LITERAL'\n   ;\n\nQUOTE_NULLABLE\n   : 'QUOTE_NULLABLE'\n   ;\n\nREGEXP_COUNT\n   : 'REGEXP_COUNT'\n   ;\n\nREGEXP_INSTR\n   : 'REGEXP_INSTR'\n   ;\n\nREGEXP_LIKE\n   : 'REGEXP_LIKE'\n   ;\n\nREGEXP_MATCH\n   : 'REGEXP_MATCH'\n   ;\n\nREGEXP_MATCHES\n   : 'REGEXP_MATCHES'\n   ;\n\nREGEXP_REPLACE\n   : 'REGEXP_REPLACE'\n   ;\n\nREGEXP_SPLIT_TO_ARRAY\n   : 'REGEXP_SPLIT_TO_ARRAY'\n   ;\n\nREGEXP_SPLIT_TO_TABLE\n   : 'REGEXP_SPLIT_TO_TABLE'\n   ;\n\nREGEXP_SUBSTR\n   : 'REGEXP_SUBSTR'\n   ;\n\nREPEAT\n   : 'REPEAT'\n   ;\n\nRPAD\n   : 'RPAD'\n   ;\n\nRTRIM\n   : 'RTRIM'\n   ;\n\nSPLIT_PART\n   : 'SPLIT_PART'\n   ;\n\nSTARTS_WITH\n   : 'STARTS_WITH'\n   ;\n\nSTRING_TO_ARRAY\n   : 'STRING_TO_ARRAY'\n   ;\n\nSTRING_TO_TABLE\n   : 'STRING_TO_TABLE'\n   ;\n\nSTRPOS\n   : 'STRPOS'\n   ;\n\nSUBSTR\n   : 'SUBSTR'\n   ;\n\nTO_ASCII\n   : 'TO_ASCII'\n   ;\n\nTO_HEX\n   : 'TO_HEX'\n   ;\n\nTRANSLATE\n   : 'TRANSLATE'\n   ;\n\nUNISTR\n   : 'UNISTR'\n   ;\n\nAGE\n   : 'AGE'\n   ;\n\nCLOCK_TIMESTAMP\n   : 'CLOCK_TIMESTAMP'\n   ;\n\nDATE_BIN\n   : 'DATE_BIN'\n   ;\n\nDATE_PART\n   : 'DATE_PART'\n   ;\n\nDATE_TRUNC\n   : 'DATE_TRUNC'\n   ;\n\nISFINITE\n   : 'ISFINITE'\n   ;\n\nJUSTIFY_DAYS\n   : 'JUSTIFY_DAYS'\n   ;\n\nJUSTIFY_HOURS\n   : 'JUSTIFY_HOURS'\n   ;\n\nJUSTIFY_INTERVAL\n   : 'JUSTIFY_INTERVAL'\n   ;\n\nMAKE_DATE\n   : 'MAKE_DATE'\n   ;\n\nMAKE_INTERVAL\n   : 'MAKE_INTERVAL'\n   ;\n\nMAKE_TIME\n   : 'MAKE_TIME'\n   ;\n\nMAKE_TIMESTAMP\n   : 'MAKE_TIMESTAMP'\n   ;\n\nMAKE_TIMESTAMPTZ\n   : 'MAKE_TIMESTAMPTZ'\n   ;\n\nNOW\n   : 'NOW'\n   ;\n\nSTATEMENT_TIMESTAMP\n   : 'STATEMENT_TIMESTAMP'\n   ;\n\nTIMEOFDAY\n   : 'TIMEOFDAY'\n   ;\n\nTRANSACTION_TIMESTAMP\n   : 'TRANSACTION_TIMESTAMP'\n   ;\n\nTO_TIMESTAMP\n   : 'TO_TIMESTAMP'\n   ;\n\nTO_CHAR\n   : 'TO_CHAR'\n   ;\n\nTO_DATE\n   : 'TO_DATE'\n   ;\n\nTO_NUMBER\n   : 'TO_NUMBER'\n   ;\n\nIdentifier\n   : IdentifierStartChar IdentifierChar*\n   ;\n\nfragment IdentifierStartChar\n   : // these are the valid identifier start characters below 0x7F\n   [a-zA-Z_]\n   | // these are the valid characters from 0x80 to 0xFF\n   [\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u00FF]\n   | // these are the letters above 0xFF which only need a single UTF-16 code unit\n   [\\u0100-\\uD7FF\\uE000-\\uFFFF]\n   {charIsLetter()}?\n   | // letters which require multiple UTF-16 code units\n   [\\uD800-\\uDBFF] [\\uDC00-\\uDFFF]\n   {\n    CheckIfUtf32Letter()\n   }?\n\n   ;\n\nfragment IdentifierChar\n   : StrictIdentifierChar\n   | '$'\n   ;\n\nfragment StrictIdentifierChar\n   : IdentifierStartChar\n   | [0-9]\n   ;\n/* Quoted Identifiers\n *\n *   These are divided into four separate tokens, allowing distinction of valid quoted identifiers from invalid quoted\n *   identifiers without sacrificing the ability of the lexer to reliably recover from lexical errors in the input.\n */\n\n\nQuotedIdentifier\n   : UnterminatedQuotedIdentifier '\"'\n   ;\n   // This is a quoted identifier which only contains valid characters but is not terminated\n\nUnterminatedQuotedIdentifier\n   : '\"' ('\"\"' | ~ [\\u0000\"])*\n   ;\n   // This is a quoted identifier which is terminated but contains a \\u0000 character\nInvalidQuotedIdentifier\n   : InvalidUnterminatedQuotedIdentifier '\"'\n   ;\n   // This is a quoted identifier which is unterminated and contains a \\u0000 character\nInvalidUnterminatedQuotedIdentifier\n   : '\"' ('\"\"' | ~ '\"')*\n   ;\n/* Unicode Quoted Identifiers\n *\n *   These are divided into four separate tokens, allowing distinction of valid Unicode quoted identifiers from invalid\n *   Unicode quoted identifiers without sacrificing the ability of the lexer to reliably recover from lexical errors in\n *   the input. Note that escape sequences are never checked as part of this determination due to the ability of users\n *   to change the escape character with a UESCAPE clause following the Unicode quoted identifier.\n *\n * TODO: these rules assume \"\" is still a valid escape sequence within a Unicode quoted identifier.\n */\nUnicodeQuotedIdentifier\n   : 'U' '&' QuotedIdentifier\n   ;\n   // This is a Unicode quoted identifier which only contains valid characters but is not terminated\nUnterminatedUnicodeQuotedIdentifier\n   : 'U' '&' UnterminatedQuotedIdentifier\n   ;\n   // This is a Unicode quoted identifier which is terminated but contains a \\u0000 character\nInvalidUnicodeQuotedIdentifier\n   : 'U' '&' InvalidQuotedIdentifier\n   ;\n   // This is a Unicode quoted identifier which is unterminated and contains a \\u0000 character\nInvalidUnterminatedUnicodeQuotedIdentifier\n   : 'U' '&' InvalidUnterminatedQuotedIdentifier\n   ;\n   //\n   // CONSTANTS (4.1.2)\n   //\n   // String Constants (4.1.2.1)\nStringConstant\n   : UnterminatedStringConstant '\\''\n   ;\n\nUnterminatedStringConstant\n   : '\\'' ('\\'\\'' | ~ '\\'')*\n   ;\n   // String Constants with C-style Escapes (4.1.2.2)\n\nBeginEscapeStringConstant\n   : 'E' '\\'' -> more , pushMode (EscapeStringConstantMode)\n   ;\n   // String Constants with Unicode Escapes (4.1.2.3)\n\n   //\n\n   //   Note that escape sequences are never checked as part of this token due to the ability of users to change the escape\n\n   //   character with a UESCAPE clause following the Unicode string constant.\n\n   //\n\n   // TODO: these rules assume '' is still a valid escape sequence within a Unicode string constant.\n\nUnicodeEscapeStringConstant\n   : UnterminatedUnicodeEscapeStringConstant '\\''\n   ;\n\nUnterminatedUnicodeEscapeStringConstant\n   : 'U' '&' UnterminatedStringConstant\n   ;\n   // Dollar-quoted String Constants (4.1.2.4)\n\nBeginDollarStringConstant\n   : '$' Tag? '$'\n   {pushTag();} -> pushMode (DollarQuotedStringMode)\n   ;\n/* \"The tag, if any, of a dollar-quoted string follows the same rules as an\n * unquoted identifier, except that it cannot contain a dollar sign.\"\n */\n\n\nfragment Tag\n   : IdentifierStartChar StrictIdentifierChar*\n   ;\n   // Bit-strings Constants (4.1.2.5)\n\nBinaryStringConstant\n   : UnterminatedBinaryStringConstant '\\''\n   ;\n\nUnterminatedBinaryStringConstant\n   : 'B' '\\'' [01]*\n   ;\n\nInvalidBinaryStringConstant\n   : InvalidUnterminatedBinaryStringConstant '\\''\n   ;\n\nInvalidUnterminatedBinaryStringConstant\n   : 'B' UnterminatedStringConstant\n   ;\n\nHexadecimalStringConstant\n   : UnterminatedHexadecimalStringConstant '\\''\n   ;\n\nUnterminatedHexadecimalStringConstant\n   : 'X' '\\'' [0-9A-F]*\n   ;\n\nInvalidHexadecimalStringConstant\n   : InvalidUnterminatedHexadecimalStringConstant '\\''\n   ;\n\nInvalidUnterminatedHexadecimalStringConstant\n   : 'X' UnterminatedStringConstant\n   ;\n   // Numeric Constants (4.1.2.6)\n\nIntegral\n   : Digits\n   ;\n\nNumericFail\n   : Digits '..'\n   {HandleNumericFail();}\n   ;\n\nNumeric\n   : Digits '.' Digits? /*? replaced with + to solve problem with DOT_DOT .. but this surely must be rewriten */\n\n   ('E' [+-]? Digits)?\n   | '.' Digits ('E' [+-]? Digits)?\n   | Digits 'E' [+-]? Digits\n   ;\n\nfragment Digits\n   : [0-9]+\n   ;\n\nPLSQLVARIABLENAME\n   : ':' [A-Z_] [A-Z_0-9$]*\n   ;\n\nPLSQLIDENTIFIER\n   : ':\"' ('\\\\' . | '\"\"' | ~ ('\"' | '\\\\'))* '\"'\n   ;\n   //\n\n   // WHITESPACE (4.1)\n\n   //\n\nWhitespace\n   : [ \\t]+ -> channel (HIDDEN)\n   ;\n\nNewline\n   : ('\\r' '\\n'? | '\\n') -> channel (HIDDEN)\n   ;\n   //\n\n   // COMMENTS (4.1.5)\n\n   //\n\nLineComment\n   : '--' ~ [\\r\\n]* -> channel (HIDDEN)\n   ;\n\nBlockComment\n   : ('/*' ('/'* BlockComment | ~ [/*] | '/'+ ~ [/*] | '*'+ ~ [/*])* '*'* '*/') -> channel (HIDDEN)\n   ;\nUnterminatedBlockComment\n   : '/*' ('/'* BlockComment | // these characters are not part of special sequences in a block comment\n   ~ [/*] | // handle / or * characters which are not part of /* or */ and do not appear at the end of the file\n   ('/'+ ~ [/*] | '*'+ ~ [/*]))*\n   // Handle the case of / or * characters at the end of the file, or a nested unterminated block comment\n   ('/'+ | '*'+ | '/'* UnterminatedBlockComment)?\n   // Optional assertion to make sure this rule is working as intended\n   {\n            UnterminatedBlockCommentDebugAssert();\n   }\n   ;\n   //\n   // META-COMMANDS\n   //\n   // http://www.postgresql.org/docs/9.3/static/app-psql.html\nMetaCommand\n   : '\\\\' (~ [\\r\\n\\\\\"] | '\"' ~ [\\r\\n\"]* '\"')* ('\"' ~ [\\r\\n\"]*)?\n   ;\nEndMetaCommand\n   : '\\\\\\\\'\n   ;\n   //\n   // ERROR\n   //\n   // Any character which does not match one of the above rules will appear in the token stream as an ErrorCharacter token.\n   // This ensures the lexer itself will never encounter a syntax error, so all error handling may be performed by the\n   // parser.\nErrorCharacter\n   : .\n   ;\nmode EscapeStringConstantMode;\nEscapeStringConstant\n   : EscapeStringText '\\'' -> mode (AfterEscapeStringConstantMode)\n   ;\nUnterminatedEscapeStringConstant\n   : EscapeStringText\n   // Handle a final unmatched \\ character appearing at the end of the file\n   '\\\\'? EOF\n   ;\nfragment EscapeStringText\n   : ('\\'\\'' | '\\\\' ( // two-digit hex escapes are still valid when treated as single-digit escapes\n   'x' [0-9a-fA-F] |\n   'u' [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] |\n   'U' [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] | // Any character other than the Unicode escapes can follow a backslash. Some have special meaning,\n   // but that doesn't affect the syntax.\n   ~ [xuU]) | ~ ['\\\\])*\n   ;\nInvalidEscapeStringConstant\n   : InvalidEscapeStringText '\\'' -> mode (AfterEscapeStringConstantMode)\n   ;\nInvalidUnterminatedEscapeStringConstant\n   : InvalidEscapeStringText\n   // Handle a final unmatched \\ character appearing at the end of the file\n   '\\\\'? EOF\n   ;\nfragment InvalidEscapeStringText\n   : ('\\'\\'' | '\\\\' . | ~ ['\\\\])*\n   ;\nmode AfterEscapeStringConstantMode;\nAfterEscapeStringConstantMode_Whitespace\n   : Whitespace -> type (Whitespace) , channel (HIDDEN)\n   ;\nAfterEscapeStringConstantMode_Newline\n   : Newline -> type (Newline) , channel (HIDDEN) , mode (AfterEscapeStringConstantWithNewlineMode)\n   ;\nAfterEscapeStringConstantMode_NotContinued\n   :\n   {} // intentionally empty\n   -> skip , popMode\n   ;\nmode AfterEscapeStringConstantWithNewlineMode;\nAfterEscapeStringConstantWithNewlineMode_Whitespace\n   : Whitespace -> type (Whitespace) , channel (HIDDEN)\n   ;\nAfterEscapeStringConstantWithNewlineMode_Newline\n   : Newline -> type (Newline) , channel (HIDDEN)\n   ;\nAfterEscapeStringConstantWithNewlineMode_Continued\n   : '\\'' -> more , mode (EscapeStringConstantMode)\n   ;\nAfterEscapeStringConstantWithNewlineMode_NotContinued\n   :\n   {} // intentionally empty\n   -> skip , popMode\n   ;\nmode DollarQuotedStringMode;\nDollarText\n   : ~ '$'+\n   //| '$'([0-9])+\n   | // this alternative improves the efficiency of handling $ characters within a dollar-quoted string which are\n   // not part of the ending tag.\n   '$' ~ '$'*\n   ;\nEndDollarStringConstant\n   : ('$' Tag? '$')\n   {isTag()}?\n   {popTag();} -> popMode\n   ;"
  },
  {
    "path": "superior-redshift-parser/src/main/antlr4/io/github/melin/superior/parser/redshift/antlr4/RedshiftParser.g4",
    "content": "parser grammar RedshiftParser;\n\n\noptions { tokenVocab = RedshiftLexer;\n    superClass = RedshiftParserBase;\n}\n\n@header\n{\n}\n@members\n{\n}\nroot\n   : stmtblock EOF\n   ;\n\nsqlroot\n   : pl_function\n   ;\n\nstmtblock\n   : stmtmulti\n   ;\n\nstmtmulti\n   : (stmt SEMI?)*\n   ;\n\nstmt\n   : altereventtrigstmt\n   | altercollationstmt\n   | alterdatabasestmt\n   | alterdatabasesetstmt\n   | alterdefaultprivilegesstmt\n   | alterdomainstmt\n   | alterenumstmt\n   | alterextensionstmt\n   | alterextensioncontentsstmt\n   | alterfdwstmt\n   | alterforeignserverstmt\n   | alterfunctionstmt\n   | altergroupstmt\n   | alterobjectdependsstmt\n   | alterobjectschemastmt\n   | alterownerstmt\n   | alteroperatorstmt\n   | altertypestmt\n   | alterpolicystmt\n   | alterseqstmt\n   | altersystemstmt\n   | altertablestmt\n   | altertblspcstmt\n   | altercompositetypestmt\n   | alterpublicationstmt\n   | alterrolesetstmt\n   | alterrolestmt\n   | altersubscriptionstmt\n   | alterstatsstmt\n   | altertsconfigurationstmt\n   | altertsdictionarystmt\n   | alterusermappingstmt\n   | analyzestmt\n   | callstmt\n   | checkpointstmt\n   | closeportalstmt\n   | clusterstmt\n   | commentstmt\n   | constraintssetstmt\n   | copystmt\n   | createamstmt\n   | createasstmt\n   | createassertionstmt\n   | createcaststmt\n   | createconversionstmt\n   | createdomainstmt\n   | createextensionstmt\n   | createfdwstmt\n   | createforeignserverstmt\n   | createforeigntablestmt\n   | createfunctionstmt\n   | creategroupstmt\n   | creatematviewstmt\n   | createopclassstmt\n   | createopfamilystmt\n   | createpublicationstmt\n   | alteropfamilystmt\n   | createpolicystmt\n   | createplangstmt\n   | createschemastmt\n   | createseqstmt\n   | createstmt\n   | createsubscriptionstmt\n   | createstatsstmt\n   | createtablespacestmt\n   | createtransformstmt\n   | createtrigstmt\n   | createeventtrigstmt\n   | createrolestmt\n   | createuserstmt\n   | createusermappingstmt\n   | createdbstmt\n   | deallocatestmt\n   | declarecursorstmt\n   | definestmt\n   | deletestmt\n   | discardstmt\n   | dostmt\n   | dropcaststmt\n   | dropopclassstmt\n   | dropopfamilystmt\n   | dropownedstmt\n   | dropstmt\n   | dropsubscriptionstmt\n   | droptablespacestmt\n   | droptransformstmt\n   | droprolestmt\n   | dropusermappingstmt\n   | dropdbstmt\n   | executestmt\n   | explainstmt\n   | fetchstmt\n   | grantstmt\n   | grantrolestmt\n   | importforeignschemastmt\n   | indexstmt\n   | insertstmt\n   | mergestmt\n   | listenstmt\n   | refreshmatviewstmt\n   | loadstmt\n   | lockstmt\n   | notifystmt\n   | preparestmt\n   | reassignownedstmt\n   | reindexstmt\n   | removeaggrstmt\n   | removefuncstmt\n   | removeoperstmt\n   | renamestmt\n   | revokestmt\n   | revokerolestmt\n   | rulestmt\n   | seclabelstmt\n   | selectstmt\n   | transactionstmt\n   | truncatestmt\n   | unlistenstmt\n   | updatestmt\n   | vacuumstmt\n   | variableresetstmt\n   | variablesetstmt\n   | variableshowstmt\n   | showstmt\n   | viewstmt\n   | plsqlconsolecommand\n   ;\n\nplsqlconsolecommand\n   : MetaCommand EndMetaCommand?\n   ;\n\ncallstmt\n   : CALL func_application\n   ;\n\ncreaterolestmt\n   : CREATE ROLE roleid opt_with optrolelist\n   ;\n\nopt_with\n   : WITH\n   //| WITH_LA\n   |\n   ;\n\noptrolelist\n   : createoptroleelem*\n   ;\n\nalteroptrolelist\n   : alteroptroleelem*\n   ;\n\nalteroptroleelem\n   : PASSWORD (sconst | NULL_P)\n   | (ENCRYPTED | UNENCRYPTED) PASSWORD sconst\n   | INHERIT\n   | CONNECTION LIMIT signediconst\n   | VALID UNTIL sconst\n   | USER role_list\n   | identifier\n   ;\n\ncreateoptroleelem\n   : alteroptroleelem\n   | SYSID iconst\n   | ADMIN role_list\n   | ROLE role_list\n   | IN_P (ROLE | GROUP_P) role_list\n   ;\n\ncreateuserstmt\n   : CREATE USER roleid opt_with optrolelist\n   ;\n\nalterrolestmt\n   : ALTER (ROLE | USER) rolespec opt_with alteroptrolelist\n   ;\n\nopt_in_database\n   :\n   | IN_P DATABASE name\n   ;\n\nalterrolesetstmt\n   : ALTER (ROLE | USER) ALL? rolespec opt_in_database setresetclause\n   ;\n\ndroprolestmt\n   : DROP (ROLE | USER | GROUP_P) (IF_P EXISTS)? role_list\n   ;\n\ncreategroupstmt\n   : CREATE GROUP_P roleid opt_with optrolelist\n   ;\n\naltergroupstmt\n   : ALTER GROUP_P rolespec add_drop USER role_list\n   ;\n\nadd_drop\n   : ADD_P\n   | DROP\n   ;\n\ncreateschemastmt\n   : CREATE SCHEMA (IF_P NOT EXISTS)? (optschemaname AUTHORIZATION rolespec | colid) optschemaeltlist\n   ;\n\noptschemaname\n   : colid\n   |\n   ;\n\noptschemaeltlist\n   : schema_stmt*\n   ;\n\nschema_stmt\n   : createstmt\n   | indexstmt\n   | createseqstmt\n   | createtrigstmt\n   | grantstmt\n   | viewstmt\n   ;\n\nvariablesetstmt\n   : SET (LOCAL | SESSION)? set_rest\n   ;\n\nset_rest\n   : TRANSACTION transaction_mode_list\n   | SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list\n   | set_rest_more\n   ;\n\ngeneric_set\n   : var_name (TO | EQUAL) var_list\n   ;\n\nset_rest_more\n   : generic_set\n   | var_name FROM CURRENT_P\n   | TIME ZONE zone_value\n   | CATALOG sconst\n   | SCHEMA sconst\n   | NAMES opt_encoding\n   | ROLE nonreservedword_or_sconst\n   | SESSION AUTHORIZATION nonreservedword_or_sconst\n   | XML_P OPTION document_or_content\n   | TRANSACTION SNAPSHOT sconst\n   ;\n\nvar_name\n   : colid (DOT colid)*\n   ;\n\nvar_list\n   : var_value (COMMA var_value)*\n   ;\n\nvar_value\n   : opt_boolean_or_string\n   | numericonly\n   ;\n\niso_level\n   : READ (UNCOMMITTED | COMMITTED)\n   | REPEATABLE READ\n   | SERIALIZABLE\n   ;\n\nopt_boolean_or_string\n   : TRUE_P\n   | FALSE_P\n   | ON\n   | nonreservedword_or_sconst\n   ;\n\nzone_value\n   : sconst\n   | identifier\n   | constinterval sconst opt_interval\n   | constinterval OPEN_PAREN iconst CLOSE_PAREN sconst\n   | numericonly\n   | DEFAULT\n   | LOCAL\n   ;\n\nopt_encoding\n   : sconst\n   | DEFAULT\n   |\n   ;\n\nnonreservedword_or_sconst\n   : nonreservedword\n   | sconst\n   ;\n\nvariableresetstmt\n   : RESET reset_rest\n   ;\n\nreset_rest\n   : generic_reset\n   | TIME ZONE\n   | TRANSACTION ISOLATION LEVEL\n   | SESSION AUTHORIZATION\n   ;\n\ngeneric_reset\n   : var_name\n   | ALL\n   ;\n\nsetresetclause\n   : SET set_rest\n   | variableresetstmt\n   ;\n\nfunctionsetresetclause\n   : SET set_rest_more\n   | variableresetstmt\n   ;\n\nvariableshowstmt\n   : SHOW (var_name | TIME ZONE | TRANSACTION ISOLATION LEVEL | SESSION AUTHORIZATION | ALL)\n   ;\n\n// redshift show https://docs.aws.amazon.com/redshift/latest/dg/r_SHOW_COLUMNS.html start\nshowstmt\n   : SHOW COLUMNS FROM TABLE qualified_name (LIKE a_expr_qual_op)? (LIMIT select_limit_value)?\n   | SHOW EXTERNAL TABLE qualified_name (PARTITION)?\n   | SHOW SCHEMAS FROM DATABASE qualified_name (LIKE a_expr_qual_op)? (LIMIT select_limit_value)?\n   | SHOW TABLE qualified_name\n   | SHOW VIEW qualified_name\n   | SHOW TABLES FROM SCHEMA qualified_name (LIKE a_expr_qual_op)? (LIMIT select_limit_value)?\n   ;\n// end\n\nconstraintssetstmt\n   : SET CONSTRAINTS constraints_set_list constraints_set_mode\n   ;\n\nconstraints_set_list\n   : ALL\n   | qualified_name_list\n   ;\n\nconstraints_set_mode\n   : DEFERRED\n   | IMMEDIATE\n   ;\n\ncheckpointstmt\n   : CHECKPOINT\n   ;\n\ndiscardstmt\n   : DISCARD (ALL | TEMP | TEMPORARY | PLANS | SEQUENCES)\n   ;\n\naltertablestmt\n   : ALTER TABLE (IF_P EXISTS)? relation_expr (alter_table_cmds | partition_cmd)\n   | ALTER TABLE ALL IN_P TABLESPACE name (OWNED BY role_list)? SET TABLESPACE name opt_nowait\n   | ALTER INDEX (IF_P EXISTS)? qualified_name (alter_table_cmds | index_partition_cmd)\n   | ALTER INDEX ALL IN_P TABLESPACE name (OWNED BY role_list)? SET TABLESPACE name opt_nowait\n   | ALTER SEQUENCE (IF_P EXISTS)? qualified_name alter_table_cmds\n   | ALTER VIEW (IF_P EXISTS)? qualified_name alter_table_cmds\n   | ALTER MATERIALIZED VIEW (IF_P EXISTS)? qualified_name alter_table_cmds\n   | ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name (OWNED BY role_list)? SET TABLESPACE name opt_nowait\n   | ALTER FOREIGN TABLE (IF_P EXISTS)? relation_expr alter_table_cmds\n   ;\n\nalter_table_cmds\n   : alter_table_cmd (COMMA alter_table_cmd)*\n   ;\n\npartition_cmd\n   : ATTACH PARTITION qualified_name partitionboundspec\n   | DETACH PARTITION qualified_name\n   ;\n\nindex_partition_cmd\n   : ATTACH PARTITION qualified_name\n   ;\n\nalter_table_cmd\n   : ADD_P columnDef\n   | ADD_P IF_P NOT EXISTS columnDef\n   | ADD_P COLUMN columnDef\n   | ADD_P COLUMN IF_P NOT EXISTS columnDef\n   | ALTER opt_column colid alter_column_default\n   | ALTER opt_column colid DROP NOT NULL_P\n   | ALTER opt_column colid SET NOT NULL_P\n   | ALTER opt_column colid DROP EXPRESSION\n   | ALTER opt_column colid DROP EXPRESSION IF_P EXISTS\n   | ALTER opt_column colid SET STATISTICS signediconst\n   | ALTER opt_column iconst SET STATISTICS signediconst\n   | ALTER opt_column colid SET reloptions\n   | ALTER opt_column colid RESET reloptions\n   | ALTER opt_column colid SET STORAGE colid\n   | ALTER opt_column colid ADD_P GENERATED generated_when AS IDENTITY_P optparenthesizedseqoptlist\n   | ALTER opt_column colid alter_identity_column_option_list\n   | ALTER opt_column colid DROP IDENTITY_P\n   | ALTER opt_column colid DROP IDENTITY_P IF_P EXISTS\n   | DROP opt_column IF_P EXISTS colid opt_drop_behavior\n   | DROP opt_column colid opt_drop_behavior\n   | ALTER opt_column colid opt_set_data TYPE_P typename opt_collate_clause alter_using\n   | ALTER opt_column colid alter_generic_options\n   | ADD_P tableconstraint\n   | ALTER CONSTRAINT name constraintattributespec\n   | VALIDATE CONSTRAINT name\n   | DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior\n   | DROP CONSTRAINT name opt_drop_behavior\n   | SET WITHOUT OIDS\n   | CLUSTER ON name\n   | SET WITHOUT CLUSTER\n   | SET LOGGED\n   | SET UNLOGGED\n   | ENABLE_P TRIGGER name\n   | ENABLE_P ALWAYS TRIGGER name\n   | ENABLE_P REPLICA TRIGGER name\n   | ENABLE_P TRIGGER ALL\n   | ENABLE_P TRIGGER USER\n   | DISABLE_P TRIGGER name\n   | DISABLE_P TRIGGER ALL\n   | DISABLE_P TRIGGER USER\n   | ENABLE_P RULE name\n   | ENABLE_P ALWAYS RULE name\n   | ENABLE_P REPLICA RULE name\n   | DISABLE_P RULE name\n   | INHERIT qualified_name\n   | NO INHERIT qualified_name\n   | OF any_name\n   | NOT OF\n   | OWNER TO rolespec\n   | SET TABLESPACE name\n   | SET reloptions\n   | RESET reloptions\n   | REPLICA IDENTITY_P replica_identity\n   | ENABLE_P ROW LEVEL SECURITY\n   | DISABLE_P ROW LEVEL SECURITY\n   | FORCE ROW LEVEL SECURITY\n   | NO FORCE ROW LEVEL SECURITY\n   | alter_generic_options\n   ;\n\nalter_column_default\n   : SET DEFAULT a_expr\n   | DROP DEFAULT\n   ;\n\nopt_drop_behavior\n   : CASCADE\n   | RESTRICT\n   |\n   ;\n\nopt_collate_clause\n   : COLLATE any_name\n   |\n   ;\n\nalter_using\n   : USING a_expr\n   |\n   ;\n\nreplica_identity\n   : NOTHING\n   | FULL\n   | DEFAULT\n   | USING INDEX name\n   ;\n\nreloptions\n   : OPEN_PAREN reloption_list CLOSE_PAREN\n   ;\n\nopt_reloptions\n   : WITH reloptions\n   |\n   ;\n\nreloption_list\n   : reloption_elem (COMMA reloption_elem)*\n   ;\n\nreloption_elem\n   : collabel (EQUAL def_arg | DOT collabel (EQUAL def_arg)?)?\n   ;\n\nalter_identity_column_option_list\n   : alter_identity_column_option+\n   ;\n\nalter_identity_column_option\n   : RESTART (opt_with numericonly)?\n   | SET (seqoptelem | GENERATED generated_when)\n   ;\n\npartitionboundspec\n   : FOR VALUES WITH OPEN_PAREN hash_partbound CLOSE_PAREN\n   | FOR VALUES IN_P OPEN_PAREN expr_list CLOSE_PAREN\n   | FOR VALUES FROM OPEN_PAREN expr_list CLOSE_PAREN TO OPEN_PAREN expr_list CLOSE_PAREN\n   | DEFAULT\n   ;\n\nhash_partbound_elem\n   : nonreservedword iconst\n   ;\n\nhash_partbound\n   : hash_partbound_elem (COMMA hash_partbound_elem)*\n   ;\n\naltercompositetypestmt\n   : ALTER TYPE_P any_name alter_type_cmds\n   ;\n\nalter_type_cmds\n   : alter_type_cmd (COMMA alter_type_cmd)*\n   ;\n\nalter_type_cmd\n   : ADD_P ATTRIBUTE tablefuncelement opt_drop_behavior\n   | DROP ATTRIBUTE (IF_P EXISTS)? colid opt_drop_behavior\n   | ALTER ATTRIBUTE colid opt_set_data TYPE_P typename opt_collate_clause opt_drop_behavior\n   ;\n\ncloseportalstmt\n   : CLOSE (cursor_name | ALL)\n   ;\n\ncopystmt\n   : COPY opt_binary qualified_name opt_column_list copy_from opt_program copy_file_name copy_delimiter opt_with copy_options where_clause\n   | COPY OPEN_PAREN preparablestmt CLOSE_PAREN TO opt_program copy_file_name opt_with copy_options\n   ;\n\ncopy_from\n   : FROM\n   | TO\n   ;\n\nopt_program\n   : PROGRAM\n   |\n   ;\n\ncopy_file_name\n   : sconst\n   | STDIN\n   | STDOUT\n   ;\n\ncopy_options\n   : copy_opt_list\n   | OPEN_PAREN copy_generic_opt_list CLOSE_PAREN\n   ;\n\ncopy_opt_list\n   : copy_opt_item*\n   ;\n\ncopy_opt_item\n   : BINARY\n   | FREEZE\n   | DELIMITER opt_as sconst\n   | NULL_P opt_as sconst\n   | CSV\n   | HEADER_P\n   | QUOTE opt_as sconst\n   | ESCAPE opt_as sconst\n   | FORCE QUOTE columnlist\n   | FORCE QUOTE STAR\n   | FORCE NOT NULL_P columnlist\n   | FORCE NULL_P columnlist\n   | ENCODING sconst\n   ;\n\nopt_binary\n   : BINARY\n   |\n   ;\n\ncopy_delimiter\n   : opt_using DELIMITERS sconst\n   |\n   ;\n\nopt_using\n   : USING\n   |\n   ;\n\ncopy_generic_opt_list\n   : copy_generic_opt_elem (COMMA copy_generic_opt_elem)*\n   ;\n\ncopy_generic_opt_elem\n   : collabel copy_generic_opt_arg\n   ;\n\ncopy_generic_opt_arg\n   : opt_boolean_or_string\n   | numericonly\n   | STAR\n   | OPEN_PAREN copy_generic_opt_arg_list CLOSE_PAREN\n   |\n   ;\n\ncopy_generic_opt_arg_list\n   : copy_generic_opt_arg_list_item (COMMA copy_generic_opt_arg_list_item)*\n   ;\n\ncopy_generic_opt_arg_list_item\n   : opt_boolean_or_string\n   ;\n\ncreatestmt\n   : CREATE opttemp TABLE (IF_P NOT EXISTS)? qualified_name\n   (\n        OPEN_PAREN opttableelementlist CLOSE_PAREN optinherit optpartitionspec table_access_method_clause gaussprimayindex optwith oncommitoption opttablespace gaussextension\n        | OF any_name opttypedtableelementlist optpartitionspec table_access_method_clause optwith oncommitoption opttablespace\n        | PARTITION OF qualified_name opttypedtableelementlist partitionboundspec optpartitionspec table_access_method_clause optwith oncommitoption opttablespace\n   )\n   ;\n\n// -------- support gauss\n\ngaussprimayindex\n   : PRIMARY INDEX OPEN_PAREN colid CLOSE_PAREN\n   |\n   ;\n\ngaussextension\n   : distributeby toGroupOrNode tablePartition?\n   |\n   ;\n\ndistributeby\n   : DISTRIBUTE BY (REPLICATION | ROUNDROBIN | HASH OPEN_PAREN distributebyhashlist CLOSE_PAREN)\n   | DISTRIBUTED BY OPEN_PAREN distributebyhashlist CLOSE_PAREN\n   | DISTRIBUTED (RANDOMLY | REPLICATED)\n   |\n   ;\n\ndistributebyhashlist\n   : distributebyhashitem (COMMA distributebyhashitem)*\n   ;\n\ndistributebyhashitem\n   : collabel\n   ;\n\ntoGroupOrNode\n   : TO GROUP_P collabel\n   | TO NODE_P OPEN_PAREN collabel (COMMA collabel)* CLOSE_PAREN\n   |\n   ;\n\n tablePartition\n   : PARTITION BY partition_list ((ENABLE_P | DISABLE_P) ROW MOVEMENT)?\n   ;\n\n partition_list\n   : value_partition_stmt\n   | range_partition_stmt\n   | list_partition_stmt\n   | normal_partition_stmt\n   ;\n\nnormal_partition_stmt\n   : OPEN_PAREN list_partition_value CLOSE_PAREN AUTOMAPPED?\n   ;\n\nlist_partition_stmt\n   : LIST_P OPEN_PAREN partition_key CLOSE_PAREN OPEN_PAREN list_partition_items CLOSE_PAREN\n   ;\n\nlist_partition_items\n   : list_partition_item (COMMA list_partition_item)*\n   ;\n\nlist_partition_item\n   : PARTITION partition_name VALUES LESS THAN OPEN_PAREN list_partition_value CLOSE_PAREN table_space_item?\n   ;\n\nlist_partition_value\n   : partition_name (COMMA partition_name)*\n   | DEFAULT\n   ;\n\nvalue_partition_stmt\n   : VALUES OPEN_PAREN partition_key CLOSE_PAREN\n   ;\n\nrange_partition_stmt\n   : RANGE OPEN_PAREN partition_key CLOSE_PAREN OPEN_PAREN (partition_less_than_items | partition_start_end_items) CLOSE_PAREN\n   ;\n\npartition_less_than_items\n   : partition_less_than_item (COMMA partition_less_than_item)*\n   ;\n\npartition_start_end_items\n   : partition_start_end_item (COMMA partition_start_end_item)*\n   ;\n\npartition_less_than_item\n   : PARTITION partition_name VALUES LESS THAN OPEN_PAREN (partition_value | MAXVALUE) CLOSE_PAREN table_space_item?\n   ;\n\npartition_start_end_item\n   : PARTITION partition_name start_end_item table_space_item?\n   ;\n\nstart_end_item\n   : start_item\n   | end_item\n   | start_item end_item (EVERY OPEN_PAREN aexprconst CLOSE_PAREN)?\n   ;\n\nstart_item\n   : START OPEN_PAREN partition_value CLOSE_PAREN\n   ;\n\nend_item\n   : END_P OPEN_PAREN (partition_value | MAXVALUE) CLOSE_PAREN\n   ;\n\npartition_key\n   : colid\n   ;\n\npartition_name\n   : colid\n   ;\n\npartition_value\n   : a_expr\n   ;\n\ntable_space_item\n   : TABLESPACE table_space_name\n   ;\n\ntable_space_name\n   : qualified_name\n   ;\n\n// -------- support gauss\n\nopttemp\n   : TEMPORARY\n   | TEMP\n   | LOCAL (TEMPORARY | TEMP)\n   | GLOBAL (TEMPORARY | TEMP)\n   | UNLOGGED\n   |\n   ;\n\nopttableelementlist\n   : tableelementlist\n   |\n   ;\n\nopttypedtableelementlist\n   : OPEN_PAREN typedtableelementlist CLOSE_PAREN\n   |\n   ;\n\ntableelementlist\n   : tableelement (COMMA tableelement)*\n   ;\n\ntypedtableelementlist\n   : typedtableelement (COMMA typedtableelement)*\n   ;\n\ntableelement\n   : tableconstraint\n   | tablelikeclause\n   | columnDef\n   ;\n\ntypedtableelement\n   : columnOptions\n   | tableconstraint\n   ;\n\ncolumnDef\n   : colid typename create_generic_options colquallist\n   ;\n\ncolumnOptions\n   : colid (WITH OPTIONS)? colquallist\n   ;\n\ncolquallist\n   : colconstraint*\n   ;\n\ncolconstraint\n   : CONSTRAINT name colconstraintelem\n   | colconstraintelem\n   | constraintattr\n   | COLLATE any_name\n   ;\n\ncolconstraintelem\n   : NOT NULL_P\n   | NULL_P\n   | UNIQUE opt_definition optconstablespace\n   | PRIMARY KEY opt_definition optconstablespace\n   | CHECK OPEN_PAREN a_expr CLOSE_PAREN opt_no_inherit\n   | DEFAULT b_expr\n   | GENERATED generated_when AS (IDENTITY_P optparenthesizedseqoptlist | OPEN_PAREN a_expr CLOSE_PAREN STORED)\n   | REFERENCES qualified_name opt_column_list key_match key_actions\n   ;\n\ngenerated_when\n   : ALWAYS\n   | BY DEFAULT\n   ;\n\nconstraintattr\n   : DEFERRABLE\n   | NOT DEFERRABLE\n   | INITIALLY (DEFERRED | IMMEDIATE)\n   ;\n\ntablelikeclause\n   : LIKE qualified_name tablelikeoptionlist\n   ;\n\ntablelikeoptionlist\n   : ((INCLUDING | EXCLUDING) tablelikeoption)*\n   ;\n\ntablelikeoption\n   : COMMENTS\n   | CONSTRAINTS\n   | DEFAULTS\n   | IDENTITY_P\n   | GENERATED\n   | INDEXES\n   | STATISTICS\n   | STORAGE\n   | ALL\n   ;\n\ntableconstraint\n   : CONSTRAINT name constraintelem\n   | constraintelem\n   ;\n\nconstraintelem\n   : CHECK OPEN_PAREN a_expr CLOSE_PAREN constraintattributespec\n   | UNIQUE (OPEN_PAREN columnlist CLOSE_PAREN opt_c_include opt_definition optconstablespace constraintattributespec | existingindex constraintattributespec)\n   | PRIMARY KEY (OPEN_PAREN columnlist CLOSE_PAREN opt_c_include opt_definition optconstablespace constraintattributespec | existingindex constraintattributespec)\n   | EXCLUDE access_method_clause OPEN_PAREN exclusionconstraintlist CLOSE_PAREN opt_c_include opt_definition optconstablespace exclusionwhereclause constraintattributespec\n   | FOREIGN KEY OPEN_PAREN columnlist CLOSE_PAREN REFERENCES qualified_name opt_column_list key_match key_actions constraintattributespec\n   ;\n\nopt_no_inherit\n   : NO INHERIT\n   |\n   ;\n\nopt_column_list\n   : OPEN_PAREN columnlist CLOSE_PAREN\n   |\n   ;\n\ncolumnlist\n   : columnElem (COMMA columnElem)*\n   ;\n\ncolumnElem\n   : colid\n   ;\n\nopt_c_include\n   : INCLUDE OPEN_PAREN columnlist CLOSE_PAREN\n   |\n   ;\n\nkey_match\n   : MATCH (FULL | PARTIAL | SIMPLE)\n   |\n   ;\n\nexclusionconstraintlist\n   : exclusionconstraintelem (COMMA exclusionconstraintelem)*\n   ;\n\nexclusionconstraintelem\n   : index_elem WITH (any_operator | OPERATOR OPEN_PAREN any_operator CLOSE_PAREN)\n   ;\n\nexclusionwhereclause\n   : WHERE OPEN_PAREN a_expr CLOSE_PAREN\n   |\n   ;\n\nkey_actions\n   : key_update\n   | key_delete\n   | key_update key_delete\n   | key_delete key_update\n   |\n   ;\n\nkey_update\n   : ON UPDATE key_action\n   ;\n\nkey_delete\n   : ON DELETE_P key_action\n   ;\n\nkey_action\n   : NO ACTION\n   | RESTRICT\n   | CASCADE\n   | SET (NULL_P | DEFAULT)\n   ;\n\noptinherit\n   : INHERITS OPEN_PAREN qualified_name_list CLOSE_PAREN\n   |\n   ;\n\noptpartitionspec\n   : partitionspec\n   |\n   ;\n\npartitionspec\n   : PARTITION BY colid OPEN_PAREN part_params CLOSE_PAREN\n   ;\n\npart_params\n   : part_elem (COMMA part_elem)*\n   ;\n\npart_elem\n   : colid opt_collate opt_class\n   | func_expr_windowless opt_collate opt_class\n   | OPEN_PAREN a_expr CLOSE_PAREN opt_collate opt_class\n   ;\n\ntable_access_method_clause\n   : USING name\n   |\n   ;\n\noptwith\n   : WITH reloptions\n   | WITHOUT OIDS\n   |\n   ;\n\noncommitoption\n   : ON COMMIT (DROP | DELETE_P ROWS | PRESERVE ROWS)\n   |\n   ;\n\nopttablespace\n   : TABLESPACE name\n   |\n   ;\n\noptconstablespace\n   : USING INDEX TABLESPACE name\n   |\n   ;\n\nexistingindex\n   : USING INDEX name\n   ;\n\ncreatestatsstmt\n   : CREATE STATISTICS (IF_P NOT EXISTS)? any_name opt_name_list ON expr_list FROM from_list\n   ;\n\nalterstatsstmt\n   : ALTER STATISTICS (IF_P EXISTS)? any_name SET STATISTICS signediconst\n   ;\n\ncreateasstmt\n   : CREATE opttemp TABLE (IF_P NOT EXISTS)? create_as_target AS selectstmt opt_with_data\n   ;\n\ncreate_as_target\n   : qualified_name opt_column_list table_access_method_clause optwith oncommitoption opttablespace\n   ;\n\nopt_with_data\n   : WITH (DATA_P | NO DATA_P)\n   |\n   ;\n\ncreatematviewstmt\n   : CREATE optnolog MATERIALIZED VIEW (IF_P NOT EXISTS)? create_mv_target AS selectstmt opt_with_data\n   ;\n\ncreate_mv_target\n   : qualified_name opt_column_list table_access_method_clause opt_reloptions opttablespace\n   ;\n\noptnolog\n   : UNLOGGED\n   |\n   ;\n\nrefreshmatviewstmt\n   : REFRESH MATERIALIZED VIEW opt_concurrently qualified_name opt_with_data\n   ;\n\ncreateseqstmt\n   : CREATE opttemp SEQUENCE (IF_P NOT EXISTS)? qualified_name optseqoptlist\n   ;\n\nalterseqstmt\n   : ALTER SEQUENCE (IF_P EXISTS)? qualified_name seqoptlist\n   ;\n\noptseqoptlist\n   : seqoptlist\n   |\n   ;\n\noptparenthesizedseqoptlist\n   : OPEN_PAREN seqoptlist CLOSE_PAREN\n   |\n   ;\n\nseqoptlist\n   : seqoptelem+\n   ;\n\nseqoptelem\n   : AS simpletypename\n   | CACHE numericonly\n   | CYCLE\n   | INCREMENT opt_by numericonly\n   | MAXVALUE numericonly\n   | MINVALUE numericonly\n   | NO (MAXVALUE | MINVALUE | CYCLE)\n   | OWNED BY any_name\n   | SEQUENCE NAME_P any_name\n   | START opt_with numericonly\n   | RESTART opt_with numericonly?\n   ;\n\nopt_by\n   : BY\n   |\n   ;\n\nnumericonly\n   : fconst\n   | PLUS fconst\n   | MINUS fconst\n   | signediconst\n   ;\n\nnumericonly_list\n   : numericonly (COMMA numericonly)*\n   ;\n\ncreateplangstmt\n   : CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE name (HANDLER handler_name opt_inline_handler opt_validator)?\n   ;\n\nopt_trusted\n   : TRUSTED\n   |\n   ;\n\nhandler_name\n   : name attrs?\n   ;\n\nopt_inline_handler\n   : INLINE_P handler_name\n   |\n   ;\n\nvalidator_clause\n   : VALIDATOR handler_name\n   | NO VALIDATOR\n   ;\n\nopt_validator\n   : validator_clause\n   |\n   ;\n\nopt_procedural\n   : PROCEDURAL\n   |\n   ;\n\ncreatetablespacestmt\n   : CREATE TABLESPACE name opttablespaceowner LOCATION sconst opt_reloptions\n   ;\n\nopttablespaceowner\n   : OWNER rolespec\n   |\n   ;\n\ndroptablespacestmt\n   : DROP TABLESPACE (IF_P EXISTS)? name\n   ;\n\ncreateextensionstmt\n   : CREATE EXTENSION (IF_P NOT EXISTS)? name opt_with create_extension_opt_list\n   ;\n\ncreate_extension_opt_list\n   : create_extension_opt_item*\n   ;\n\ncreate_extension_opt_item\n   : SCHEMA name\n   | VERSION_P nonreservedword_or_sconst\n   | FROM nonreservedword_or_sconst\n   | CASCADE\n   ;\n\nalterextensionstmt\n   : ALTER EXTENSION name UPDATE alter_extension_opt_list\n   ;\n\nalter_extension_opt_list\n   : alter_extension_opt_item*\n   ;\n\nalter_extension_opt_item\n   : TO nonreservedword_or_sconst\n   ;\n\nalterextensioncontentsstmt\n   : ALTER EXTENSION name add_drop object_type_name name\n   | ALTER EXTENSION name add_drop object_type_any_name any_name\n   | ALTER EXTENSION name add_drop AGGREGATE aggregate_with_argtypes\n   | ALTER EXTENSION name add_drop CAST OPEN_PAREN typename AS typename CLOSE_PAREN\n   | ALTER EXTENSION name add_drop DOMAIN_P typename\n   | ALTER EXTENSION name add_drop FUNCTION function_with_argtypes\n   | ALTER EXTENSION name add_drop OPERATOR operator_with_argtypes\n   | ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING name\n   | ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING name\n   | ALTER EXTENSION name add_drop PROCEDURE function_with_argtypes\n   | ALTER EXTENSION name add_drop ROUTINE function_with_argtypes\n   | ALTER EXTENSION name add_drop TRANSFORM FOR typename LANGUAGE name\n   | ALTER EXTENSION name add_drop TYPE_P typename\n   ;\n\ncreatefdwstmt\n   : CREATE FOREIGN DATA_P WRAPPER name opt_fdw_options create_generic_options\n   ;\n\nfdw_option\n   : HANDLER handler_name\n   | NO HANDLER\n   | VALIDATOR handler_name\n   | NO VALIDATOR\n   ;\n\nfdw_options\n   : fdw_option+\n   ;\n\nopt_fdw_options\n   : fdw_options\n   |\n   ;\n\nalterfdwstmt\n   : ALTER FOREIGN DATA_P WRAPPER name opt_fdw_options alter_generic_options\n   | ALTER FOREIGN DATA_P WRAPPER name fdw_options\n   ;\n\ncreate_generic_options\n   : OPTIONS OPEN_PAREN generic_option_list CLOSE_PAREN\n   |\n   ;\n\ngeneric_option_list\n   : generic_option_elem (COMMA generic_option_elem)*\n   ;\n\nalter_generic_options\n   : OPTIONS OPEN_PAREN alter_generic_option_list CLOSE_PAREN\n   ;\n\nalter_generic_option_list\n   : alter_generic_option_elem (COMMA alter_generic_option_elem)*\n   ;\n\nalter_generic_option_elem\n   : generic_option_elem\n   | SET generic_option_elem\n   | ADD_P generic_option_elem\n   | DROP generic_option_name\n   ;\n\ngeneric_option_elem\n   : generic_option_name generic_option_arg\n   ;\n\ngeneric_option_name\n   : collabel\n   ;\n\ngeneric_option_arg\n   : sconst\n   ;\n\ncreateforeignserverstmt\n   : CREATE SERVER name opt_type opt_foreign_server_version FOREIGN DATA_P WRAPPER name create_generic_options\n   | CREATE SERVER IF_P NOT EXISTS name opt_type opt_foreign_server_version FOREIGN DATA_P WRAPPER name create_generic_options\n   ;\n\nopt_type\n   : TYPE_P sconst\n   |\n   ;\n\nforeign_server_version\n   : VERSION_P (sconst | NULL_P)\n   ;\n\nopt_foreign_server_version\n   : foreign_server_version\n   |\n   ;\n\nalterforeignserverstmt\n   : ALTER SERVER name (alter_generic_options | foreign_server_version alter_generic_options?)\n   ;\n\ncreateforeigntablestmt\n   : CREATE FOREIGN TABLE qualified_name OPEN_PAREN opttableelementlist CLOSE_PAREN optinherit SERVER name create_generic_options\n   | CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name OPEN_PAREN opttableelementlist CLOSE_PAREN optinherit SERVER name create_generic_options\n   | CREATE FOREIGN TABLE qualified_name PARTITION OF qualified_name opttypedtableelementlist partitionboundspec SERVER name create_generic_options\n   | CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name PARTITION OF qualified_name opttypedtableelementlist partitionboundspec SERVER name create_generic_options\n   ;\n\nimportforeignschemastmt\n   : IMPORT_P FOREIGN SCHEMA name import_qualification FROM SERVER name INTO name create_generic_options\n   ;\n\nimport_qualification_type\n   : LIMIT TO\n   | EXCEPT\n   ;\n\nimport_qualification\n   : import_qualification_type OPEN_PAREN relation_expr_list CLOSE_PAREN\n   |\n   ;\n\ncreateusermappingstmt\n   : CREATE USER MAPPING FOR auth_ident SERVER name create_generic_options\n   | CREATE USER MAPPING IF_P NOT EXISTS FOR auth_ident SERVER name create_generic_options\n   ;\n\nauth_ident\n   : rolespec\n   | USER\n   ;\n\ndropusermappingstmt\n   : DROP USER MAPPING FOR auth_ident SERVER name\n   | DROP USER MAPPING IF_P EXISTS FOR auth_ident SERVER name\n   ;\n\nalterusermappingstmt\n   : ALTER USER MAPPING FOR auth_ident SERVER name alter_generic_options\n   ;\n\ncreatepolicystmt\n   : CREATE POLICY name ON qualified_name rowsecuritydefaultpermissive rowsecuritydefaultforcmd rowsecuritydefaulttorole rowsecurityoptionalexpr rowsecurityoptionalwithcheck\n   ;\n\nalterpolicystmt\n   : ALTER POLICY name ON qualified_name rowsecurityoptionaltorole rowsecurityoptionalexpr rowsecurityoptionalwithcheck\n   ;\n\nrowsecurityoptionalexpr\n   : USING OPEN_PAREN a_expr CLOSE_PAREN\n   |\n   ;\n\nrowsecurityoptionalwithcheck\n   : WITH CHECK OPEN_PAREN a_expr CLOSE_PAREN\n   |\n   ;\n\nrowsecuritydefaulttorole\n   : TO role_list\n   |\n   ;\n\nrowsecurityoptionaltorole\n   : TO role_list\n   |\n   ;\n\nrowsecuritydefaultpermissive\n   : AS identifier\n   |\n   ;\n\nrowsecuritydefaultforcmd\n   : FOR row_security_cmd\n   |\n   ;\n\nrow_security_cmd\n   : ALL\n   | SELECT\n   | INSERT\n   | UPDATE\n   | DELETE_P\n   ;\n\ncreateamstmt\n   : CREATE ACCESS METHOD name TYPE_P am_type HANDLER handler_name\n   ;\n\nam_type\n   : INDEX\n   | TABLE\n   ;\n\ncreatetrigstmt\n   : CREATE TRIGGER name triggeractiontime triggerevents ON qualified_name triggerreferencing triggerforspec triggerwhen EXECUTE function_or_procedure func_name OPEN_PAREN triggerfuncargs CLOSE_PAREN\n   | CREATE CONSTRAINT TRIGGER name AFTER triggerevents ON qualified_name optconstrfromtable constraintattributespec FOR EACH ROW triggerwhen EXECUTE function_or_procedure func_name OPEN_PAREN triggerfuncargs CLOSE_PAREN\n   ;\n\ntriggeractiontime\n   : BEFORE\n   | AFTER\n   | INSTEAD OF\n   ;\n\ntriggerevents\n   : triggeroneevent (OR triggeroneevent)*\n   ;\n\ntriggeroneevent\n   : INSERT\n   | DELETE_P\n   | UPDATE\n   | UPDATE OF columnlist\n   | TRUNCATE\n   ;\n\ntriggerreferencing\n   : REFERENCING triggertransitions\n   |\n   ;\n\ntriggertransitions\n   : triggertransition+\n   ;\n\ntriggertransition\n   : transitionoldornew transitionrowortable opt_as transitionrelname\n   ;\n\ntransitionoldornew\n   : NEW\n   | OLD\n   ;\n\ntransitionrowortable\n   : TABLE\n   | ROW\n   ;\n\ntransitionrelname\n   : colid\n   ;\n\ntriggerforspec\n   : FOR triggerforopteach triggerfortype\n   |\n   ;\n\ntriggerforopteach\n   : EACH\n   |\n   ;\n\ntriggerfortype\n   : ROW\n   | STATEMENT\n   ;\n\ntriggerwhen\n   : WHEN OPEN_PAREN a_expr CLOSE_PAREN\n   |\n   ;\n\nfunction_or_procedure\n   : FUNCTION\n   | PROCEDURE\n   ;\n\ntriggerfuncargs\n   : (triggerfuncarg |) (COMMA triggerfuncarg)*\n   ;\n\ntriggerfuncarg\n   : iconst\n   | fconst\n   | sconst\n   | collabel\n   ;\n\noptconstrfromtable\n   : FROM qualified_name\n   |\n   ;\n\nconstraintattributespec\n   : constraintattributeElem*\n   ;\n\nconstraintattributeElem\n   : NOT DEFERRABLE\n   | DEFERRABLE\n   | INITIALLY IMMEDIATE\n   | INITIALLY DEFERRED\n   | NOT VALID\n   | NO INHERIT\n   ;\n\ncreateeventtrigstmt\n   : CREATE EVENT TRIGGER name ON collabel EXECUTE function_or_procedure func_name OPEN_PAREN CLOSE_PAREN\n   | CREATE EVENT TRIGGER name ON collabel WHEN event_trigger_when_list EXECUTE function_or_procedure func_name OPEN_PAREN CLOSE_PAREN\n   ;\n\nevent_trigger_when_list\n   : event_trigger_when_item (AND event_trigger_when_item)*\n   ;\n\nevent_trigger_when_item\n   : colid IN_P OPEN_PAREN event_trigger_value_list CLOSE_PAREN\n   ;\n\nevent_trigger_value_list\n   : sconst (COMMA sconst)*\n   ;\n\naltereventtrigstmt\n   : ALTER EVENT TRIGGER name enable_trigger\n   ;\n\nenable_trigger\n   : ENABLE_P\n   | ENABLE_P REPLICA\n   | ENABLE_P ALWAYS\n   | DISABLE_P\n   ;\n\ncreateassertionstmt\n   : CREATE ASSERTION any_name CHECK OPEN_PAREN a_expr CLOSE_PAREN constraintattributespec\n   ;\n\ndefinestmt\n   : CREATE opt_or_replace AGGREGATE func_name aggr_args definition\n   | CREATE opt_or_replace AGGREGATE func_name old_aggr_definition\n   | CREATE OPERATOR any_operator definition\n   | CREATE TYPE_P any_name definition\n   | CREATE TYPE_P any_name\n   | CREATE TYPE_P any_name AS OPEN_PAREN opttablefuncelementlist CLOSE_PAREN\n   | CREATE TYPE_P any_name AS ENUM_P OPEN_PAREN opt_enum_val_list CLOSE_PAREN\n   | CREATE TYPE_P any_name AS RANGE definition\n   | CREATE TEXT_P SEARCH PARSER any_name definition\n   | CREATE TEXT_P SEARCH DICTIONARY any_name definition\n   | CREATE TEXT_P SEARCH TEMPLATE any_name definition\n   | CREATE TEXT_P SEARCH CONFIGURATION any_name definition\n   | CREATE COLLATION any_name definition\n   | CREATE COLLATION IF_P NOT EXISTS any_name definition\n   | CREATE COLLATION any_name FROM any_name\n   | CREATE COLLATION IF_P NOT EXISTS any_name FROM any_name\n   ;\n\ndefinition\n   : OPEN_PAREN def_list CLOSE_PAREN\n   ;\n\ndef_list\n   : def_elem (COMMA def_elem)*\n   ;\n\ndef_elem\n   : collabel (EQUAL def_arg)?\n   ;\n\ndef_arg\n   : func_type\n   | reserved_keyword\n   | qual_all_op\n   | numericonly\n   | sconst\n   | NONE\n   ;\n\nold_aggr_definition\n   : OPEN_PAREN old_aggr_list CLOSE_PAREN\n   ;\n\nold_aggr_list\n   : old_aggr_elem (COMMA old_aggr_elem)*\n   ;\n\nold_aggr_elem\n   : identifier EQUAL def_arg\n   ;\n\nopt_enum_val_list\n   : enum_val_list\n   |\n   ;\n\nenum_val_list\n   : sconst (COMMA sconst)*\n   ;\n\nalterenumstmt\n   : ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists sconst\n   | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists sconst BEFORE sconst\n   | ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists sconst AFTER sconst\n   | ALTER TYPE_P any_name RENAME VALUE_P sconst TO sconst\n   ;\n\nopt_if_not_exists\n   : IF_P NOT EXISTS\n   |\n   ;\n\ncreateopclassstmt\n   : CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P typename USING name opt_opfamily AS opclass_item_list\n   ;\n\nopclass_item_list\n   : opclass_item (COMMA opclass_item)*\n   ;\n\nopclass_item\n   : OPERATOR iconst any_operator opclass_purpose opt_recheck\n   | OPERATOR iconst operator_with_argtypes opclass_purpose opt_recheck\n   | FUNCTION iconst function_with_argtypes\n   | FUNCTION iconst OPEN_PAREN type_list CLOSE_PAREN function_with_argtypes\n   | STORAGE typename\n   ;\n\nopt_default\n   : DEFAULT\n   |\n   ;\n\nopt_opfamily\n   : FAMILY any_name\n   |\n   ;\n\nopclass_purpose\n   : FOR SEARCH\n   | FOR ORDER BY any_name\n   |\n   ;\n\nopt_recheck\n   : RECHECK\n   |\n   ;\n\ncreateopfamilystmt\n   : CREATE OPERATOR FAMILY any_name USING name\n   ;\n\nalteropfamilystmt\n   : ALTER OPERATOR FAMILY any_name USING name ADD_P opclass_item_list\n   | ALTER OPERATOR FAMILY any_name USING name DROP opclass_drop_list\n   ;\n\nopclass_drop_list\n   : opclass_drop (COMMA opclass_drop)*\n   ;\n\nopclass_drop\n   : OPERATOR iconst OPEN_PAREN type_list CLOSE_PAREN\n   | FUNCTION iconst OPEN_PAREN type_list CLOSE_PAREN\n   ;\n\ndropopclassstmt\n   : DROP OPERATOR CLASS any_name USING name opt_drop_behavior\n   | DROP OPERATOR CLASS IF_P EXISTS any_name USING name opt_drop_behavior\n   ;\n\ndropopfamilystmt\n   : DROP OPERATOR FAMILY any_name USING name opt_drop_behavior\n   | DROP OPERATOR FAMILY IF_P EXISTS any_name USING name opt_drop_behavior\n   ;\n\ndropownedstmt\n   : DROP OWNED BY role_list opt_drop_behavior\n   ;\n\nreassignownedstmt\n   : REASSIGN OWNED BY role_list TO rolespec\n   ;\n\ndropstmt\n   : DROP object_type_any_name IF_P EXISTS any_name_list opt_drop_behavior\n   | DROP object_type_any_name any_name_list opt_drop_behavior\n   | DROP drop_type_name IF_P EXISTS name_list opt_drop_behavior\n   | DROP drop_type_name name_list opt_drop_behavior\n   | DROP object_type_name_on_any_name name ON any_name opt_drop_behavior\n   | DROP object_type_name_on_any_name IF_P EXISTS name ON any_name opt_drop_behavior\n   | DROP TYPE_P type_name_list opt_drop_behavior\n   | DROP TYPE_P IF_P EXISTS type_name_list opt_drop_behavior\n   | DROP DOMAIN_P type_name_list opt_drop_behavior\n   | DROP DOMAIN_P IF_P EXISTS type_name_list opt_drop_behavior\n   | DROP INDEX CONCURRENTLY any_name_list opt_drop_behavior\n   | DROP INDEX CONCURRENTLY IF_P EXISTS any_name_list opt_drop_behavior\n   ;\n\nobject_type_any_name\n   : TABLE\n   | SEQUENCE\n   | VIEW\n   | MATERIALIZED VIEW\n   | INDEX\n   | FOREIGN TABLE\n   | COLLATION\n   | CONVERSION_P\n   | STATISTICS\n   | TEXT_P SEARCH PARSER\n   | TEXT_P SEARCH DICTIONARY\n   | TEXT_P SEARCH TEMPLATE\n   | TEXT_P SEARCH CONFIGURATION\n   ;\n\nobject_type_name\n   : drop_type_name\n   | DATABASE\n   | ROLE\n   | SUBSCRIPTION\n   | TABLESPACE\n   ;\n\ndrop_type_name\n   : ACCESS METHOD\n   | EVENT TRIGGER\n   | EXTENSION\n   | FOREIGN DATA_P WRAPPER\n   | opt_procedural LANGUAGE\n   | PUBLICATION\n   | SCHEMA\n   | SERVER\n   ;\n\nobject_type_name_on_any_name\n   : POLICY\n   | RULE\n   | TRIGGER\n   ;\n\nany_name_list\n   : any_name (COMMA any_name)*\n   ;\n\nany_name\n   : colid attrs?\n   ;\n\nattrs\n   :(DOT attr_name)+\n   ;\n\ntype_name_list\n   : typename (COMMA typename)*\n   ;\n\ntruncatestmt\n   : TRUNCATE opt_table relation_expr_list opt_restart_seqs opt_drop_behavior\n   ;\n\nopt_restart_seqs\n   : CONTINUE_P IDENTITY_P\n   | RESTART IDENTITY_P\n   |\n   ;\n\ncommentstmt\n   : COMMENT ON object_type_any_name any_name IS comment_text\n   | COMMENT ON COLUMN any_name IS comment_text\n   | COMMENT ON object_type_name name IS comment_text\n   | COMMENT ON TYPE_P typename IS comment_text\n   | COMMENT ON DOMAIN_P typename IS comment_text\n   | COMMENT ON AGGREGATE aggregate_with_argtypes IS comment_text\n   | COMMENT ON FUNCTION function_with_argtypes IS comment_text\n   | COMMENT ON OPERATOR operator_with_argtypes IS comment_text\n   | COMMENT ON CONSTRAINT name ON any_name IS comment_text\n   | COMMENT ON CONSTRAINT name ON DOMAIN_P any_name IS comment_text\n   | COMMENT ON object_type_name_on_any_name name ON any_name IS comment_text\n   | COMMENT ON PROCEDURE function_with_argtypes IS comment_text\n   | COMMENT ON ROUTINE function_with_argtypes IS comment_text\n   | COMMENT ON TRANSFORM FOR typename LANGUAGE name IS comment_text\n   | COMMENT ON OPERATOR CLASS any_name USING name IS comment_text\n   | COMMENT ON OPERATOR FAMILY any_name USING name IS comment_text\n   | COMMENT ON LARGE_P OBJECT_P numericonly IS comment_text\n   | COMMENT ON CAST OPEN_PAREN typename AS typename CLOSE_PAREN IS comment_text\n   ;\n\ncomment_text\n   : sconst\n   | NULL_P\n   ;\n\nseclabelstmt\n   : SECURITY LABEL opt_provider ON object_type_any_name any_name IS security_label\n   | SECURITY LABEL opt_provider ON COLUMN any_name IS security_label\n   | SECURITY LABEL opt_provider ON object_type_name name IS security_label\n   | SECURITY LABEL opt_provider ON TYPE_P typename IS security_label\n   | SECURITY LABEL opt_provider ON DOMAIN_P typename IS security_label\n   | SECURITY LABEL opt_provider ON AGGREGATE aggregate_with_argtypes IS security_label\n   | SECURITY LABEL opt_provider ON FUNCTION function_with_argtypes IS security_label\n   | SECURITY LABEL opt_provider ON LARGE_P OBJECT_P numericonly IS security_label\n   | SECURITY LABEL opt_provider ON PROCEDURE function_with_argtypes IS security_label\n   | SECURITY LABEL opt_provider ON ROUTINE function_with_argtypes IS security_label\n   ;\n\nopt_provider\n   : FOR nonreservedword_or_sconst\n   |\n   ;\n\nsecurity_label\n   : sconst\n   | NULL_P\n   ;\n\nfetchstmt\n   : FETCH fetch_args\n   | MOVE fetch_args\n   ;\n\nfetch_args\n   : cursor_name\n   | from_in cursor_name\n   | NEXT opt_from_in cursor_name\n   | PRIOR opt_from_in cursor_name\n   | FIRST_P opt_from_in cursor_name\n   | LAST_P opt_from_in cursor_name\n   | ABSOLUTE_P signediconst opt_from_in cursor_name\n   | RELATIVE_P signediconst opt_from_in cursor_name\n   | signediconst opt_from_in cursor_name\n   | ALL opt_from_in cursor_name\n   | FORWARD opt_from_in cursor_name\n   | FORWARD signediconst opt_from_in cursor_name\n   | FORWARD ALL opt_from_in cursor_name\n   | BACKWARD opt_from_in cursor_name\n   | BACKWARD signediconst opt_from_in cursor_name\n   | BACKWARD ALL opt_from_in cursor_name\n   ;\n\nfrom_in\n   : FROM\n   | IN_P\n   ;\n\nopt_from_in\n   : from_in\n   |\n   ;\n\ngrantstmt\n   : GRANT privileges ON privilege_target TO grantee_list opt_grant_grant_option\n   ;\n\nrevokestmt\n   : REVOKE privileges ON privilege_target FROM grantee_list opt_drop_behavior\n   | REVOKE GRANT OPTION FOR privileges ON privilege_target FROM grantee_list opt_drop_behavior\n   ;\n\nprivileges\n   : privilege_list\n   | ALL\n   | ALL PRIVILEGES\n   | ALL OPEN_PAREN columnlist CLOSE_PAREN\n   | ALL PRIVILEGES OPEN_PAREN columnlist CLOSE_PAREN\n   ;\n\nprivilege_list\n   : privilege (COMMA privilege)*\n   ;\n\nprivilege\n   : SELECT opt_column_list\n   | REFERENCES opt_column_list\n   | CREATE opt_column_list\n   | colid opt_column_list\n   ;\n\nprivilege_target\n   : qualified_name_list\n   | TABLE qualified_name_list\n   | SEQUENCE qualified_name_list\n   | FOREIGN DATA_P WRAPPER name_list\n   | FOREIGN SERVER name_list\n   | FUNCTION function_with_argtypes_list\n   | PROCEDURE function_with_argtypes_list\n   | ROUTINE function_with_argtypes_list\n   | DATABASE name_list\n   | DOMAIN_P any_name_list\n   | LANGUAGE name_list\n   | LARGE_P OBJECT_P numericonly_list\n   | SCHEMA name_list\n   | TABLESPACE name_list\n   | TYPE_P any_name_list\n   | ALL TABLES IN_P SCHEMA name_list\n   | ALL SEQUENCES IN_P SCHEMA name_list\n   | ALL FUNCTIONS IN_P SCHEMA name_list\n   | ALL PROCEDURES IN_P SCHEMA name_list\n   | ALL ROUTINES IN_P SCHEMA name_list\n   ;\n\ngrantee_list\n   : grantee (COMMA grantee)*\n   ;\n\ngrantee\n   : rolespec\n   | GROUP_P rolespec\n   ;\n\nopt_grant_grant_option\n   : WITH GRANT OPTION\n   |\n   ;\n\ngrantrolestmt\n   : GRANT privilege_list TO role_list opt_grant_admin_option opt_granted_by\n   ;\n\nrevokerolestmt\n   : REVOKE privilege_list FROM role_list opt_granted_by opt_drop_behavior\n   | REVOKE ADMIN OPTION FOR privilege_list FROM role_list opt_granted_by opt_drop_behavior\n   ;\n\nopt_grant_admin_option\n   : WITH ADMIN OPTION\n   |\n   ;\n\nopt_granted_by\n   : GRANTED BY rolespec\n   |\n   ;\n\nalterdefaultprivilegesstmt\n   : ALTER DEFAULT PRIVILEGES defacloptionlist defaclaction\n   ;\n\ndefacloptionlist\n   : defacloption*\n   ;\n\ndefacloption\n   : IN_P SCHEMA name_list\n   | FOR ROLE role_list\n   | FOR USER role_list\n   ;\n\ndefaclaction\n   : GRANT privileges ON defacl_privilege_target TO grantee_list opt_grant_grant_option\n   | REVOKE privileges ON defacl_privilege_target FROM grantee_list opt_drop_behavior\n   | REVOKE GRANT OPTION FOR privileges ON defacl_privilege_target FROM grantee_list opt_drop_behavior\n   ;\n\ndefacl_privilege_target\n   : TABLES\n   | FUNCTIONS\n   | ROUTINES\n   | SEQUENCES\n   | TYPES_P\n   | SCHEMAS\n   ;\n   //create index\n\nindexstmt\n   : CREATE opt_unique INDEX opt_concurrently opt_index_name ON relation_expr access_method_clause OPEN_PAREN index_params CLOSE_PAREN opt_include opt_reloptions opttablespace where_clause\n   | CREATE opt_unique INDEX opt_concurrently IF_P NOT EXISTS name ON relation_expr access_method_clause OPEN_PAREN index_params CLOSE_PAREN opt_include opt_reloptions opttablespace where_clause\n   ;\n\nopt_unique\n   : UNIQUE\n   |\n   ;\n\nopt_concurrently\n   : CONCURRENTLY\n   |\n   ;\n\nopt_index_name\n   : name\n   |\n   ;\n\naccess_method_clause\n   : USING name\n   |\n   ;\n\nindex_params\n   : index_elem (COMMA index_elem)*\n   ;\n\nindex_elem_options\n   : opt_collate opt_class opt_asc_desc opt_nulls_order\n   | opt_collate any_name reloptions opt_asc_desc opt_nulls_order\n   ;\n\nindex_elem\n   : colid index_elem_options\n   | func_expr_windowless index_elem_options\n   | OPEN_PAREN a_expr CLOSE_PAREN index_elem_options\n   ;\n\nopt_include\n   : INCLUDE OPEN_PAREN index_including_params CLOSE_PAREN\n   |\n   ;\n\nindex_including_params\n   : index_elem (COMMA index_elem)*\n   ;\n\nopt_collate\n   : COLLATE any_name\n   |\n   ;\n\nopt_class\n   : any_name\n   |\n   ;\n\nopt_asc_desc\n   : ASC\n   | DESC\n   |\n   ;\n   //TOD NULLS_LA was used\n\nopt_nulls_order\n   : NULLS_P FIRST_P\n   | NULLS_P LAST_P\n   |\n   ;\n\ncreatefunctionstmt\n   : CREATE opt_or_replace (FUNCTION | PROCEDURE) func_name func_args_with_defaults\n     (\n        RETURNS (func_return | TABLE OPEN_PAREN table_func_column_list CLOSE_PAREN)\n     )?\n     createfunc_opt_list\n   ;\n\nopt_or_replace\n   : OR REPLACE\n   |\n   ;\n\nfunc_args\n   : OPEN_PAREN func_args_list? CLOSE_PAREN\n   ;\n\nfunc_args_list\n   : func_arg (COMMA func_arg)*\n   ;\n\nfunction_with_argtypes_list\n   : function_with_argtypes (COMMA function_with_argtypes)*\n   ;\n\nfunction_with_argtypes\n   : func_name func_args\n   | type_func_name_keyword\n   | colid indirection?\n   ;\n\nfunc_args_with_defaults\n   : OPEN_PAREN func_args_with_defaults_list? CLOSE_PAREN\n   ;\n\nfunc_args_with_defaults_list\n   : func_arg_with_default (COMMA func_arg_with_default)*\n   ;\n\nfunc_arg\n   : arg_class param_name? func_type\n   | param_name arg_class? func_type\n   | func_type\n   ;\n\narg_class\n   : IN_P OUT_P?\n   | OUT_P\n   | INOUT\n   | VARIADIC\n   ;\n\nparam_name\n   : type_function_name\n   | builtin_function_name\n   | LEFT\n   | RIGHT\n   ;\n\nfunc_return\n   : func_type\n   ;\n\nfunc_type\n   : typename\n   | SETOF? (builtin_function_name | type_function_name | LEFT | RIGHT) attrs PERCENT TYPE_P\n   ;\n\nfunc_arg_with_default\n   : func_arg ((DEFAULT | EQUAL) a_expr)?\n   ;\n\naggr_arg\n   : func_arg\n   ;\n\naggr_args\n   : OPEN_PAREN (STAR | aggr_args_list | ORDER BY aggr_args_list | aggr_args_list ORDER BY aggr_args_list) CLOSE_PAREN\n   ;\n\naggr_args_list\n   : aggr_arg (COMMA aggr_arg)*\n   ;\n\naggregate_with_argtypes\n   : func_name aggr_args\n   ;\n\naggregate_with_argtypes_list\n   : aggregate_with_argtypes (COMMA aggregate_with_argtypes)*\n   ;\n\ncreatefunc_opt_list\n   : createfunc_opt_item+\n   {\n                ParseRoutineBody(_localctx);\n            }\n   //                    | createfunc_opt_list createfunc_opt_item\n\n   ;\n\ncommon_func_opt_item\n   : CALLED ON NULL_P INPUT_P\n   | RETURNS NULL_P ON NULL_P INPUT_P\n   | STRICT_P\n   | IMMUTABLE\n   | STABLE\n   | VOLATILE\n   | EXTERNAL SECURITY DEFINER\n   | EXTERNAL SECURITY INVOKER\n   | SECURITY DEFINER\n   | SECURITY INVOKER\n   | LEAKPROOF\n   | NOT LEAKPROOF\n   | COST numericonly\n   | ROWS numericonly\n   | SUPPORT any_name\n   | functionsetresetclause\n   | PARALLEL colid\n   ;\n\ncreatefunc_opt_item\n   : AS func_as\n   | LANGUAGE nonreservedword_or_sconst\n   | TRANSFORM transform_type_list\n   | WINDOW\n   | common_func_opt_item\n   ;\n   //https://www.postgresql.org/docs/9.1/sql-createfunction.html\n\n   //    | AS 'definition'\n\n   //    | AS 'obj_file', 'link_symbol'\n\nfunc_as locals[ParserRuleContext Definition]\n   :\n   /* |AS 'definition'*/\n   def = sconst\n   /*| AS 'obj_file', 'link_symbol'*/\n   | sconst COMMA sconst\n   ;\n\ntransform_type_list\n   :FOR TYPE_P typename (COMMA FOR TYPE_P typename)*\n   ;\n\nopt_definition\n   : WITH definition\n   |\n   ;\n\ntable_func_column\n   : param_name func_type\n   ;\n\ntable_func_column_list\n   : table_func_column (COMMA table_func_column)*\n   ;\n\nalterfunctionstmt\n   : ALTER (FUNCTION | PROCEDURE | ROUTINE) function_with_argtypes alterfunc_opt_list opt_restrict\n   ;\n\nalterfunc_opt_list\n   : common_func_opt_item+\n   ;\n\nopt_restrict\n   : RESTRICT\n   |\n   ;\n\nremovefuncstmt\n   : DROP FUNCTION function_with_argtypes_list opt_drop_behavior\n   | DROP FUNCTION IF_P EXISTS function_with_argtypes_list opt_drop_behavior\n   | DROP PROCEDURE function_with_argtypes_list opt_drop_behavior\n   | DROP PROCEDURE IF_P EXISTS function_with_argtypes_list opt_drop_behavior\n   | DROP ROUTINE function_with_argtypes_list opt_drop_behavior\n   | DROP ROUTINE IF_P EXISTS function_with_argtypes_list opt_drop_behavior\n   ;\n\nremoveaggrstmt\n   : DROP AGGREGATE aggregate_with_argtypes_list opt_drop_behavior\n   | DROP AGGREGATE IF_P EXISTS aggregate_with_argtypes_list opt_drop_behavior\n   ;\n\nremoveoperstmt\n   : DROP OPERATOR operator_with_argtypes_list opt_drop_behavior\n   | DROP OPERATOR IF_P EXISTS operator_with_argtypes_list opt_drop_behavior\n   ;\n\noper_argtypes\n   : OPEN_PAREN typename CLOSE_PAREN\n   | OPEN_PAREN typename COMMA typename CLOSE_PAREN\n   | OPEN_PAREN NONE COMMA typename CLOSE_PAREN\n   | OPEN_PAREN typename COMMA NONE CLOSE_PAREN\n   ;\n\nany_operator\n   : (colid DOT)* all_op\n   ;\n\noperator_with_argtypes_list\n   : operator_with_argtypes (COMMA operator_with_argtypes)*\n   ;\n\noperator_with_argtypes\n   : any_operator oper_argtypes\n   ;\n\ndostmt\n   : DO dostmt_opt_list\n   ;\n\ndostmt_opt_list\n   : dostmt_opt_item+\n   ;\n\ndostmt_opt_item\n   : sconst\n   | LANGUAGE nonreservedword_or_sconst\n   ;\n\ncreatecaststmt\n   : CREATE CAST OPEN_PAREN typename AS typename CLOSE_PAREN WITH FUNCTION function_with_argtypes cast_context\n   | CREATE CAST OPEN_PAREN typename AS typename CLOSE_PAREN WITHOUT FUNCTION cast_context\n   | CREATE CAST OPEN_PAREN typename AS typename CLOSE_PAREN WITH INOUT cast_context\n   ;\n\ncast_context\n   : AS IMPLICIT_P\n   | AS ASSIGNMENT\n   |\n   ;\n\ndropcaststmt\n   : DROP CAST opt_if_exists OPEN_PAREN typename AS typename CLOSE_PAREN opt_drop_behavior\n   ;\n\nopt_if_exists\n   : IF_P EXISTS\n   |\n   ;\n\ncreatetransformstmt\n   : CREATE opt_or_replace TRANSFORM FOR typename LANGUAGE name OPEN_PAREN transform_element_list CLOSE_PAREN\n   ;\n\ntransform_element_list\n   : FROM SQL_P WITH FUNCTION function_with_argtypes COMMA TO SQL_P WITH FUNCTION function_with_argtypes\n   | TO SQL_P WITH FUNCTION function_with_argtypes COMMA FROM SQL_P WITH FUNCTION function_with_argtypes\n   | FROM SQL_P WITH FUNCTION function_with_argtypes\n   | TO SQL_P WITH FUNCTION function_with_argtypes\n   ;\n\ndroptransformstmt\n   : DROP TRANSFORM opt_if_exists FOR typename LANGUAGE name opt_drop_behavior\n   ;\n\nreindexstmt\n   : REINDEX reindex_target_type opt_concurrently qualified_name\n   | REINDEX reindex_target_multitable opt_concurrently name\n   | REINDEX OPEN_PAREN reindex_option_list CLOSE_PAREN reindex_target_type opt_concurrently qualified_name\n   | REINDEX OPEN_PAREN reindex_option_list CLOSE_PAREN reindex_target_multitable opt_concurrently name\n   ;\n\nreindex_target_type\n   : INDEX\n   | TABLE\n   | SCHEMA\n   | DATABASE\n   | SYSTEM_P\n   ;\n\nreindex_target_multitable\n   : SCHEMA\n   | SYSTEM_P\n   | DATABASE\n   ;\n\nreindex_option_list\n   : reindex_option_elem (COMMA reindex_option_elem)*\n   ;\n\nreindex_option_elem\n   : VERBOSE\n   | TABLESPACE\n   | CONCURRENTLY\n   ;\n\naltertblspcstmt\n   : ALTER TABLESPACE name SET reloptions\n   | ALTER TABLESPACE name RESET reloptions\n   ;\n\nrenamestmt\n   : ALTER AGGREGATE aggregate_with_argtypes RENAME TO name\n   | ALTER COLLATION any_name RENAME TO name\n   | ALTER CONVERSION_P any_name RENAME TO name\n   | ALTER DATABASE name RENAME TO name\n   | ALTER DOMAIN_P any_name RENAME TO name\n   | ALTER DOMAIN_P any_name RENAME CONSTRAINT name TO name\n   | ALTER FOREIGN DATA_P WRAPPER name RENAME TO name\n   | ALTER FUNCTION function_with_argtypes RENAME TO name\n   | ALTER GROUP_P roleid RENAME TO roleid\n   | ALTER opt_procedural LANGUAGE name RENAME TO name\n   | ALTER OPERATOR CLASS any_name USING name RENAME TO name\n   | ALTER OPERATOR FAMILY any_name USING name RENAME TO name\n   | ALTER POLICY name ON qualified_name RENAME TO name\n   | ALTER POLICY IF_P EXISTS name ON qualified_name RENAME TO name\n   | ALTER PROCEDURE function_with_argtypes RENAME TO name\n   | ALTER PUBLICATION name RENAME TO name\n   | ALTER ROUTINE function_with_argtypes RENAME TO name\n   | ALTER SCHEMA name RENAME TO name\n   | ALTER SERVER name RENAME TO name\n   | ALTER SUBSCRIPTION name RENAME TO name\n   | ALTER TABLE relation_expr RENAME TO name\n   | ALTER TABLE IF_P EXISTS relation_expr RENAME TO name\n   | ALTER SEQUENCE qualified_name RENAME TO name\n   | ALTER SEQUENCE IF_P EXISTS qualified_name RENAME TO name\n   | ALTER VIEW qualified_name RENAME TO name\n   | ALTER VIEW IF_P EXISTS qualified_name RENAME TO name\n   | ALTER MATERIALIZED VIEW qualified_name RENAME TO name\n   | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name RENAME TO name\n   | ALTER INDEX qualified_name RENAME TO name\n   | ALTER INDEX IF_P EXISTS qualified_name RENAME TO name\n   | ALTER FOREIGN TABLE relation_expr RENAME TO name\n   | ALTER FOREIGN TABLE IF_P EXISTS relation_expr RENAME TO name\n   | ALTER TABLE relation_expr RENAME opt_column name TO name\n   | ALTER TABLE IF_P EXISTS relation_expr RENAME opt_column name TO name\n   | ALTER VIEW qualified_name RENAME opt_column name TO name\n   | ALTER VIEW IF_P EXISTS qualified_name RENAME opt_column name TO name\n   | ALTER MATERIALIZED VIEW qualified_name RENAME opt_column name TO name\n   | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name RENAME opt_column name TO name\n   | ALTER TABLE relation_expr RENAME CONSTRAINT name TO name\n   | ALTER TABLE IF_P EXISTS relation_expr RENAME CONSTRAINT name TO name\n   | ALTER FOREIGN TABLE relation_expr RENAME opt_column name TO name\n   | ALTER FOREIGN TABLE IF_P EXISTS relation_expr RENAME opt_column name TO name\n   | ALTER RULE name ON qualified_name RENAME TO name\n   | ALTER TRIGGER name ON qualified_name RENAME TO name\n   | ALTER EVENT TRIGGER name RENAME TO name\n   | ALTER ROLE roleid RENAME TO roleid\n   | ALTER USER roleid RENAME TO roleid\n   | ALTER TABLESPACE name RENAME TO name\n   | ALTER STATISTICS any_name RENAME TO name\n   | ALTER TEXT_P SEARCH PARSER any_name RENAME TO name\n   | ALTER TEXT_P SEARCH DICTIONARY any_name RENAME TO name\n   | ALTER TEXT_P SEARCH TEMPLATE any_name RENAME TO name\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name RENAME TO name\n   | ALTER TYPE_P any_name RENAME TO name\n   | ALTER TYPE_P any_name RENAME ATTRIBUTE name TO name opt_drop_behavior\n   ;\n\nopt_column\n   : COLUMN\n   |\n   ;\n\nopt_set_data\n   : SET DATA_P\n   |\n   ;\n\nalterobjectdependsstmt\n   : ALTER FUNCTION function_with_argtypes opt_no DEPENDS ON EXTENSION name\n   | ALTER PROCEDURE function_with_argtypes opt_no DEPENDS ON EXTENSION name\n   | ALTER ROUTINE function_with_argtypes opt_no DEPENDS ON EXTENSION name\n   | ALTER TRIGGER name ON qualified_name opt_no DEPENDS ON EXTENSION name\n   | ALTER MATERIALIZED VIEW qualified_name opt_no DEPENDS ON EXTENSION name\n   | ALTER INDEX qualified_name opt_no DEPENDS ON EXTENSION name\n   ;\n\nopt_no\n   : NO\n   |\n   ;\n\nalterobjectschemastmt\n   : ALTER AGGREGATE aggregate_with_argtypes SET SCHEMA name\n   | ALTER COLLATION any_name SET SCHEMA name\n   | ALTER CONVERSION_P any_name SET SCHEMA name\n   | ALTER DOMAIN_P any_name SET SCHEMA name\n   | ALTER EXTENSION name SET SCHEMA name\n   | ALTER FUNCTION function_with_argtypes SET SCHEMA name\n   | ALTER OPERATOR operator_with_argtypes SET SCHEMA name\n   | ALTER OPERATOR CLASS any_name USING name SET SCHEMA name\n   | ALTER OPERATOR FAMILY any_name USING name SET SCHEMA name\n   | ALTER PROCEDURE function_with_argtypes SET SCHEMA name\n   | ALTER ROUTINE function_with_argtypes SET SCHEMA name\n   | ALTER TABLE relation_expr SET SCHEMA name\n   | ALTER TABLE IF_P EXISTS relation_expr SET SCHEMA name\n   | ALTER STATISTICS any_name SET SCHEMA name\n   | ALTER TEXT_P SEARCH PARSER any_name SET SCHEMA name\n   | ALTER TEXT_P SEARCH DICTIONARY any_name SET SCHEMA name\n   | ALTER TEXT_P SEARCH TEMPLATE any_name SET SCHEMA name\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name SET SCHEMA name\n   | ALTER SEQUENCE qualified_name SET SCHEMA name\n   | ALTER SEQUENCE IF_P EXISTS qualified_name SET SCHEMA name\n   | ALTER VIEW qualified_name SET SCHEMA name\n   | ALTER VIEW IF_P EXISTS qualified_name SET SCHEMA name\n   | ALTER MATERIALIZED VIEW qualified_name SET SCHEMA name\n   | ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name SET SCHEMA name\n   | ALTER FOREIGN TABLE relation_expr SET SCHEMA name\n   | ALTER FOREIGN TABLE IF_P EXISTS relation_expr SET SCHEMA name\n   | ALTER TYPE_P any_name SET SCHEMA name\n   ;\n\nalteroperatorstmt\n   : ALTER OPERATOR operator_with_argtypes SET OPEN_PAREN operator_def_list CLOSE_PAREN\n   ;\n\noperator_def_list\n   : operator_def_elem (COMMA operator_def_elem)*\n   ;\n\noperator_def_elem\n   : collabel EQUAL NONE\n   | collabel EQUAL operator_def_arg\n   ;\n\noperator_def_arg\n   : func_type\n   | reserved_keyword\n   | qual_all_op\n   | numericonly\n   | sconst\n   ;\n\naltertypestmt\n   : ALTER TYPE_P any_name SET OPEN_PAREN operator_def_list CLOSE_PAREN\n   ;\n\nalterownerstmt\n   : ALTER AGGREGATE aggregate_with_argtypes OWNER TO rolespec\n   | ALTER COLLATION any_name OWNER TO rolespec\n   | ALTER CONVERSION_P any_name OWNER TO rolespec\n   | ALTER DATABASE name OWNER TO rolespec\n   | ALTER DOMAIN_P any_name OWNER TO rolespec\n   | ALTER FUNCTION function_with_argtypes OWNER TO rolespec\n   | ALTER opt_procedural LANGUAGE name OWNER TO rolespec\n   | ALTER LARGE_P OBJECT_P numericonly OWNER TO rolespec\n   | ALTER OPERATOR operator_with_argtypes OWNER TO rolespec\n   | ALTER OPERATOR CLASS any_name USING name OWNER TO rolespec\n   | ALTER OPERATOR FAMILY any_name USING name OWNER TO rolespec\n   | ALTER PROCEDURE function_with_argtypes OWNER TO rolespec\n   | ALTER ROUTINE function_with_argtypes OWNER TO rolespec\n   | ALTER SCHEMA name OWNER TO rolespec\n   | ALTER TYPE_P any_name OWNER TO rolespec\n   | ALTER TABLESPACE name OWNER TO rolespec\n   | ALTER STATISTICS any_name OWNER TO rolespec\n   | ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO rolespec\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO rolespec\n   | ALTER FOREIGN DATA_P WRAPPER name OWNER TO rolespec\n   | ALTER SERVER name OWNER TO rolespec\n   | ALTER EVENT TRIGGER name OWNER TO rolespec\n   | ALTER PUBLICATION name OWNER TO rolespec\n   | ALTER SUBSCRIPTION name OWNER TO rolespec\n   ;\n\ncreatepublicationstmt\n   : CREATE PUBLICATION name opt_publication_for_tables opt_definition\n   ;\n\nopt_publication_for_tables\n   : publication_for_tables\n   |\n   ;\n\npublication_for_tables\n   : FOR TABLE relation_expr_list\n   | FOR ALL TABLES\n   ;\n\nalterpublicationstmt\n   : ALTER PUBLICATION name SET definition\n   | ALTER PUBLICATION name ADD_P TABLE relation_expr_list\n   | ALTER PUBLICATION name SET TABLE relation_expr_list\n   | ALTER PUBLICATION name DROP TABLE relation_expr_list\n   ;\n\ncreatesubscriptionstmt\n   : CREATE SUBSCRIPTION name CONNECTION sconst PUBLICATION publication_name_list opt_definition\n   ;\n\npublication_name_list\n   : publication_name_item (COMMA publication_name_item)*\n   ;\n\npublication_name_item\n   : collabel\n   ;\n\naltersubscriptionstmt\n   : ALTER SUBSCRIPTION name SET definition\n   | ALTER SUBSCRIPTION name CONNECTION sconst\n   | ALTER SUBSCRIPTION name REFRESH PUBLICATION opt_definition\n   | ALTER SUBSCRIPTION name SET PUBLICATION publication_name_list opt_definition\n   | ALTER SUBSCRIPTION name ENABLE_P\n   | ALTER SUBSCRIPTION name DISABLE_P\n   ;\n\ndropsubscriptionstmt\n   : DROP SUBSCRIPTION name opt_drop_behavior\n   | DROP SUBSCRIPTION IF_P EXISTS name opt_drop_behavior\n   ;\n\nrulestmt\n   : CREATE opt_or_replace RULE name AS ON event TO qualified_name where_clause DO opt_instead ruleactionlist\n   ;\n\nruleactionlist\n   : NOTHING\n   | ruleactionstmt\n   | OPEN_PAREN ruleactionmulti CLOSE_PAREN\n   ;\n\nruleactionmulti\n   : ruleactionstmtOrEmpty (SEMI ruleactionstmtOrEmpty)*\n   ;\n\nruleactionstmt\n   : selectstmt\n   | insertstmt\n   | updatestmt\n   | deletestmt\n   | notifystmt\n   ;\n\nruleactionstmtOrEmpty\n   : ruleactionstmt\n   |\n   ;\n\nevent\n   : SELECT\n   | UPDATE\n   | DELETE_P\n   | INSERT\n   ;\n\nopt_instead\n   : INSTEAD\n   | ALSO\n   |\n   ;\n\nnotifystmt\n   : NOTIFY colid notify_payload\n   ;\n\nnotify_payload\n   : COMMA sconst\n   |\n   ;\n\nlistenstmt\n   : LISTEN colid\n   ;\n\nunlistenstmt\n   : UNLISTEN colid\n   | UNLISTEN STAR\n   ;\n\ntransactionstmt\n   : ABORT_P opt_transaction opt_transaction_chain\n   | BEGIN_P opt_transaction transaction_mode_list_or_empty\n   | START TRANSACTION transaction_mode_list_or_empty\n   | COMMIT opt_transaction opt_transaction_chain\n   | END_P opt_transaction opt_transaction_chain\n   | ROLLBACK opt_transaction opt_transaction_chain\n   | SAVEPOINT colid\n   | RELEASE SAVEPOINT colid\n   | RELEASE colid\n   | ROLLBACK opt_transaction TO SAVEPOINT colid\n   | ROLLBACK opt_transaction TO colid\n   | PREPARE TRANSACTION sconst\n   | COMMIT PREPARED sconst\n   | ROLLBACK PREPARED sconst\n   ;\n\nopt_transaction\n   : WORK\n   | TRANSACTION\n   |\n   ;\n\ntransaction_mode_item\n   : ISOLATION LEVEL iso_level\n   | READ ONLY\n   | READ WRITE\n   | DEFERRABLE\n   | NOT DEFERRABLE\n   ;\n\ntransaction_mode_list\n   : transaction_mode_item (COMMA? transaction_mode_item)*\n   ;\n\ntransaction_mode_list_or_empty\n   : transaction_mode_list\n   |\n   ;\n\nopt_transaction_chain\n   : AND NO? CHAIN\n   |\n   ;\n\nviewstmt\n   : CREATE (OR REPLACE)? opttemp\n    (\n          VIEW qualified_name opt_column_list opt_reloptions\n        | RECURSIVE VIEW qualified_name OPEN_PAREN columnlist CLOSE_PAREN opt_reloptions\n    )\n     AS selectstmt opt_check_option\n   ;\n\nopt_check_option\n   : WITH (CASCADED | LOCAL)? CHECK OPTION\n   |\n   ;\n\nloadstmt\n   : LOAD file_name\n   ;\n\ncreatedbstmt\n   : CREATE DATABASE name opt_with createdb_opt_list\n   ;\n\ncreatedb_opt_list\n   : createdb_opt_items\n   |\n   ;\n\ncreatedb_opt_items\n   : createdb_opt_item+\n   ;\n\ncreatedb_opt_item\n   : createdb_opt_name opt_equal (signediconst | opt_boolean_or_string | DEFAULT)\n   ;\n\ncreatedb_opt_name\n   : identifier\n   | CONNECTION LIMIT\n   | ENCODING\n   | LOCATION\n   | OWNER\n   | TABLESPACE\n   | TEMPLATE\n   ;\n\nopt_equal\n   : EQUAL\n   |\n   ;\n\nalterdatabasestmt\n   : ALTER DATABASE name (WITH createdb_opt_list | createdb_opt_list | SET TABLESPACE name)\n   ;\n\nalterdatabasesetstmt\n   : ALTER DATABASE name setresetclause\n   ;\n\ndropdbstmt\n   : DROP DATABASE (IF_P EXISTS)? name (opt_with OPEN_PAREN drop_option_list CLOSE_PAREN)?\n   ;\n\ndrop_option_list\n   : drop_option (COMMA drop_option)*\n   ;\n\ndrop_option\n   : FORCE\n   ;\n\naltercollationstmt\n   : ALTER COLLATION any_name REFRESH VERSION_P\n   ;\n\naltersystemstmt\n   : ALTER SYSTEM_P (SET | RESET) generic_set\n   ;\n\ncreatedomainstmt\n   : CREATE DOMAIN_P any_name opt_as typename colquallist\n   ;\n\nalterdomainstmt\n   : ALTER DOMAIN_P any_name (alter_column_default | DROP NOT NULL_P | SET NOT NULL_P | ADD_P tableconstraint | DROP CONSTRAINT (IF_P EXISTS)? name opt_drop_behavior | VALIDATE CONSTRAINT name)\n   ;\n\nopt_as\n   : AS\n   |\n   ;\n\naltertsdictionarystmt\n   : ALTER TEXT_P SEARCH DICTIONARY any_name definition\n   ;\n\naltertsconfigurationstmt\n   : ALTER TEXT_P SEARCH CONFIGURATION any_name ADD_P MAPPING FOR name_list any_with any_name_list\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list any_with any_name_list\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING REPLACE any_name any_with any_name\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list REPLACE any_name any_with any_name\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING FOR name_list\n   | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING IF_P EXISTS FOR name_list\n   ;\n\nany_with\n   : WITH\n   //TODO\n\n   //         | WITH_LA\n\n   ;\n\ncreateconversionstmt\n   : CREATE opt_default CONVERSION_P any_name FOR sconst TO sconst FROM any_name\n   ;\n\nclusterstmt\n   : CLUSTER opt_verbose qualified_name cluster_index_specification\n   | CLUSTER opt_verbose\n   | CLUSTER opt_verbose name ON qualified_name\n   ;\n\ncluster_index_specification\n   : USING name\n   |\n   ;\n\nvacuumstmt\n   : VACUUM opt_full opt_freeze opt_verbose opt_analyze opt_vacuum_relation_list\n   | VACUUM OPEN_PAREN vac_analyze_option_list CLOSE_PAREN opt_vacuum_relation_list\n   ;\n\nanalyzestmt\n   : analyze_keyword opt_verbose opt_vacuum_relation_list\n   | analyze_keyword OPEN_PAREN vac_analyze_option_list CLOSE_PAREN opt_vacuum_relation_list\n   ;\n\nvac_analyze_option_list\n   : vac_analyze_option_elem (COMMA vac_analyze_option_elem)*\n   ;\n\nanalyze_keyword\n   : ANALYZE\n   | ANALYSE\n   ;\n\nvac_analyze_option_elem\n   : vac_analyze_option_name vac_analyze_option_arg\n   ;\n\nvac_analyze_option_name\n   : nonreservedword\n   | analyze_keyword\n   ;\n\nvac_analyze_option_arg\n   : opt_boolean_or_string\n   | numericonly\n   |\n   ;\n\nopt_analyze\n   : analyze_keyword\n   |\n   ;\n\nopt_verbose\n   : VERBOSE\n   |\n   ;\n\nopt_full\n   : FULL\n   |\n   ;\n\nopt_freeze\n   : FREEZE\n   |\n   ;\n\nopt_name_list\n   : OPEN_PAREN name_list CLOSE_PAREN\n   |\n   ;\n\nvacuum_relation\n   : qualified_name opt_name_list\n   ;\n\nvacuum_relation_list\n   : vacuum_relation (COMMA vacuum_relation)*\n   ;\n\nopt_vacuum_relation_list\n   : vacuum_relation_list\n   |\n   ;\n\nexplainstmt\n   : EXPLAIN explainablestmt\n   | EXPLAIN analyze_keyword opt_verbose explainablestmt\n   | EXPLAIN VERBOSE explainablestmt\n   | EXPLAIN OPEN_PAREN explain_option_list CLOSE_PAREN explainablestmt\n   ;\n\nexplainablestmt\n   : selectstmt\n   | insertstmt\n   | updatestmt\n   | deletestmt\n   | declarecursorstmt\n   | createasstmt\n   | creatematviewstmt\n   | refreshmatviewstmt\n   | executestmt\n   ;\n\nexplain_option_list\n   : explain_option_elem (COMMA explain_option_elem)*\n   ;\n\nexplain_option_elem\n   : explain_option_name explain_option_arg\n   ;\n\nexplain_option_name\n   : nonreservedword\n   | analyze_keyword\n   ;\n\nexplain_option_arg\n   : opt_boolean_or_string\n   | numericonly\n   |\n   ;\n\npreparestmt\n   : PREPARE name prep_type_clause AS preparablestmt\n   ;\n\nprep_type_clause\n   : OPEN_PAREN type_list CLOSE_PAREN\n   |\n   ;\n\npreparablestmt\n   : selectstmt\n   | insertstmt\n   | updatestmt\n   | deletestmt\n   ;\n\nexecutestmt\n   : EXECUTE name execute_param_clause\n   | CREATE opttemp TABLE create_as_target AS EXECUTE name execute_param_clause opt_with_data\n   | CREATE opttemp TABLE IF_P NOT EXISTS create_as_target AS EXECUTE name execute_param_clause opt_with_data\n   ;\n\nexecute_param_clause\n   : OPEN_PAREN expr_list CLOSE_PAREN\n   |\n   ;\n\ndeallocatestmt\n   : DEALLOCATE name\n   | DEALLOCATE PREPARE name\n   | DEALLOCATE ALL\n   | DEALLOCATE PREPARE ALL\n   ;\n\ninsertstmt\n   : opt_with_clause INSERT INTO insert_target insert_rest opt_on_conflict returning_clause\n   ;\n\ninsert_target\n   : qualified_name (AS colid)?\n   ;\n\ninsert_rest\n   : selectstmt\n   | OVERRIDING override_kind VALUE_P selectstmt\n   | OPEN_PAREN insert_column_list CLOSE_PAREN (OVERRIDING override_kind VALUE_P)? selectstmt\n   | DEFAULT VALUES\n   ;\n\noverride_kind\n   : USER\n   | SYSTEM_P\n   ;\n\ninsert_column_list\n   : insert_column_item (COMMA insert_column_item)*\n   ;\n\ninsert_column_item\n   : colid opt_indirection\n   ;\n\nopt_on_conflict\n   : ON CONFLICT opt_conf_expr DO (UPDATE SET set_clause_list where_clause | NOTHING)\n   |\n   ;\n\nopt_conf_expr\n   : OPEN_PAREN index_params CLOSE_PAREN where_clause\n   | ON CONSTRAINT name\n   |\n   ;\n\nreturning_clause\n   : RETURNING target_list\n   |\n   ;\n\n// https://www.postgresql.org/docs/current/sql-merge.html\nmergestmt\n   : MERGE INTO? qualified_name alias_clause? USING (select_with_parens|qualified_name) alias_clause? ON a_expr\n        (merge_insert_clause merge_update_clause? | merge_update_clause merge_insert_clause?) merge_delete_clause?\n   ;\n\nmerge_insert_clause\n   : WHEN NOT MATCHED (AND a_expr)? THEN? INSERT (OPEN_PAREN insert_column_list CLOSE_PAREN)? values_clause\n   ;\n\nmerge_update_clause\n   : WHEN MATCHED (AND a_expr)? THEN? UPDATE SET set_clause_list\n   ;\n\nmerge_delete_clause\n   : WHEN MATCHED THEN? DELETE_P\n   ;\n\ndeletestmt\n   : opt_with_clause DELETE_P FROM relation_expr_opt_alias using_clause where_or_current_clause returning_clause\n   ;\n\nusing_clause\n   : USING from_list\n   |\n   ;\n\nlockstmt\n   : LOCK_P opt_table relation_expr_list opt_lock opt_nowait\n   ;\n\nopt_lock\n   : IN_P lock_type MODE\n   |\n   ;\n\nlock_type\n   : ACCESS (SHARE | EXCLUSIVE)\n   | ROW (SHARE | EXCLUSIVE)\n   | SHARE (UPDATE EXCLUSIVE | ROW EXCLUSIVE)?\n   | EXCLUSIVE\n   ;\n\nopt_nowait\n   : NOWAIT\n   |\n   ;\n\nopt_nowait_or_skip\n   : NOWAIT\n   | SKIP_P LOCKED\n   |\n   ;\n\nupdatestmt\n   : opt_with_clause UPDATE relation_expr_opt_alias SET set_clause_list from_clause where_or_current_clause returning_clause\n   ;\n\nset_clause_list\n   : set_clause (COMMA set_clause)*\n   ;\n\nset_clause\n   : set_target EQUAL a_expr\n   | OPEN_PAREN set_target_list CLOSE_PAREN EQUAL a_expr\n   ;\n\nset_target\n   : colid opt_indirection\n   ;\n\nset_target_list\n   : set_target (COMMA set_target)*\n   ;\n\ndeclarecursorstmt\n   : DECLARE cursor_name cursor_options CURSOR opt_hold FOR selectstmt\n   ;\n\ncursor_name\n   : name\n   ;\n\ncursor_options\n   : (NO SCROLL | SCROLL | BINARY | INSENSITIVE)*\n   ;\n\nopt_hold\n   :\n   | WITH HOLD\n   | WITHOUT HOLD\n   ;\n/*\nTODO: why select_with_parens alternative is needed at all?\ni guess it because original byson grammar can choose selectstmt(2)->select_with_parens on only OPEN_PARENT/SELECT kewords at the begining of statement;\n(select * from tab);\nparse can go through selectstmt( )->select_no_parens(1)->select_clause(2)->select_with_parens(1)->select_no_parens(1)->select_clause(1)->simple_select\ninstead of           selectstmt(1)->select_no_parens(1)->select_clause(2)->select_with_parens(1)->select_no_parens(1)->select_clause(1)->simple_select\nall standard tests passed on both variants\n*/\n\n\nselectstmt\n   : select_no_parens\n   | select_with_parens\n   ;\n\nselect_with_parens\n   : OPEN_PAREN select_no_parens CLOSE_PAREN\n   | OPEN_PAREN select_with_parens CLOSE_PAREN\n   ;\n\nselect_no_parens\n   : select_clause opt_sort_clause (for_locking_clause opt_select_limit | select_limit opt_for_locking_clause)?\n   | with_clause select_clause opt_sort_clause (for_locking_clause opt_select_limit | select_limit opt_for_locking_clause)?\n   ;\n\nselect_clause\n   : simple_select_intersect ((UNION | EXCEPT) all_or_distinct simple_select_intersect)*\n   ;\n\nsimple_select_intersect\n    : simple_select_pramary (INTERSECT all_or_distinct simple_select_pramary)*\n    ;\n\nsimple_select_pramary\n   : ( SELECT (opt_all_clause into_clause opt_target_list | distinct_clause target_list)\n           into_clause\n           from_clause\n           where_clause\n           group_clause\n           having_clause\n           window_clause\n    )\n   | values_clause\n   | TABLE relation_expr\n   | select_with_parens\n   ;\n\nwith_clause\n   : WITH RECURSIVE? cte_list\n   ;\n\ncte_list\n   : common_table_expr (COMMA common_table_expr)*\n   ;\n\ncommon_table_expr\n   : name opt_name_list AS opt_materialized OPEN_PAREN preparablestmt CLOSE_PAREN\n   ;\n\nopt_materialized\n   : MATERIALIZED\n   | NOT MATERIALIZED\n   |\n   ;\n\nopt_with_clause\n   : with_clause\n   |\n   ;\n\ninto_clause\n   : INTO (opt_strict opttempTableName | into_target)\n   |\n   ;\n\nopt_strict\n   :\n   | STRICT_P\n   ;\n\nopttempTableName\n   : (LOCAL|GLOBAL)? (TEMPORARY | TEMP) opt_table qualified_name\n   | UNLOGGED opt_table qualified_name\n   | TABLE qualified_name\n   | qualified_name\n   ;\n\nopt_table\n   : TABLE\n   |\n   ;\n\nall_or_distinct\n   : ALL\n   | DISTINCT\n   |\n   ;\n\ndistinct_clause\n   : DISTINCT (ON OPEN_PAREN expr_list CLOSE_PAREN)?\n   ;\n\nopt_all_clause\n   : ALL\n   |\n   ;\n\nopt_sort_clause\n   : sort_clause\n   |\n   ;\n\nsort_clause\n   : ORDER BY sortby_list\n   ;\n\nsortby_list\n   : sortby (COMMA sortby)*\n   ;\n\nsortby\n   : a_expr (USING qual_all_op | opt_asc_desc) opt_nulls_order\n   ;\n\nselect_limit\n   : limit_clause offset_clause?\n   | offset_clause limit_clause?\n   ;\n\nopt_select_limit\n   : select_limit\n   |\n   ;\n\nlimit_clause\n   : LIMIT select_limit_value (COMMA select_offset_value)?\n   | FETCH first_or_next (select_fetch_first_value row_or_rows (ONLY | WITH TIES) | row_or_rows (ONLY | WITH TIES))\n   ;\n\noffset_clause\n   : OFFSET (select_offset_value | select_fetch_first_value row_or_rows)\n   ;\n\nselect_limit_value\n   : a_expr\n   | ALL\n   ;\n\nselect_offset_value\n   : a_expr\n   ;\n\nselect_fetch_first_value\n   : c_expr\n   | PLUS i_or_f_const\n   | MINUS i_or_f_const\n   ;\n\ni_or_f_const\n   : iconst\n   | fconst\n   ;\n\nrow_or_rows\n   : ROW\n   | ROWS\n   ;\n\nfirst_or_next\n   : FIRST_P\n   | NEXT\n   ;\n\ngroup_clause\n   : GROUP_P BY group_by_list\n   |\n   ;\n\ngroup_by_list\n   : group_by_item (COMMA group_by_item)*\n   ;\n\ngroup_by_item\n   : empty_grouping_set\n   | cube_clause\n   | rollup_clause\n   | grouping_sets_clause\n   | a_expr\n   ;\n\nempty_grouping_set\n   : OPEN_PAREN CLOSE_PAREN\n   ;\n\nrollup_clause\n   : ROLLUP OPEN_PAREN expr_list CLOSE_PAREN\n   ;\n\ncube_clause\n   : CUBE OPEN_PAREN expr_list CLOSE_PAREN\n   ;\n\ngrouping_sets_clause\n   : GROUPING SETS OPEN_PAREN group_by_list CLOSE_PAREN\n   ;\n\nhaving_clause\n   : HAVING a_expr\n   |\n   ;\n\nfor_locking_clause\n   : for_locking_items\n   | FOR READ ONLY\n   ;\n\nopt_for_locking_clause\n   : for_locking_clause\n   |\n   ;\n\nfor_locking_items\n   : for_locking_item+\n   ;\n\nfor_locking_item\n   : for_locking_strength locked_rels_list opt_nowait_or_skip\n   ;\n\nfor_locking_strength\n   : FOR ((NO KEY)? UPDATE | KEY? SHARE)\n   ;\n\nlocked_rels_list\n   : OF qualified_name_list\n   |\n   ;\n\nvalues_clause\n   : VALUES OPEN_PAREN expr_list CLOSE_PAREN (COMMA OPEN_PAREN expr_list CLOSE_PAREN)*\n   ;\n\nfrom_clause\n   : FROM from_list\n   |\n   ;\n\nfrom_list\n   : non_ansi_join\n   | table_ref (COMMA table_ref)*\n   ;\n\nnon_ansi_join\n   : table_ref (COMMA table_ref)+\n   ;\n\ntable_ref\n   : (relation_expr opt_alias_clause tablesample_clause?\n      | func_table func_alias_clause\n      | xmltable opt_alias_clause\n      | select_with_parens opt_alias_clause\n      | LATERAL_P (\n                    xmltable opt_alias_clause\n                    | func_table func_alias_clause\n                    | select_with_parens opt_alias_clause\n                  )\n      | OPEN_PAREN table_ref (\n                                CROSS JOIN table_ref\n                                | NATURAL join_type? JOIN table_ref\n                                | join_type? JOIN table_ref join_qual\n                             )? CLOSE_PAREN opt_alias_clause\n     )\n        (CROSS JOIN table_ref | NATURAL join_type? JOIN table_ref | join_type? JOIN table_ref join_qual)*\n   ;\n\nalias_clause\n   : AS? colid (OPEN_PAREN name_list CLOSE_PAREN)?\n   ;\n\nopt_alias_clause\n   : table_alias_clause\n   |\n   ;\n\ntable_alias_clause\n   : AS? table_alias (OPEN_PAREN name_list CLOSE_PAREN)?\n   ;\n\nfunc_alias_clause\n   : alias_clause\n   | (AS colid? | colid) OPEN_PAREN tablefuncelementlist CLOSE_PAREN\n   |\n   ;\n\njoin_type\n   : (FULL | LEFT | RIGHT | INNER_P) OUTER_P?\n   ;\n\njoin_qual\n   : USING OPEN_PAREN name_list CLOSE_PAREN\n   | ON a_expr\n   ;\n\nrelation_expr\n   : qualified_name STAR?\n   | ONLY (qualified_name | OPEN_PAREN qualified_name CLOSE_PAREN)\n   ;\n\nrelation_expr_list\n   : relation_expr (COMMA relation_expr)*\n   ;\n\nrelation_expr_opt_alias\n   : relation_expr (AS? colid)?\n   ;\n\ntablesample_clause\n   : TABLESAMPLE func_name OPEN_PAREN expr_list CLOSE_PAREN opt_repeatable_clause\n   ;\n\nopt_repeatable_clause\n   : REPEATABLE OPEN_PAREN a_expr CLOSE_PAREN\n   |\n   ;\n\nfunc_table\n   : func_expr_windowless opt_ordinality\n   | ROWS FROM OPEN_PAREN rowsfrom_list CLOSE_PAREN opt_ordinality\n   ;\n\nrowsfrom_item\n   : func_expr_windowless opt_col_def_list\n   ;\n\nrowsfrom_list\n   : rowsfrom_item (COMMA rowsfrom_item)*\n   ;\n\nopt_col_def_list\n   : AS OPEN_PAREN tablefuncelementlist CLOSE_PAREN\n   |\n   ;\n   //TODO WITH_LA was used\n\nopt_ordinality\n   : WITH ORDINALITY\n   |\n   ;\n\nwhere_clause\n   : WHERE a_expr\n   |\n   ;\n\nwhere_or_current_clause\n   : WHERE (CURRENT_P OF cursor_name | a_expr)\n   |\n   ;\n\nopttablefuncelementlist\n   : tablefuncelementlist\n   |\n   ;\n\ntablefuncelementlist\n   : tablefuncelement (COMMA tablefuncelement)*\n   ;\n\ntablefuncelement\n   : colid typename opt_collate_clause\n   ;\n\nxmltable\n   : XMLTABLE OPEN_PAREN (c_expr xmlexists_argument COLUMNS xmltable_column_list | XMLNAMESPACES OPEN_PAREN xml_namespace_list CLOSE_PAREN COMMA c_expr xmlexists_argument COLUMNS xmltable_column_list) CLOSE_PAREN\n   ;\n\nxmltable_column_list\n   : xmltable_column_el (COMMA xmltable_column_el)*\n   ;\n\nxmltable_column_el\n   : colid (typename xmltable_column_option_list? | FOR ORDINALITY)\n   ;\n\nxmltable_column_option_list\n   : xmltable_column_option_el+\n   ;\n\nxmltable_column_option_el\n   : DEFAULT a_expr\n   | identifier a_expr\n   | NOT NULL_P\n   | NULL_P\n   ;\n\nxml_namespace_list\n   : xml_namespace_el (COMMA xml_namespace_el)*\n   ;\n\nxml_namespace_el\n   : b_expr AS collabel\n   | DEFAULT b_expr\n   ;\n\ntypename\n   : SETOF? simpletypename (opt_array_bounds | ARRAY (OPEN_BRACKET iconst CLOSE_BRACKET)?)\n   | qualified_name PERCENT (ROWTYPE | TYPE_P)\n   ;\n\nopt_array_bounds\n   : (OPEN_BRACKET iconst? CLOSE_BRACKET)*\n   ;\n\nsimpletypename\n   : generictype\n   | numeric\n   | bit\n   | character\n   | constdatetime\n   | constinterval (opt_interval | OPEN_PAREN iconst CLOSE_PAREN)\n   ;\n\nconsttypename\n   : numeric\n   | constbit\n   | constcharacter\n   | constdatetime\n   ;\n\ngenerictype\n   : (builtin_function_name | type_function_name | LEFT | RIGHT) attrs? opt_type_modifiers\n   ;\n\nopt_type_modifiers\n   : OPEN_PAREN expr_list CLOSE_PAREN\n   |\n   ;\n\nnumeric\n   : INT_P\n   | INTEGER\n   | SMALLINT\n   | BIGINT\n   | REAL\n   | FLOAT_P opt_float\n   | DOUBLE_P PRECISION\n   | DECIMAL_P opt_type_modifiers\n   | DEC opt_type_modifiers\n   | NUMERIC opt_type_modifiers\n   | BOOLEAN_P\n   ;\n\nopt_float\n   : OPEN_PAREN iconst CLOSE_PAREN\n   |\n   ;\n   //todo: merge alts\n\nbit\n   : bitwithlength\n   | bitwithoutlength\n   ;\n\nconstbit\n   : bitwithlength\n   | bitwithoutlength\n   ;\n\nbitwithlength\n   : BIT opt_varying OPEN_PAREN expr_list CLOSE_PAREN\n   ;\n\nbitwithoutlength\n   : BIT opt_varying\n   ;\n\ncharacter\n   : character_c (OPEN_PAREN iconst CLOSE_PAREN)?\n   ;\n\nconstcharacter\n   : character_c (OPEN_PAREN iconst CLOSE_PAREN)?\n   ;\n\ncharacter_c\n   : (CHARACTER | CHAR_P | NCHAR) opt_varying\n   | VARCHAR\n   | NATIONAL (CHARACTER | CHAR_P) opt_varying\n   ;\n\nopt_varying\n   : VARYING\n   |\n   ;\n\nconstdatetime\n   : (TIMESTAMP | TIME) (OPEN_PAREN iconst CLOSE_PAREN)? opt_timezone\n   ;\n\nconstinterval\n   : INTERVAL\n   ;\n   //TODO with_la was used\n\nopt_timezone\n   : WITH TIME ZONE\n   | WITHOUT TIME ZONE\n   |\n   ;\n\nopt_interval\n   : YEAR_P\n   | MONTH_P\n   | DAY_P\n   | HOUR_P\n   | MINUTE_P\n   | interval_second\n   | YEAR_P TO MONTH_P\n   | DAY_P TO (HOUR_P | MINUTE_P | interval_second)\n   | HOUR_P TO (MINUTE_P | interval_second)\n   | MINUTE_P TO interval_second\n   |\n   ;\n\ninterval_second\n   : SECOND_P (OPEN_PAREN iconst CLOSE_PAREN)?\n   ;\n\nopt_escape\n   : ESCAPE a_expr\n   |\n   ;\n   //precendence accroding to Table 4.2. Operator Precedence (highest to lowest)\n\n   //https://www.postgresql.org/docs/12/sql-syntax-lexical.html#SQL-PRECEDENCE\n\n/*\noriginal version of a_expr, for info\n a_expr: c_expr\n        //::\tleft\tPostgreSQL-style typecast\n       | a_expr TYPECAST typename -- 1\n       | a_expr COLLATE any_name -- 2\n       | a_expr AT TIME ZONE a_expr-- 3\n       //right\tunary plus, unary minus\n       | (PLUS| MINUS) a_expr -- 4\n        //left\texponentiation\n       | a_expr CARET a_expr -- 5\n        //left\tmultiplication, division, modulo\n       | a_expr (STAR | SLASH | PERCENT) a_expr -- 6\n        //left\taddition, subtraction\n       | a_expr (PLUS | MINUS) a_expr -- 7\n        //left\tall other native and user-defined operators\n       | a_expr qual_op a_expr -- 8\n       | qual_op a_expr -- 9\n        //range containment, set membership, string matching BETWEEN IN LIKE ILIKE SIMILAR\n       | a_expr NOT? (LIKE|ILIKE|SIMILAR TO|(BETWEEN SYMMETRIC?)) a_expr opt_escape -- 10\n        //< > = <= >= <>\t \tcomparison operators\n       | a_expr (LT | GT | EQUAL | LESS_EQUALS | GREATER_EQUALS | NOT_EQUALS) a_expr -- 11\n       //IS ISNULL NOTNULL\t \tIS TRUE, IS FALSE, IS NULL, IS DISTINCT FROM, etc\n       | a_expr IS NOT?\n            (\n                NULL_P\n                |TRUE_P\n                |FALSE_P\n                |UNKNOWN\n                |DISTINCT FROM a_expr\n                |OF OPEN_PAREN type_list CLOSE_PAREN\n                |DOCUMENT_P\n                |unicode_normal_form? NORMALIZED\n            ) -- 12\n       | a_expr (ISNULL|NOTNULL) -- 13\n       | row OVERLAPS row -- 14\n       //NOT\tright\tlogical negation\n       | NOT a_expr -- 15\n        //AND\tleft\tlogical conjunction\n       | a_expr AND a_expr -- 16\n        //OR\tleft\tlogical disjunction\n       | a_expr OR a_expr -- 17\n       | a_expr (LESS_LESS|GREATER_GREATER) a_expr -- 18\n       | a_expr qual_op -- 19\n       | a_expr NOT? IN_P in_expr -- 20\n       | a_expr subquery_Op sub_type (select_with_parens|OPEN_PAREN a_expr CLOSE_PAREN) -- 21\n       | UNIQUE select_with_parens -- 22\n       | DEFAULT -- 23\n;\n*/\n\n\na_expr\n   : a_expr_qual\n   ;\n/*23*/\n\n\n/*moved to c_expr*/\n\n\n/*22*/\n\n\n/*moved to c_expr*/\n\n\n/*19*/\n\n\na_expr_qual\n   : a_expr_lessless qual_op?\n   ;\n/*18*/\n\n\na_expr_lessless\n   : a_expr_or ((LESS_LESS | GREATER_GREATER) a_expr_or)*\n   ;\n/*17*/\n\n\na_expr_or\n   : a_expr_and (OR a_expr_and)*\n   ;\n/*16*/\n\na_expr_and\n   : a_expr_between (AND a_expr_between)*\n   ;\n/*21*/\n\na_expr_between\n   : a_expr_in (NOT? BETWEEN SYMMETRIC? a_expr_in AND a_expr_in)?\n   ;\n/*20*/\n\n\na_expr_in\n   : a_expr_unary_not (NOT? IN_P in_expr)?\n   ;\n/*15*/\n\n\na_expr_unary_not\n   : NOT? a_expr_isnull\n   ;\n/*14*/\n\n\n/*moved to c_expr*/\n\n\n/*13*/\n\n\na_expr_isnull\n   : a_expr_is_not (ISNULL | NOTNULL)?\n   ;\n/*12*/\n\n\na_expr_is_not\n   : a_expr_compare (IS NOT? (NULL_P | TRUE_P | FALSE_P | UNKNOWN | DISTINCT FROM a_expr | OF OPEN_PAREN type_list CLOSE_PAREN | DOCUMENT_P | unicode_normal_form? NORMALIZED))?\n   ;\n/*11*/\n\n\na_expr_compare\n   : a_expr_like ((LT | GT | EQUAL | LESS_EQUALS | GREATER_EQUALS | NOT_EQUALS) a_expr_like |subquery_Op sub_type (select_with_parens | OPEN_PAREN a_expr CLOSE_PAREN) /*21*/\n\n   )?\n   ;\n/*10*/\n\n\na_expr_like\n   : a_expr_qual_op (NOT? (LIKE | ILIKE | SIMILAR TO) a_expr_qual_op opt_escape)?\n   ;\n/* 8*/\n\n\na_expr_qual_op\n   : a_expr_unary_qualop (qual_op a_expr_unary_qualop)*\n   ;\n/* 9*/\n\n\na_expr_unary_qualop\n   : qual_op? a_expr_add\n   ;\n/* 7*/\n\n\na_expr_add\n   : a_expr_mul ((MINUS | PLUS) a_expr_mul)*\n   ;\n/* 6*/\n\n\na_expr_mul\n   : a_expr_caret ((STAR | SLASH | PERCENT) a_expr_caret)*\n   ;\n/* 5*/\n\n\na_expr_caret\n   : a_expr_unary_sign (CARET a_expr)?\n   ;\n/* 4*/\n\n\na_expr_unary_sign\n   : (MINUS | PLUS)? a_expr_at_time_zone /* */\n\n\n   ;\n/* 3*/\n\n\na_expr_at_time_zone\n   : a_expr_collate (AT TIME ZONE a_expr)?\n   ;\n/* 2*/\n\n\na_expr_collate\n   : a_expr_typecast (COLLATE any_name)?\n   ;\n/* 1*/\n\n\na_expr_typecast\n   : c_expr (TYPECAST typename)*\n   ;\n\nb_expr\n   : c_expr\n   | b_expr TYPECAST typename\n   //right\tunary plus, unary minus\n   | (PLUS | MINUS) b_expr\n   //^\tleft\texponentiation\n   | b_expr CARET b_expr\n   //* / %\tleft\tmultiplication, division, modulo\n   | b_expr (STAR | SLASH | PERCENT) b_expr\n   //+ -\tleft\taddition, subtraction\n   | b_expr (PLUS | MINUS) b_expr\n   //(any other operator)\tleft\tall other native and user-defined operators\n   | b_expr qual_op b_expr\n   //< > = <= >= <>\t \tcomparison operators\n   | b_expr (LT | GT | EQUAL | LESS_EQUALS | GREATER_EQUALS | NOT_EQUALS) b_expr\n   | qual_op b_expr\n   | b_expr qual_op\n   //S ISNULL NOTNULL\t \tIS TRUE, IS FALSE, IS NULL, IS DISTINCT FROM, etc\n   | b_expr IS NOT? (DISTINCT FROM b_expr | OF OPEN_PAREN type_list CLOSE_PAREN | DOCUMENT_P)\n   ;\n\nc_expr\n   : EXISTS select_with_parens # c_expr_exists\n   | ARRAY (select_with_parens | array_expr) # c_expr_expr\n   | PARAM opt_indirection # c_expr_expr\n   | GROUPING OPEN_PAREN expr_list CLOSE_PAREN # c_expr_expr\n   | /*22*/\n\n   UNIQUE select_with_parens # c_expr_expr\n   | columnref # c_expr_expr\n   | aexprconst # c_expr_expr\n   | plsqlvariablename # c_expr_expr\n   | OPEN_PAREN a_expr_in_parens = a_expr CLOSE_PAREN opt_indirection # c_expr_expr\n   | case_expr # c_expr_case\n   | func_expr # c_expr_expr\n   | select_with_parens indirection? # c_expr_expr\n   | explicit_row # c_expr_expr\n   | implicit_row # c_expr_expr\n   | row OVERLAPS row /* 14*/\n\n   # c_expr_expr\n   ;\n\nplsqlvariablename\n   : PLSQLVARIABLENAME\n   ;\n\nfunc_application\n   : func_name OPEN_PAREN (func_arg_list (COMMA VARIADIC func_arg_expr)? opt_sort_clause | VARIADIC func_arg_expr opt_sort_clause | (ALL | DISTINCT) func_arg_list opt_sort_clause | STAR |) CLOSE_PAREN\n   ;\n\nfunc_expr\n   : func_application within_group_clause filter_clause over_clause\n   | func_expr_common_subexpr\n   ;\n\nfunc_expr_windowless\n   : func_application\n   | func_expr_common_subexpr\n   ;\n\nfunc_expr_common_subexpr\n   : COLLATION FOR OPEN_PAREN a_expr CLOSE_PAREN\n   | CURRENT_DATE\n   | CURRENT_TIME (OPEN_PAREN iconst CLOSE_PAREN)?\n   | CURRENT_TIMESTAMP (OPEN_PAREN iconst CLOSE_PAREN)?\n   | LOCALTIME (OPEN_PAREN iconst CLOSE_PAREN)?\n   | LOCALTIMESTAMP (OPEN_PAREN iconst CLOSE_PAREN)?\n   | CURRENT_ROLE\n   | CURRENT_USER\n   | SESSION_USER\n   | USER\n   | CURRENT_CATALOG\n   | CURRENT_SCHEMA\n   | CAST OPEN_PAREN a_expr AS typename CLOSE_PAREN\n   | EXTRACT OPEN_PAREN extract_list CLOSE_PAREN\n   | NORMALIZE OPEN_PAREN a_expr (COMMA unicode_normal_form)? CLOSE_PAREN\n   | OVERLAY OPEN_PAREN overlay_list CLOSE_PAREN\n   | POSITION OPEN_PAREN position_list CLOSE_PAREN\n   | SUBSTRING OPEN_PAREN substr_list CLOSE_PAREN\n   | TREAT OPEN_PAREN a_expr AS typename CLOSE_PAREN\n   | TRIM OPEN_PAREN (BOTH | LEADING | TRAILING)? trim_list CLOSE_PAREN\n   | NULLIF OPEN_PAREN a_expr COMMA a_expr CLOSE_PAREN\n   | COALESCE OPEN_PAREN expr_list CLOSE_PAREN\n   | GREATEST OPEN_PAREN expr_list CLOSE_PAREN\n   | LEAST OPEN_PAREN expr_list CLOSE_PAREN\n   | XMLCONCAT OPEN_PAREN expr_list CLOSE_PAREN\n   | XMLELEMENT OPEN_PAREN NAME_P collabel (COMMA (xml_attributes | expr_list))? CLOSE_PAREN\n   | XMLEXISTS OPEN_PAREN c_expr xmlexists_argument CLOSE_PAREN\n   | XMLFOREST OPEN_PAREN xml_attribute_list CLOSE_PAREN\n   | XMLPARSE OPEN_PAREN document_or_content a_expr xml_whitespace_option CLOSE_PAREN\n   | XMLPI OPEN_PAREN NAME_P collabel (COMMA a_expr)? CLOSE_PAREN\n   | XMLROOT OPEN_PAREN XML_P a_expr COMMA xml_root_version opt_xml_root_standalone CLOSE_PAREN\n   | XMLSERIALIZE OPEN_PAREN document_or_content a_expr AS simpletypename CLOSE_PAREN\n   ;\n\nxml_root_version\n   : VERSION_P a_expr\n   | VERSION_P NO VALUE_P\n   ;\n\nopt_xml_root_standalone\n   : COMMA STANDALONE_P YES_P\n   | COMMA STANDALONE_P NO\n   | COMMA STANDALONE_P NO VALUE_P\n   |\n   ;\n\nxml_attributes\n   : XMLATTRIBUTES OPEN_PAREN xml_attribute_list CLOSE_PAREN\n   ;\n\nxml_attribute_list\n   : xml_attribute_el (COMMA xml_attribute_el)*\n   ;\n\nxml_attribute_el\n   : a_expr (AS collabel)?\n   ;\n\ndocument_or_content\n   : DOCUMENT_P\n   | CONTENT_P\n   ;\n\nxml_whitespace_option\n   : PRESERVE WHITESPACE_P\n   | STRIP_P WHITESPACE_P\n   |\n   ;\n\nxmlexists_argument\n   : PASSING c_expr\n   | PASSING c_expr xml_passing_mech\n   | PASSING xml_passing_mech c_expr\n   | PASSING xml_passing_mech c_expr xml_passing_mech\n   ;\n\nxml_passing_mech\n   : BY (REF | VALUE_P)\n   ;\n\nwithin_group_clause\n   : WITHIN GROUP_P OPEN_PAREN sort_clause CLOSE_PAREN\n   |\n   ;\n\nfilter_clause\n   : FILTER OPEN_PAREN WHERE a_expr CLOSE_PAREN\n   |\n   ;\n\nwindow_clause\n   : WINDOW window_definition_list\n   |\n   ;\n\nwindow_definition_list\n   : window_definition (COMMA window_definition)*\n   ;\n\nwindow_definition\n   : colid AS window_specification\n   ;\n\nover_clause\n   : OVER (window_specification | colid)\n   |\n   ;\n\nwindow_specification\n   : OPEN_PAREN opt_existing_window_name opt_partition_clause opt_sort_clause opt_frame_clause CLOSE_PAREN\n   ;\n\nopt_existing_window_name\n   : colid\n   |\n   ;\n\nopt_partition_clause\n   : PARTITION BY expr_list\n   |\n   ;\n\nopt_frame_clause\n   : RANGE frame_extent opt_window_exclusion_clause\n   | ROWS frame_extent opt_window_exclusion_clause\n   | GROUPS frame_extent opt_window_exclusion_clause\n   |\n   ;\n\nframe_extent\n   : frame_bound\n   | BETWEEN frame_bound AND frame_bound\n   ;\n\nframe_bound\n   : UNBOUNDED (PRECEDING | FOLLOWING)\n   | CURRENT_P ROW\n   | a_expr (PRECEDING | FOLLOWING)\n   ;\n\nopt_window_exclusion_clause\n   : EXCLUDE (CURRENT_P ROW | GROUP_P | TIES | NO OTHERS)\n   |\n   ;\n\nrow\n   : ROW OPEN_PAREN expr_list? CLOSE_PAREN\n   | OPEN_PAREN expr_list COMMA a_expr CLOSE_PAREN\n   ;\n\nexplicit_row\n   : ROW OPEN_PAREN expr_list? CLOSE_PAREN\n   ;\n/*\nTODO:\nfor some reason v1\nimplicit_row: OPEN_PAREN expr_list COMMA a_expr CLOSE_PAREN;\nworks better than v2\nimplicit_row: OPEN_PAREN expr_list  CLOSE_PAREN;\nwhile looks like they are almost the same, except v2 requieres at least 2 items in list\nwhile v1 allows single item in list\n*/\n\n\nimplicit_row\n   : OPEN_PAREN expr_list COMMA a_expr CLOSE_PAREN\n   ;\n\nsub_type\n   : ANY\n   | SOME\n   | ALL\n   ;\n\nall_op\n   : Operator\n   | mathop\n   ;\n\nmathop\n   : PLUS\n   | MINUS\n   | STAR\n   | SLASH\n   | PERCENT\n   | CARET\n   | LT\n   | GT\n   | EQUAL\n   | LESS_EQUALS\n   | GREATER_EQUALS\n   | NOT_EQUALS\n   ;\n\nqual_op\n   : Operator\n   | OPERATOR OPEN_PAREN any_operator CLOSE_PAREN\n   ;\n\nqual_all_op\n   : all_op\n   | OPERATOR OPEN_PAREN any_operator CLOSE_PAREN\n   ;\n\nsubquery_Op\n   : all_op\n   | OPERATOR OPEN_PAREN any_operator CLOSE_PAREN\n   | LIKE\n   | NOT LIKE\n   | ILIKE\n   | NOT ILIKE\n   ;\n\nexpr_list\n   : a_expr (COMMA a_expr)*\n   ;\n\nfunc_arg_list\n   : func_arg_expr (COMMA func_arg_expr)*\n   ;\n\nfunc_arg_expr\n   : a_expr\n   | param_name (COLON_EQUALS | EQUALS_GREATER) a_expr\n   ;\n\ntype_list\n   : typename (COMMA typename)*\n   ;\n\narray_expr\n   : OPEN_BRACKET (expr_list | array_expr_list)? CLOSE_BRACKET\n   ;\n\narray_expr_list\n   : array_expr (COMMA array_expr)*\n   ;\n\nextract_list\n   : extract_arg FROM a_expr\n   |\n   ;\n\nextract_arg\n   : identifier\n   | YEAR_P\n   | MONTH_P\n   | DAY_P\n   | HOUR_P\n   | MINUTE_P\n   | SECOND_P\n   | sconst\n   ;\n\nunicode_normal_form\n   : NFC\n   | NFD\n   | NFKC\n   | NFKD\n   ;\n\noverlay_list\n   : a_expr PLACING a_expr FROM a_expr (FOR a_expr)?\n   ;\n\nposition_list\n   : b_expr IN_P b_expr\n   |\n   ;\n\nsubstr_list\n   : a_expr FROM a_expr FOR a_expr\n   | a_expr FOR a_expr FROM a_expr\n   | a_expr FROM a_expr\n   | a_expr FOR a_expr\n   | a_expr SIMILAR a_expr ESCAPE a_expr\n   | expr_list\n   ;\n\ntrim_list\n   : a_expr FROM expr_list\n   | FROM expr_list\n   | expr_list\n   ;\n\nin_expr\n   : select_with_parens # in_expr_select\n   | OPEN_PAREN expr_list CLOSE_PAREN # in_expr_list\n   ;\n\ncase_expr\n   : CASE case_arg when_clause_list case_default END_P\n   ;\n\nwhen_clause_list\n   : when_clause+\n   ;\n\nwhen_clause\n   : WHEN a_expr THEN a_expr\n   ;\n\ncase_default\n   : ELSE a_expr\n   |\n   ;\n\ncase_arg\n   : a_expr\n   |\n   ;\n\ncolumnref\n   : colid indirection?\n   ;\n\nindirection_el\n   : DOT (attr_name | STAR)\n   | OPEN_BRACKET (a_expr | opt_slice_bound COLON opt_slice_bound) CLOSE_BRACKET\n   ;\n\nopt_slice_bound\n   : a_expr\n   |\n   ;\n\nindirection\n   : indirection_el+\n   ;\n\nopt_indirection\n   : indirection_el*\n   ;\n\nopt_target_list\n   : target_list\n   |\n   ;\n\ntarget_list\n   : target_el (COMMA target_el)*\n   ;\n\ntarget_el\n   : a_expr (AS collabel | identifier |) # target_label\n   | STAR # target_star\n   ;\n\nqualified_name_list\n   : qualified_name (COMMA qualified_name)*\n   ;\n\nqualified_name\n   : colid indirection?\n   ;\n\nname_list\n   : name (COMMA name)*\n   ;\n\nname\n   : colid\n   ;\n\nattr_name\n   : collabel\n   ;\n\nfile_name\n   : sconst\n   ;\n\nfunc_name\n   : builtin_function_name\n   | type_function_name\n   | colid indirection\n   | LEFT\n   | RIGHT\n   ;\n\naexprconst\n   : iconst\n   | fconst\n   | sconst\n   | bconst\n   | xconst\n   | func_name (sconst | OPEN_PAREN func_arg_list opt_sort_clause CLOSE_PAREN sconst)\n   | consttypename sconst\n   | constinterval (sconst opt_interval | OPEN_PAREN iconst CLOSE_PAREN sconst)\n   | TRUE_P\n   | FALSE_P\n   | NULL_P\n   ;\n\nxconst\n   : HexadecimalStringConstant\n   ;\n\nbconst\n   : BinaryStringConstant\n   ;\n\nfconst\n   : Numeric\n   ;\n\niconst\n   : Integral\n   ;\n\nsconst\n   : anysconst opt_uescape\n   ;\n\nanysconst\n   : StringConstant\n   | UnicodeEscapeStringConstant\n   | BeginDollarStringConstant DollarText* EndDollarStringConstant\n   | EscapeStringConstant\n   ;\n\nopt_uescape\n   : UESCAPE anysconst\n   |\n   ;\n\nsignediconst\n   : iconst\n   | PLUS iconst\n   | MINUS iconst\n   ;\n\nroleid\n   : rolespec\n   ;\n\nrolespec\n   : nonreservedword\n   | CURRENT_USER\n   | SESSION_USER\n   ;\n\nrole_list\n   : rolespec (COMMA rolespec)*\n   ;\n\ncolid\n   : identifier\n   | unreserved_keyword\n   | col_name_keyword\n   | plsql_unreserved_keyword\n   | LEFT\n   | RIGHT\n   ;\n\ntable_alias\n   : identifier\n   | unreserved_keyword\n   | col_name_keyword\n   | plsql_unreserved_keyword\n   ;\n\n\ntype_function_name\n   : identifier\n   | unreserved_keyword\n   | plsql_unreserved_keyword\n   | type_func_name_keyword\n   ;\n\nnonreservedword\n   : identifier\n   | unreserved_keyword\n   | col_name_keyword\n   | type_func_name_keyword\n   ;\n\ncollabel\n   : identifier\n   | plsql_unreserved_keyword\n   | unreserved_keyword\n   | col_name_keyword\n   | type_func_name_keyword\n   | reserved_keyword\n   ;\n\nidentifier\n   : Identifier opt_uescape\n   | QuotedIdentifier\n   | UnicodeQuotedIdentifier\n   | plsqlvariablename\n   | plsqlidentifier\n   | plsql_unreserved_keyword\n   ;\n\nplsqlidentifier\n   : PLSQLIDENTIFIER\n   ;\n\nunreserved_keyword\n   : ABORT_P\n   | ABSOLUTE_P\n   | ACCESS\n   | ACTION\n   | ADD_P\n   | ADMIN\n   | AFTER\n   | AGGREGATE\n   | ALSO\n   | ALTER\n   | ALWAYS\n   | ASSERTION\n   | ASSIGNMENT\n   | AT\n   | ATTACH\n   | ATTRIBUTE\n   | BACKWARD\n   | BEFORE\n   | BEGIN_P\n   | BY\n   | CACHE\n   | CALL\n   | CALLED\n   | CASCADE\n   | CASCADED\n   | CATALOG\n   | CHAIN\n   | CHARACTERISTICS\n   | CHECKPOINT\n   | CLASS\n   | CLOSE\n   | CLUSTER\n   | COLUMNS\n   | COMMENT\n   | COMMENTS\n   | COMMIT\n   | COMMITTED\n   | CONFIGURATION\n   | CONFLICT\n   | CONNECTION\n   | CONSTRAINTS\n   | CONTENT_P\n   | CONTINUE_P\n   | CONVERSION_P\n   | COPY\n   | COST\n   | CSV\n   | CUBE\n   | CURRENT_P\n   | CURSOR\n   | CYCLE\n   | DATA_P\n   | DATABASE\n   | DAY_P\n   | DEALLOCATE\n   | DECLARE\n   | DEFAULTS\n   | DEFERRED\n   | DEFINER\n   | DELETE_P\n   | DELIMITER\n   | DELIMITERS\n   | DEPENDS\n   | DETACH\n   | DICTIONARY\n   | DISABLE_P\n   | DISCARD\n   | DOCUMENT_P\n   | DOMAIN_P\n   | DOUBLE_P\n   | DROP\n   | EACH\n   | ENABLE_P\n   | ENCODING\n   | ENCRYPTED\n   | ENUM_P\n   | ESCAPE\n   | EVENT\n   | EXCLUDE\n   | EXCLUDING\n   | EXCLUSIVE\n   | EXECUTE\n   | EXPLAIN\n   | EXPRESSION\n   | EXTENSION\n   | EXTERNAL\n   | FAMILY\n   | FILTER\n   | FIRST_P\n   | FOLLOWING\n   | FORCE\n   | FORWARD\n   | FUNCTION\n   | FUNCTIONS\n   | GENERATED\n   | GLOBAL\n   | GRANTED\n   | GROUPS\n   | HANDLER\n   | HEADER_P\n   | HOLD\n   | HOUR_P\n   | IDENTITY_P\n   | IF_P\n   | IMMEDIATE\n   | IMMUTABLE\n   | IMPLICIT_P\n   | IMPORT_P\n   | INCLUDE\n   | INCLUDING\n   | INCREMENT\n   | INDEX\n   | INDEXES\n   | INHERIT\n   | INHERITS\n   | INLINE_P\n   | INPUT_P\n   | INSENSITIVE\n   | INSERT\n   | INSTEAD\n   | INVOKER\n   | ISOLATION\n   | KEY\n   | LABEL\n   | LANGUAGE\n   | LARGE_P\n   | LAST_P\n   | LEAKPROOF\n   | LEVEL\n   | LISTEN\n   | LOAD\n   | LOCAL\n   | LOCATION\n   | LOCK_P\n   | LOCKED\n   | LOGGED\n   | MAPPING\n   | MATCH\n   | MATERIALIZED\n   | MAXVALUE\n   | METHOD\n   | MINUTE_P\n   | MINVALUE\n   | MODE\n   | MONTH_P\n   | MOVE\n   | NAME_P\n   | NAMES\n   | NEW\n   | NEXT\n   | NFC\n   | NFD\n   | NFKC\n   | NFKD\n   | NO\n   | NORMALIZED\n   | NOTHING\n   | NOTIFY\n   | NOWAIT\n   | NULLS_P\n   | OBJECT_P\n   | OF\n   | OFF\n   | OIDS\n   | OLD\n   | OPERATOR\n   | OPTION\n   | OPTIONS\n   | ORDINALITY\n   | OTHERS\n   | OVER\n   | OVERRIDING\n   | OWNED\n   | OWNER\n   | PARALLEL\n   | PARSER\n   | PARTIAL\n   | PARTITION\n   | PASSING\n   | PASSWORD\n   | PLANS\n   | POLICY\n   | PRECEDING\n   | PREPARE\n   | PREPARED\n   | PRESERVE\n   | PRIOR\n   | PRIVILEGES\n   | PROCEDURAL\n   | PROCEDURE\n   | PROCEDURES\n   | PROGRAM\n   | PUBLICATION\n   | QUOTE\n   | RANGE\n   | READ\n   | REASSIGN\n   | RECHECK\n   | RECURSIVE\n   | REF\n   | REFERENCING\n   | REFRESH\n   | REINDEX\n   | RELATIVE_P\n   | RELEASE\n   | RENAME\n   | REPEATABLE\n   | REPLICA\n   | RESET\n   | RESTART\n   | RESTRICT\n   | RETURNS\n   | REVOKE\n   | ROLE\n   | ROLLBACK\n   | ROLLUP\n   | ROUTINE\n   | ROUTINES\n   | ROWS\n   | RULE\n   | SAVEPOINT\n   | SCHEMA\n   | SCHEMAS\n   | SCROLL\n   | SEARCH\n   | SECOND_P\n   | SECURITY\n   | SEQUENCE\n   | SEQUENCES\n   | SERIALIZABLE\n   | SERVER\n   | SESSION\n   | SET\n   | SETS\n   | SHARE\n   | SHOW\n   | SIMPLE\n   | SKIP_P\n   | SNAPSHOT\n   | SQL_P\n   | STABLE\n   | STANDALONE_P\n   | START\n   | STATEMENT\n   | STATISTICS\n   | STDIN\n   | STDOUT\n   | STORAGE\n   | STORED\n   | STRICT_P\n   | STRIP_P\n   | SUBSCRIPTION\n   | SUPPORT\n   | SYSID\n   | SYSTEM_P\n   | TABLES\n   | TABLESPACE\n   | TEMP\n   | TEMPLATE\n   | TEMPORARY\n   | TEXT_P\n   | TIES\n   | TRANSACTION\n   | TRANSFORM\n   | TRIGGER\n   | TRUNCATE\n   | TRUSTED\n   | TYPE_P\n   | TYPES_P\n   | UESCAPE\n   | UNBOUNDED\n   | UNCOMMITTED\n   | UNENCRYPTED\n   | UNKNOWN\n   | UNLISTEN\n   | UNLOGGED\n   | UNTIL\n   | UPDATE\n   | VACUUM\n   | VALID\n   | VALIDATE\n   | VALIDATOR\n   | VALUE_P\n   | VARYING\n   | VERSION_P\n   | VIEW\n   | VIEWS\n   | VOLATILE\n   | WHITESPACE_P\n   | WITHIN\n   | WITHOUT\n   | WORK\n   | WRAPPER\n   | WRITE\n   | XML_P\n   | YEAR_P\n   | YES_P\n   | ZONE\n   ;\n\ncol_name_keyword\n   : BETWEEN\n   | BIGINT\n   | bit\n   | BOOLEAN_P\n   | CHAR_P\n   | character\n   | COALESCE\n   | DEC\n   | DECIMAL_P\n   | EXISTS\n   | EXTRACT\n   | FLOAT_P\n   | GREATEST\n   | GROUPING\n   | INOUT\n   | INT_P\n   | INTEGER\n   | INTERVAL\n   | LEAST\n   | NATIONAL\n   | NCHAR\n   | NONE\n   | NORMALIZE\n   | NULLIF\n   | numeric\n   | OUT_P\n   | OVERLAY\n   | POSITION\n   | PRECISION\n   | REAL\n   | ROW\n   | SETOF\n   | SMALLINT\n   | SUBSTRING\n   | TIME\n   | TIMESTAMP\n   | TREAT\n   | TRIM\n   | VALUES\n   | VARCHAR\n   | XMLATTRIBUTES\n   | XMLCONCAT\n   | XMLELEMENT\n   | XMLEXISTS\n   | XMLFOREST\n   | XMLNAMESPACES\n   | XMLPARSE\n   | XMLPI\n   | XMLROOT\n   | XMLSERIALIZE\n   | XMLTABLE\n   | builtin_function_name\n   ;\n\ntype_func_name_keyword\n   : AUTHORIZATION\n   | BINARY\n   | COLLATION\n   | CONCURRENTLY\n   | CROSS\n   | CURRENT_SCHEMA\n   | FREEZE\n   | FULL\n   | ILIKE\n   | INNER_P\n   | IS\n   | ISNULL\n   | JOIN\n   | LIKE\n   | NATURAL\n   | NOTNULL\n   | OUTER_P\n   | OVERLAPS\n   | SIMILAR\n   | TABLESAMPLE\n   | VERBOSE\n   ;\n\nreserved_keyword\n   : ALL\n   | ANALYSE\n   | ANALYZE\n   | AND\n   | ANY\n   | ARRAY\n   | AS\n   | ASC\n   | ASYMMETRIC\n   | BOTH\n   | CASE\n   | CAST\n   | CHECK\n   | COLLATE\n   | COLUMN\n   | CONSTRAINT\n   | CREATE\n   | CURRENT_CATALOG\n   | CURRENT_DATE\n   | CURRENT_ROLE\n   | CURRENT_TIME\n   | CURRENT_TIMESTAMP\n   | CURRENT_USER\n   //                 | DEFAULT\n   | DEFERRABLE\n   | DESC\n   | DISTINCT\n   | DO\n   | ELSE\n   | END_P\n   | EXCEPT\n   | FALSE_P\n   | FETCH\n   | FOR\n   | FOREIGN\n   | FROM\n   | GRANT\n   | GROUP_P\n   | HAVING\n   | IN_P\n   | INITIALLY\n   | INTERSECT\n/*\nfrom pl_gram.y, line ~2982\n\t * Fortunately, INTO is a fully reserved word in the main grammar, so\n\t * at least we need not worry about it appearing as an identifier.\n*/\n\n\n   //                 | INTO\n   | LATERAL_P\n   | LEADING\n   | LIMIT\n   | LOCALTIME\n   | LOCALTIMESTAMP\n   | NOT\n   | NULL_P\n   | OFFSET\n   | ON\n   | ONLY\n   | OR\n   | ORDER\n   | PLACING\n   | PRIMARY\n   | REFERENCES\n   | RETURNING\n   | SELECT\n   | SESSION_USER\n   | SOME\n   | SYMMETRIC\n   | TABLE\n   | THEN\n   | TO\n   | TRAILING\n   | TRUE_P\n   | UNION\n   | UNIQUE\n   | USER\n   | USING\n   | VARIADIC\n   | WHEN\n   | WHERE\n   | WINDOW\n   | WITH\n   ;\n\nbuiltin_function_name\n   : XMLCOMMENT\n   | XML_IS_WELL_FORMED\n   | XML_IS_WELL_FORMED_DOCUMENT\n   | XML_IS_WELL_FORMED_CONTENT\n   | XMLAGG\n   | XPATH\n   | XPATH_EXISTS\n   | ABS\n   | CBRT\n   | CEIL\n   | CEILING\n   | DEGREES\n   | DIV\n   | EXP\n   | FACTORIAL\n   | FLOOR\n   | GCD\n   | LCM\n   | LN\n   | LOG\n   | LOG10\n   | MIN_SCALE\n   | MOD\n   | PI\n   | POWER\n   | RADIANS\n   | ROUND\n   | SCALE\n   | SIGN\n   | SQRT\n   | TRIM_SCALE\n   | TRUNC\n   | WIDTH_BUCKET\n   | RANDOM\n   | SETSEED\n   | ACOS\n   | ACOSD\n   | ACOSH\n   | ASIN\n   | ASIND\n   | ASINH\n   | ATAN\n   | ATAND\n   | ATANH\n   | ATAN2\n   | ATAN2D\n   | COS\n   | COSD\n   | COSH\n   | COT\n   | COTD\n   | SIN\n   | SIND\n   | SINH\n   | TAN\n   | TAND\n   | TANH\n   | BIT_LENGTH\n   | CHAR_LENGTH\n   | CHARACTER_LENGTH\n   | LOWER\n   | OCTET_LENGTH\n   | OCTET_LENGTH\n   | UPPER\n   | ASCII\n   | BTRIM\n   | CHR\n   | CONCAT\n   | CONCAT_WS\n   | FORMAT\n   | INITCAP\n   | LENGTH\n   | LPAD\n   | LTRIM\n   | MD5\n   | PARSE_IDENT\n   | PG_CLIENT_ENCODING\n   | QUOTE_IDENT\n   | QUOTE_LITERAL\n   | QUOTE_NULLABLE\n   | REGEXP_COUNT\n   | REGEXP_INSTR\n   | REGEXP_LIKE\n   | REGEXP_MATCH\n   | REGEXP_MATCHES\n   | REGEXP_REPLACE\n   | REGEXP_SPLIT_TO_ARRAY\n   | REGEXP_SPLIT_TO_TABLE\n   | REGEXP_SUBSTR\n   | REPEAT\n   | REPLACE\n   | REVERSE\n   | RPAD\n   | RTRIM\n   | SPLIT_PART\n   | STARTS_WITH\n   | STRING_TO_ARRAY\n   | STRING_TO_TABLE\n   | STRPOS\n   | SUBSTR\n   | TO_ASCII\n   | TO_HEX\n   | TRANSLATE\n   | UNISTR\n   | AGE\n   | DATE_BIN\n   | DATE_PART\n   | DATE_TRUNC\n   | ISFINITE\n   | JUSTIFY_DAYS\n   | JUSTIFY_HOURS\n   | JUSTIFY_INTERVAL\n   | MAKE_DATE\n   | MAKE_INTERVAL\n   | MAKE_TIME\n   | MAKE_TIMESTAMP\n   | MAKE_TIMESTAMPTZ\n   | CLOCK_TIMESTAMP\n   | NOW\n   | STATEMENT_TIMESTAMP\n   | TIMEOFDAY\n   | TRANSACTION_TIMESTAMP\n   | TO_TIMESTAMP\n   | JUSTIFY_INTERVAL\n   | JUSTIFY_INTERVAL\n   | TO_CHAR\n   | TO_DATE\n   | TO_NUMBER\n   ;\n\n/************************************************************************************************************************************************************/\n/*PL/SQL GRAMMAR */\n\n\n/*PLSQL grammar */\n\n/************************************************************************************************************************************************************/\npl_function\n   : comp_options pl_block opt_semi\n   ;\n\ncomp_options\n   : comp_option*\n   ;\n\ncomp_option\n   : sharp OPTION DUMP\n   | sharp PRINT_STRICT_PARAMS option_value\n   | sharp VARIABLE_CONFLICT ERROR\n   | sharp VARIABLE_CONFLICT USE_VARIABLE\n   | sharp VARIABLE_CONFLICT USE_COLUMN\n   ;\n\nsharp\n   : Operator\n   ;\n\noption_value\n   : sconst\n   | reserved_keyword\n   | plsql_unreserved_keyword\n   | unreserved_keyword\n   ;\n\nopt_semi\n   :\n   | SEMI\n   ;\n   // exception_sect means opt_exception_sect in original grammar, don't be confused!\n\npl_block\n   : decl_sect BEGIN_P proc_sect exception_sect END_P opt_label\n   ;\n\ndecl_sect\n   : opt_block_label (decl_start decl_stmts?)?\n   ;\n\ndecl_start\n   : DECLARE\n   ;\n\ndecl_stmts\n   : decl_stmt+\n   ;\n\nlabel_decl\n   : LESS_LESS any_identifier GREATER_GREATER\n   ;\n\ndecl_stmt\n   : decl_statement\n   | DECLARE\n   | label_decl\n   ;\n\ndecl_statement\n   : decl_varname\n     (\n          ALIAS FOR decl_aliasitem\n        | decl_const decl_datatype decl_collate decl_notnull decl_defval\n        | opt_scrollable CURSOR decl_cursor_args decl_is_for decl_cursor_query\n     ) SEMI\n   ;\n\nopt_scrollable\n   :\n   | NO SCROLL\n   | SCROLL\n   ;\n\ndecl_cursor_query\n   : selectstmt\n   ;\n\ndecl_cursor_args\n   :\n   | OPEN_PAREN decl_cursor_arglist CLOSE_PAREN\n   ;\n\ndecl_cursor_arglist\n   : decl_cursor_arg (COMMA decl_cursor_arg)*\n   ;\n\ndecl_cursor_arg\n   : decl_varname decl_datatype\n   ;\n\ndecl_is_for\n   : IS\n   | FOR\n   ;\n\ndecl_aliasitem\n   : PARAM\n   | colid\n   ;\n\ndecl_varname\n   : any_identifier\n   ;\n\ndecl_const\n   :\n   | CONSTANT\n   ;\n\ndecl_datatype\n   : typename\n   ; //TODO: $$ = read_datatype(yychar);\n\ndecl_collate\n   :\n   | COLLATE any_name\n   ;\n\ndecl_notnull\n   :\n   | NOT NULL_P\n   ;\n\ndecl_defval\n   :\n   | decl_defkey sql_expression\n   ;\n\ndecl_defkey\n   : assign_operator\n   | DEFAULT\n   ;\n\nassign_operator\n   : EQUAL\n   | COLON_EQUALS\n   ;\n\nproc_sect\n   : proc_stmt*\n   ;\n\nproc_stmt\n   : pl_block SEMI\n   | stmt_return\n   | stmt_raise\n   | stmt_assign\n   | stmt_if\n   | stmt_case\n   | stmt_loop\n   | stmt_while\n   | stmt_for\n   | stmt_foreach_a\n   | stmt_exit\n   | stmt_assert\n   | stmt_execsql\n   | stmt_dynexecute\n   | stmt_perform\n   | stmt_call\n   | stmt_getdiag\n   | stmt_open\n   | stmt_fetch\n   | stmt_move\n   | stmt_close\n   | stmt_null\n   | stmt_commit\n   | stmt_rollback\n   | stmt_set\n   ;\n\nstmt_perform\n   : PERFORM expr_until_semi SEMI\n   ;\n\nstmt_call\n   : CALL any_identifier OPEN_PAREN opt_expr_list CLOSE_PAREN SEMI\n   | DO any_identifier OPEN_PAREN opt_expr_list CLOSE_PAREN SEMI\n   ;\n\nopt_expr_list\n   :\n   | expr_list\n   ;\n\nstmt_assign\n   : assign_var assign_operator sql_expression SEMI\n   ;\n\nstmt_getdiag\n   : GET getdiag_area_opt DIAGNOSTICS getdiag_list SEMI\n   ;\n\ngetdiag_area_opt\n   :\n   | CURRENT_P\n   | STACKED\n   ;\n\ngetdiag_list\n   : getdiag_list_item (COMMA getdiag_list_item)*\n   ;\n\ngetdiag_list_item\n   : getdiag_target assign_operator getdiag_item\n   ;\n\ngetdiag_item\n   : colid\n   ;\n\ngetdiag_target\n   : assign_var\n   ;\n\nassign_var\n   : (any_name | PARAM) (OPEN_BRACKET expr_until_rightbracket CLOSE_BRACKET)*\n   ;\n\nstmt_if\n   : IF_P expr_until_then THEN proc_sect stmt_elsifs stmt_else END_P IF_P SEMI\n   ;\n\nstmt_elsifs\n   : (ELSIF a_expr THEN proc_sect)*\n   ;\n\nstmt_else\n   :\n   | ELSE proc_sect\n   ;\n\nstmt_case\n   : CASE opt_expr_until_when case_when_list opt_case_else END_P CASE SEMI\n   ;\n\nopt_expr_until_when\n   :\n   | sql_expression\n   ;\n\ncase_when_list\n   : case_when+\n   ;\n\ncase_when\n   : WHEN expr_list THEN proc_sect\n   ;\n\nopt_case_else\n   :\n   | ELSE proc_sect\n   ;\n\nstmt_loop\n   : opt_loop_label loop_body\n   ;\n\nstmt_while\n   : opt_loop_label WHILE expr_until_loop loop_body\n   ;\n\nstmt_for\n   : opt_loop_label FOR for_control loop_body\n   ;\n   //TODO: rewrite using read_sql_expression logic?\n\nfor_control\n   : for_variable IN_P\n     (\n          cursor_name opt_cursor_parameters\n        | selectstmt\n        | explainstmt\n        | EXECUTE a_expr opt_for_using_expression\n        | opt_reverse a_expr DOT_DOT a_expr opt_by_expression\n     )\n   ;\n\nopt_for_using_expression\n   :\n   | USING expr_list\n   ;\n\nopt_cursor_parameters\n   :\n   | OPEN_PAREN a_expr (COMMA a_expr)* CLOSE_PAREN\n   ;\n\nopt_reverse\n   :\n   | REVERSE\n   ;\n\nopt_by_expression\n   :\n   | BY a_expr\n   ;\n\nfor_variable\n   : any_name_list\n   ;\n\nstmt_foreach_a\n   : opt_loop_label FOREACH for_variable foreach_slice IN_P ARRAY a_expr loop_body\n   ;\n\nforeach_slice\n   :\n   | SLICE iconst\n   ;\n\nstmt_exit\n   : exit_type opt_label opt_exitcond SEMI\n   ;\n\nexit_type\n   : EXIT\n   | CONTINUE_P\n   ;\n   //todo implement RETURN statement according to initial grammar line 1754\n\nstmt_return\n   : RETURN (NEXT sql_expression | QUERY (EXECUTE a_expr opt_for_using_expression | selectstmt) | opt_return_result) SEMI\n   ;\n\nopt_return_result\n   :\n   | sql_expression\n   ;\n   //https://www.postgresql.org/docs/current/plpgsql-errors-and-messages.html\n\n   //RAISE [ level ] 'format' [, expression [, ... ]] [ USING option = expression [, ... ] ];\n\n   //RAISE [ level ] condition_name [ USING option = expression [, ... ] ];\n\n   //RAISE [ level ] SQLSTATE 'sqlstate' [ USING option = expression [, ... ] ];\n\n   //RAISE [ level ] USING option = expression [, ... ];\n\n   //RAISE ;\n\nstmt_raise\n   : RAISE opt_stmt_raise_level sconst opt_raise_list opt_raise_using SEMI\n   | RAISE opt_stmt_raise_level identifier opt_raise_using SEMI\n   | RAISE opt_stmt_raise_level SQLSTATE sconst opt_raise_using SEMI\n   | RAISE opt_stmt_raise_level opt_raise_using SEMI\n   | RAISE\n   ;\n\nopt_stmt_raise_level\n   :\n   |\n   | DEBUG\n   | LOG\n   | INFO\n   | NOTICE\n   | WARNING\n   | EXCEPTION\n   ;\n\nopt_raise_list\n   :\n   | (COMMA a_expr)+\n   ;\n\nopt_raise_using\n   :\n   | USING opt_raise_using_elem_list\n   ;\n\nopt_raise_using_elem\n   : identifier EQUAL a_expr\n   ;\n\nopt_raise_using_elem_list\n   : opt_raise_using_elem (COMMA opt_raise_using_elem)*\n   ;\n   //todo imnplement\n\nstmt_assert\n   : ASSERT sql_expression opt_stmt_assert_message SEMI\n   ;\n\nopt_stmt_assert_message\n   :\n   | COMMA sql_expression\n   ;\n\nloop_body\n   : LOOP proc_sect END_P LOOP opt_label SEMI\n   ;\n   //TODO: looks like all other statements like INSERT/SELECT/UPDATE/DELETE are handled here;\n\n   //pls take a look at original grammar\n\nstmt_execsql\n   : make_execsql_stmt SEMI\n/*K_IMPORT\n            | K_INSERT\n            | t_word\n            | t_cword\n*/\n\n\n   ;\n   //https://www.postgresql.org/docs/current/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-NORESULT\n\n   //EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];\n\nstmt_dynexecute\n   : EXECUTE a_expr (\n/*this is silly, but i have to time to find nice way to code */\n\n   opt_execute_into opt_execute_using | opt_execute_using opt_execute_into |) SEMI\n   ;\n\nopt_execute_using\n   :\n   | USING opt_execute_using_list\n   ;\n\nopt_execute_using_list\n   : a_expr (COMMA a_expr)*\n   ;\n\nopt_execute_into\n   :\n   | INTO STRICT_P? into_target\n   ;\n   //https://www.postgresql.org/docs/current/plpgsql-cursors.html#PLPGSQL-CURSOR-OPENING\n\n   //OPEN unbound_cursorvar [ [ NO ] SCROLL ] FOR query;\n\n   //OPEN unbound_cursorvar [ [ NO ] SCROLL ] FOR EXECUTE query_string\n\n   //                                     [ USING expression [, ... ] ];\n\n   //OPEN bound_cursorvar [ ( [ argument_name := ] argument_value [, ...] ) ];\n\nstmt_open\n   : OPEN\n     (\n          cursor_variable opt_scroll_option FOR (selectstmt | EXECUTE sql_expression opt_open_using)\n        | colid (OPEN_PAREN opt_open_bound_list CLOSE_PAREN)?\n     ) SEMI\n   ;\n\nopt_open_bound_list_item\n   : colid COLON_EQUALS a_expr\n   | a_expr\n   ;\n\nopt_open_bound_list\n   : opt_open_bound_list_item (COMMA opt_open_bound_list_item)*\n   ;\n\nopt_open_using\n   :\n   | USING expr_list\n   ;\n\nopt_scroll_option\n   :\n   | opt_scroll_option_no SCROLL\n   ;\n\nopt_scroll_option_no\n   :\n   | NO\n   ;\n   //https://www.postgresql.org/docs/current/plpgsql-cursors.html#PLPGSQL-CURSOR-OPENING\n\n   //FETCH [ direction { FROM | IN } ] cursor INTO target;\n\nstmt_fetch\n   : FETCH direction = opt_fetch_direction opt_cursor_from cursor_variable INTO into_target SEMI\n   ;\n\ninto_target\n   : expr_list\n   ;\n\nopt_cursor_from\n   :\n   | FROM\n   | IN_P\n   ;\n\nopt_fetch_direction\n   :\n   |\n   | NEXT\n   | PRIOR\n   | FIRST_P\n   | LAST_P\n   | ABSOLUTE_P a_expr\n   | RELATIVE_P a_expr\n   | a_expr\n   | ALL\n   | (FORWARD | BACKWARD) (a_expr | ALL)?\n   ;\n   //https://www.postgresql.org/docs/current/plpgsql-cursors.html#PLPGSQL-CURSOR-OPENING\n\n   //MOVE [ direction { FROM | IN } ] cursor;\n\nstmt_move\n   : MOVE opt_fetch_direction cursor_variable SEMI\n   ;\n\nstmt_close\n   : CLOSE cursor_variable SEMI\n   ;\n\nstmt_null\n   : NULL_P SEMI\n   ;\n\nstmt_commit\n   : COMMIT plsql_opt_transaction_chain SEMI\n   ;\n\nstmt_rollback\n   : ROLLBACK plsql_opt_transaction_chain SEMI\n   ;\n\nplsql_opt_transaction_chain\n   : AND NO? CHAIN\n   |\n   ;\n\nstmt_set\n   : SET any_name TO DEFAULT SEMI\n   | RESET (any_name | ALL) SEMI\n   ;\n\ncursor_variable\n   : colid\n   | PARAM\n   ;\n\nexception_sect\n   :\n   | EXCEPTION proc_exceptions\n   ;\n\nproc_exceptions\n   : proc_exception+\n   ;\n\nproc_exception\n   : WHEN proc_conditions THEN proc_sect\n   ;\n\nproc_conditions\n   : proc_condition (OR proc_condition)*\n   ;\n\nproc_condition\n   : any_identifier\n   | SQLSTATE sconst\n   ;\n   //expr_until_semi:\n\n   //;\n\n   //expr_until_rightbracket:\n\n   //;\n\n   //expr_until_loop:\n\n   //;\n\nopt_block_label\n   :\n   | label_decl\n   ;\n\nopt_loop_label\n   :\n   | label_decl\n   ;\n\nopt_label\n   :\n   | any_identifier\n   ;\n\nopt_exitcond\n   : WHEN expr_until_semi\n   |\n   ;\n\nany_identifier\n   : colid\n   | plsql_unreserved_keyword\n   ;\n\nplsql_unreserved_keyword\n   : ABSOLUTE_P\n   | ALIAS\n   | AND\n   | ARRAY\n   | ASSERT\n   | BACKWARD\n   | CALL\n   | CHAIN\n   | CLOSE\n   | COLLATE\n   | COLUMN\n   //| COLUMN_NAME\n   | COMMIT\n   | CONSTANT\n   | CONSTRAINT\n   //| CONSTRAINT_NAME\n   | CONTINUE_P\n   | CURRENT_P\n   | CURSOR\n   //| DATATYPE\n   | DEBUG\n   | DEFAULT\n   //| DETAIL\n   | DIAGNOSTICS\n   | DO\n   | DUMP\n   | ELSIF\n   //| ERRCODE\n   | ERROR\n   | EXCEPTION\n   | EXIT\n   | FETCH\n   | FIRST_P\n   | FORWARD\n   | GET\n   //| HINT\n\n   //| IMPORT\n   | INFO\n   | INSERT\n   | IS\n   | LAST_P\n   //| MESSAGE\n\n   //| MESSAGE_TEXT\n   | MOVE\n   | NEXT\n   | NO\n   | NOTICE\n   | OPEN\n   | OPTION\n   | PERFORM\n   //| PG_CONTEXT\n\n   //| PG_DATATYPE_NAME\n\n   //| PG_EXCEPTION_CONTEXT\n\n   //| PG_EXCEPTION_DETAIL\n\n   //| PG_EXCEPTION_HINT\n   | PRINT_STRICT_PARAMS\n   | PRIOR\n   | QUERY\n   | RAISE\n   | RELATIVE_P\n   | RESET\n   | RETURN\n   //| RETURNED_SQLSTATE\n   | ROLLBACK\n   //| ROW_COUNT\n   | ROWTYPE\n   | SCHEMA\n   //| SCHEMA_NAME\n   | SCROLL\n   | SET\n   | SLICE\n   | SQLSTATE\n   | STACKED\n   | TABLE\n   //| TABLE_NAME\n   | TYPE_P\n   | USE_COLUMN\n   | USE_VARIABLE\n   | VARIABLE_CONFLICT\n   | WARNING\n   | OUTER_P\n   ;\n\nsql_expression\n   : opt_target_list into_clause from_clause where_clause group_clause having_clause window_clause\n   ;\n\nexpr_until_then\n   : sql_expression\n   ;\n\nexpr_until_semi\n   : sql_expression\n   ;\n\nexpr_until_rightbracket\n   : a_expr\n   ;\n\nexpr_until_loop\n   : a_expr\n   ;\n\nmake_execsql_stmt\n   : stmt opt_returning_clause_into\n   ;\n\nopt_returning_clause_into\n   : INTO opt_strict into_target\n   |\n   ;"
  },
  {
    "path": "superior-redshift-parser/src/main/java/io/github/melin/superior/parser/redshift/antlr4/LexerDispatchingErrorListener.java",
    "content": "package io.github.melin.superior.parser.redshift.antlr4;\n\nimport java.util.BitSet;\nimport org.antlr.v4.runtime.*;\nimport org.antlr.v4.runtime.atn.*;\nimport org.antlr.v4.runtime.dfa.*;\n\npublic class LexerDispatchingErrorListener implements ANTLRErrorListener {\n    Lexer _parent;\n\n    public LexerDispatchingErrorListener(Lexer parent) {\n        _parent = parent;\n    }\n\n    public void syntaxError(\n            Recognizer<?, ?> recognizer,\n            Object offendingSymbol,\n            int line,\n            int charPositionInLine,\n            String msg,\n            RecognitionException e) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);\n    }\n\n    public void reportAmbiguity(\n            Parser recognizer,\n            DFA dfa,\n            int startIndex,\n            int stopIndex,\n            boolean exact,\n            BitSet ambigAlts,\n            ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs);\n    }\n\n    public void reportAttemptingFullContext(\n            Parser recognizer, DFA dfa, int startIndex, int stopIndex, BitSet conflictingAlts, ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs);\n    }\n\n    public void reportContextSensitivity(\n            Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs);\n    }\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/java/io/github/melin/superior/parser/redshift/antlr4/ParserDispatchingErrorListener.java",
    "content": "package io.github.melin.superior.parser.redshift.antlr4;\n\nimport java.util.BitSet;\nimport org.antlr.v4.runtime.*;\nimport org.antlr.v4.runtime.atn.*;\nimport org.antlr.v4.runtime.dfa.*;\n\npublic class ParserDispatchingErrorListener implements ANTLRErrorListener {\n    Parser _parent;\n\n    public ParserDispatchingErrorListener(Parser parent) {\n        _parent = parent;\n    }\n\n    public void syntaxError(\n            Recognizer<?, ?> recognizer,\n            Object offendingSymbol,\n            int line,\n            int charPositionInLine,\n            String msg,\n            RecognitionException e) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);\n    }\n\n    public void reportAmbiguity(\n            Parser recognizer,\n            DFA dfa,\n            int startIndex,\n            int stopIndex,\n            boolean exact,\n            BitSet ambigAlts,\n            ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs);\n    }\n\n    public void reportAttemptingFullContext(\n            Parser recognizer, DFA dfa, int startIndex, int stopIndex, BitSet conflictingAlts, ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs);\n    }\n\n    public void reportContextSensitivity(\n            Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, ATNConfigSet configs) {\n        ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());\n        foo.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs);\n    }\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/java/io/github/melin/superior/parser/redshift/antlr4/RedshiftLexerBase.java",
    "content": "package io.github.melin.superior.parser.redshift.antlr4;\n\nimport java.util.ArrayDeque;\nimport java.util.Deque;\nimport org.antlr.v4.runtime.CharStream;\nimport org.antlr.v4.runtime.Lexer;\n\npublic abstract class RedshiftLexerBase extends Lexer {\n    protected final Deque<String> tags = new ArrayDeque<>();\n\n    protected RedshiftLexerBase(CharStream input) {\n        super(input);\n    }\n\n    public void pushTag() {\n        tags.push(getText());\n    }\n\n    public boolean isTag() {\n        return getText().equals(tags.peek());\n    }\n\n    public void popTag() {\n        tags.pop();\n    }\n\n    public boolean checkLA(int c) {\n        return getInputStream().LA(1) != c;\n    }\n\n    public boolean charIsLetter() {\n        return Character.isLetter(getInputStream().LA(-1));\n    }\n\n    public void HandleNumericFail() {\n        getInputStream().seek(getInputStream().index() - 2);\n        setType(RedshiftLexer.Integral);\n    }\n\n    public void HandleLessLessGreaterGreater() {\n        if (getText() == \"<<\") setType(RedshiftLexer.LESS_LESS);\n        if (getText() == \">>\") setType(RedshiftLexer.GREATER_GREATER);\n    }\n\n    public void UnterminatedBlockCommentDebugAssert() {\n        // Debug.Assert(InputStream.LA(1) == -1 /*EOF*/);\n    }\n\n    public boolean CheckIfUtf32Letter() {\n        int codePoint = getInputStream().LA(-2) << 8 + getInputStream().LA(-1);\n        char[] c;\n        if (codePoint < 0x10000) {\n            c = new char[] {(char) codePoint};\n        } else {\n            codePoint -= 0x10000;\n            c = new char[] {(char) (codePoint / 0x400 + 0xd800), (char) (codePoint % 0x400 + 0xdc00)};\n        }\n        return Character.isLetter(c[0]);\n    }\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/java/io/github/melin/superior/parser/redshift/antlr4/RedshiftParserBase.java",
    "content": "package io.github.melin.superior.parser.redshift.antlr4;\n\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream;\nimport java.util.List;\nimport org.antlr.v4.runtime.*;\nimport org.apache.commons.lang3.StringUtils;\n\npublic abstract class RedshiftParserBase extends Parser {\n\n    public RedshiftParserBase(TokenStream input) {\n        super(input);\n    }\n\n    ParserRuleContext GetParsedSqlTree(String script, int line) {\n        RedshiftParser ph = getPostgreSQLParser(script);\n        ParserRuleContext result = ph.root();\n        return result;\n    }\n\n    public void ParseRoutineBody(RedshiftParser.Createfunc_opt_listContext _localctx) {\n        String lang = null;\n        for (RedshiftParser.Createfunc_opt_itemContext coi : _localctx.createfunc_opt_item()) {\n            if (coi.LANGUAGE() != null) {\n                if (coi.nonreservedword_or_sconst() != null)\n                    if (coi.nonreservedword_or_sconst().nonreservedword() != null)\n                        if (coi.nonreservedword_or_sconst().nonreservedword().identifier() != null)\n                            if (coi.nonreservedword_or_sconst()\n                                            .nonreservedword()\n                                            .identifier()\n                                            .Identifier()\n                                    != null) {\n                                lang = coi.nonreservedword_or_sconst()\n                                        .nonreservedword()\n                                        .identifier()\n                                        .Identifier()\n                                        .getText();\n                                break;\n                            }\n            }\n        }\n        if (null == lang) return;\n        RedshiftParser.Createfunc_opt_itemContext func_as = null;\n        for (RedshiftParser.Createfunc_opt_itemContext a : _localctx.createfunc_opt_item()) {\n            if (a.func_as() != null) {\n                func_as = a;\n                break;\n            }\n        }\n        if (func_as != null) {\n            String txt = GetRoutineBodyString(func_as.func_as().sconst(0));\n            RedshiftParser ph = getPostgreSQLParser(StringUtils.trim(txt));\n            switch (lang) {\n                case \"plpgsql\":\n                    func_as.func_as().Definition = ph.sqlroot();\n                    break;\n                case \"sql\":\n                    func_as.func_as().Definition = ph.root();\n                    break;\n            }\n        }\n    }\n\n    private String TrimQuotes(String s) {\n        return (s == null || s.isEmpty()) ? s : s.substring(1, s.length() - 1);\n    }\n\n    public String unquote(String s) {\n        int slength = s.length();\n        StringBuilder r = new StringBuilder(slength);\n        int i = 0;\n        while (i < slength) {\n            Character c = s.charAt(i);\n            r.append(c);\n            if (c == '\\'' && i < slength - 1 && (s.charAt(i + 1) == '\\'')) i++;\n            i++;\n        }\n        return r.toString();\n    }\n\n    public String GetRoutineBodyString(RedshiftParser.SconstContext rule) {\n        RedshiftParser.AnysconstContext anysconst = rule.anysconst();\n        org.antlr.v4.runtime.tree.TerminalNode StringConstant = anysconst.StringConstant();\n        if (null != StringConstant) return unquote(TrimQuotes(StringConstant.getText()));\n        org.antlr.v4.runtime.tree.TerminalNode UnicodeEscapeStringConstant = anysconst.UnicodeEscapeStringConstant();\n        if (null != UnicodeEscapeStringConstant) return TrimQuotes(UnicodeEscapeStringConstant.getText());\n        org.antlr.v4.runtime.tree.TerminalNode EscapeStringConstant = anysconst.EscapeStringConstant();\n        if (null != EscapeStringConstant) return TrimQuotes(EscapeStringConstant.getText());\n        String result = \"\";\n        List<org.antlr.v4.runtime.tree.TerminalNode> dollartext = anysconst.DollarText();\n        for (org.antlr.v4.runtime.tree.TerminalNode s : dollartext) {\n            result += s.getText();\n        }\n        return result;\n    }\n\n    public RedshiftParser getPostgreSQLParser(String script) {\n        UpperCaseCharStream charStream = new UpperCaseCharStream(CharStreams.fromString(script));\n        Lexer lexer = new RedshiftLexer(charStream);\n        CommonTokenStream tokens = new CommonTokenStream(lexer);\n        RedshiftParser parser = new RedshiftParser(tokens);\n        lexer.removeErrorListeners();\n        parser.removeErrorListeners();\n        LexerDispatchingErrorListener listener_lexer = new LexerDispatchingErrorListener(\n                (Lexer) (((CommonTokenStream) (this.getInputStream())).getTokenSource()));\n        ParserDispatchingErrorListener listener_parser = new ParserDispatchingErrorListener(this);\n        lexer.addErrorListener(listener_lexer);\n        parser.addErrorListener(listener_parser);\n        return parser;\n    }\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/AbstractSqlParser.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.redshift.antlr4.RedshiftParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(RedshiftParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: RedshiftParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(RedshiftParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/RedshiftSqlAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport com.google.common.collect.Lists\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.AlterActionType.*\nimport io.github.melin.superior.common.StatementType.*\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.*\nimport io.github.melin.superior.common.relational.alter.*\nimport io.github.melin.superior.common.relational.common.CommentStatement\nimport io.github.melin.superior.common.relational.common.RefreshMaterializedView\nimport io.github.melin.superior.common.relational.common.ShowStatement\nimport io.github.melin.superior.common.relational.create.*\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.drop.DropDatabase\nimport io.github.melin.superior.common.relational.drop.DropMaterializedView\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport io.github.melin.superior.common.relational.drop.DropView\nimport io.github.melin.superior.common.relational.table.ColumnRel\nimport io.github.melin.superior.common.relational.table.TruncateTable\nimport io.github.melin.superior.parser.postgre.relational.CreatePartitionTable\nimport io.github.melin.superior.parser.redshift.antlr4.RedshiftParser\nimport io.github.melin.superior.parser.redshift.antlr4.RedshiftParser.SqlrootContext\nimport io.github.melin.superior.parser.redshift.antlr4.RedshiftParserBaseVisitor\nimport org.antlr.v4.runtime.tree.RuleNode\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2020/6/30 9:57 上午 */\nclass RedshiftSqlAntlr4Visitor(val splitSql: Boolean = false) :\n    RedshiftParserBaseVisitor<Statement>() {\n\n    private var currentOptType: StatementType = StatementType.UNKOWN\n\n    private var limit: Int? = null\n    private var offset: Int? = null\n    private var inputTables: ArrayList<TableId> = arrayListOf()\n    private var outputTables: ArrayList<TableId> = arrayListOf()\n    private var cteTempTables: ArrayList<TableId> = arrayListOf()\n\n    // 多语句解析结果\n    private var statements: ArrayList<Statement> = arrayListOf()\n    // 存储过程和函数中包含的子语句\n    private var childStatements: ArrayList<Statement> = arrayListOf()\n    private val sqls: ArrayList<String> = arrayListOf()\n\n    fun getSqlStatements(): List<Statement> {\n        return statements\n    }\n\n    fun getSplitSqls(): List<String> {\n        return sqls\n    }\n\n    override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {\n        return if (currentResult == null) true else false\n    }\n\n    override fun visitDecl_cursor_query(ctx: RedshiftParser.Decl_cursor_queryContext): Statement? {\n        val statement = visitSelectstmt(ctx.selectstmt())\n        statement.setSql(source(ctx))\n        childStatements.add(statement)\n        return null\n    }\n\n    override fun visitStmtmulti(ctx: RedshiftParser.StmtmultiContext): Statement? {\n        ctx.stmt().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else {\n                        var statement = this.visitStmt(it)\n                        if (statement == null) {\n                            statement = DefaultStatement(StatementType.UNKOWN)\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n                currentOptType = StatementType.UNKOWN\n                clean()\n            }\n        }\n        return null\n    }\n\n    override fun visitStmt(ctx: RedshiftParser.StmtContext): Statement? {\n        val stmt: Statement? = super.visitStmt(ctx)\n        if (stmt != null) {\n            if (currentOptType != CREATE_FUNCTION && currentOptType != CREATE_PROCEDURE) {\n                stmt.setSql(source(ctx))\n                childStatements.add(stmt)\n            }\n        }\n        clean()\n        return stmt\n    }\n\n    private fun clean() {\n        currentOptType = StatementType.UNKOWN\n\n        limit = null\n        offset = null\n        inputTables = arrayListOf()\n        outputTables = arrayListOf()\n        cteTempTables = arrayListOf()\n    }\n\n    private fun addOutputTableId(tableId: TableId) {\n        if (!outputTables.contains(tableId)) {\n            outputTables.add(tableId)\n        }\n    }\n\n    // -----------------------------------database-------------------------------------------------\n\n    override fun visitCreatedbstmt(ctx: RedshiftParser.CreatedbstmtContext): Statement {\n        val databaseName = CommonUtils.cleanQuote(ctx.name().text)\n        return CreateDatabase(databaseName)\n    }\n\n    override fun visitDropdbstmt(ctx: RedshiftParser.DropdbstmtContext): Statement {\n        val databaseName = CommonUtils.cleanQuote(ctx.name().text)\n        return DropDatabase(databaseName)\n    }\n\n    // -----------------------------------schema-------------------------------------------------\n\n    override fun visitCreateschemastmt(ctx: RedshiftParser.CreateschemastmtContext): Statement {\n        val schemaName = CommonUtils.cleanQuote(ctx.colid().text)\n        return CreateSchema(schemaName)\n    }\n\n    // -----------------------------------table-------------------------------------------------\n\n    override fun visitCreatestmt(ctx: RedshiftParser.CreatestmtContext): Statement {\n        currentOptType = CREATE_TABLE\n\n        if (ctx.PARTITION() != null) {\n            val partitionTableId = parseTableName(ctx.qualified_name(0))\n            val tableId = parseTableName(ctx.qualified_name(1))\n            return CreatePartitionTable(tableId, partitionTableId)\n        }\n\n        val tableId = parseTableName(ctx.qualified_name(0))\n        val columns =\n            ctx.opttableelementlist()?.tableelementlist()?.tableelement()?.map {\n                val colDef = it.columnDef()\n                val colName = colDef.colid().text\n                val dataType = colDef.typename().text\n                val columnRel = ColumnRel(colName, dataType)\n\n                colDef.colquallist().colconstraint().forEach { colconstraint ->\n                    val child = colconstraint.getChild(0)\n                    if (child is RedshiftParser.ColconstraintelemContext) {\n                        if (child.NOT() != null) {\n                            columnRel.nullable = false\n                        } else if (child.PRIMARY() != null) {\n                            columnRel.primaryKey = true\n                        }\n                    }\n                }\n                columnRel\n            }\n\n        val createTable = CreateTable(tableId, TableType.POSTGRES, columnRels = columns)\n        if (ctx.opttemp().TEMP() != null || ctx.opttemp().TEMPORARY() != null) {\n            createTable.temporary = true\n        }\n\n        val partitionspec = ctx.optpartitionspec()?.partitionspec()\n        val tablePartition = ctx.gaussextension()?.tablePartition()\n        if (partitionspec != null) {\n            val partitionType = partitionspec.colid().text.uppercase()\n            val partitionColumns = partitionspec.part_params().part_elem().map { it.text }\n\n            createTable.partitionColumnNames.addAll(partitionColumns)\n            if (\"RANGE\" == partitionType) {\n                createTable.partitionType = PartitionType.RANGE\n            } else {\n\n                createTable.partitionType = PartitionType.LIST\n            }\n        } else if (tablePartition != null) {\n            var partitionType: PartitionType? = null\n            val partitionColumns = mutableListOf<String>()\n\n            val ptSpec = tablePartition.partition_list()\n            if (ptSpec.list_partition_stmt() != null) {\n                partitionType = PartitionType.LIST\n                partitionColumns.add(ptSpec.list_partition_stmt().partition_key().colid().text)\n            } else if (ptSpec.value_partition_stmt() != null) {\n                partitionType = PartitionType.VALUES\n                partitionColumns.add(ptSpec.value_partition_stmt().partition_key().colid().text)\n            } else if (ptSpec.range_partition_stmt() != null) {\n                partitionType = PartitionType.RANGE\n                partitionColumns.add(ptSpec.range_partition_stmt().partition_key().colid().text)\n            } else if (ptSpec.normal_partition_stmt() != null) {\n                partitionType = PartitionType.NORMAL\n            }\n\n            createTable.partitionColumnNames.addAll(partitionColumns)\n            createTable.partitionType = partitionType\n        }\n\n        return createTable\n    }\n\n    override fun visitFunc_as(ctx: RedshiftParser.Func_asContext): Statement? {\n        if (ctx.Definition != null) {\n            visitSqlroot(ctx.Definition as SqlrootContext)\n        }\n        return super.visitFunc_as(ctx)\n    }\n\n    override fun visitCreatefunctionstmt(ctx: RedshiftParser.CreatefunctionstmtContext): Statement {\n        currentOptType = if (ctx.FUNCTION() != null) CREATE_FUNCTION else CREATE_PROCEDURE\n        childStatements = arrayListOf()\n\n        val optItems = ctx.createfunc_opt_list().createfunc_opt_item()\n        if (optItems != null) {\n            optItems\n                .filter { it.func_as() != null && it.func_as().Definition != null }\n                .forEach { visitSqlroot(it.func_as().Definition as RedshiftParser.SqlrootContext) }\n        }\n\n        val replace = if (ctx.opt_or_replace().REPLACE() != null) true else false\n        val funcName = ctx.func_name()\n\n        if (ctx.FUNCTION() != null) {\n            val functionId =\n                if (funcName.type_function_name() != null) {\n                    FunctionId(funcName.text)\n                } else {\n                    FunctionId(funcName.colid().text, funcName.indirection().indirection_el()[0].attr_name().text)\n                }\n\n            currentOptType = if (ctx.FUNCTION() != null) CREATE_FUNCTION else CREATE_PROCEDURE\n            return CreateFunction(functionId, childStatements, replace)\n        } else {\n            val procedureId =\n                if (funcName.type_function_name() != null) {\n                    ProcedureId(funcName.text)\n                } else {\n                    ProcedureId(funcName.colid().text, funcName.indirection().indirection_el()[0].attr_name().text)\n                }\n\n            currentOptType = if (ctx.FUNCTION() != null) CREATE_FUNCTION else CREATE_PROCEDURE\n            return CreateProcedure(procedureId, childStatements, replace)\n        }\n    }\n\n    override fun visitProc_stmt(ctx: RedshiftParser.Proc_stmtContext): Statement? {\n        super.visitProc_stmt(ctx)\n        return null\n    }\n\n    override fun visitViewstmt(ctx: RedshiftParser.ViewstmtContext): Statement {\n        currentOptType = StatementType.CREATE_VIEW\n        val tableId = parseTableName(ctx.qualified_name())\n        val replace = if (ctx.REPLACE() != null) true else false\n        val queryStmt = this.visitSelectstmt(ctx.selectstmt()) as QueryStmt\n        val createView = CreateView(tableId, queryStmt)\n        createView.replace = replace\n\n        if (ctx.opttemp().TEMP() != null || ctx.opttemp().TEMPORARY() != null) {\n            createView.temporary = true\n        }\n        return createView\n    }\n\n    override fun visitCreatematviewstmt(ctx: RedshiftParser.CreatematviewstmtContext): Statement {\n        currentOptType = StatementType.CREATE_MATERIALIZED_VIEW\n        val tableId = parseTableName(ctx.create_mv_target().qualified_name())\n        val ifNotExists = if (ctx.IF_P() != null) true else false\n        val queryStmt = this.visitSelectstmt(ctx.selectstmt()) as QueryStmt\n        val createView = CreateMaterializedView(tableId, queryStmt)\n        createView.ifNotExists = ifNotExists\n        return createView\n    }\n\n    override fun visitRefreshmatviewstmt(ctx: RedshiftParser.RefreshmatviewstmtContext): Statement {\n        val tableId = parseTableName(ctx.qualified_name())\n        return RefreshMaterializedView(tableId)\n    }\n\n    override fun visitRenamestmt(ctx: RedshiftParser.RenamestmtContext): Statement? {\n        if (ctx.TABLE() != null) {\n            val tableId = parseTableName(ctx.qualified_name())\n            val newTable = ctx.name().get(0).text\n            val ifexists = ctx.EXISTS() != null\n            val action = RenameAction(TableId(newTable), ifexists)\n            return AlterTable(tableId, action)\n        } else if (ctx.VIEW() != null) {\n            if (ctx.MATERIALIZED() == null) {\n                val tableId = parseTableName(ctx.qualified_name())\n                val newTable = ctx.name().get(0).text\n                val ifexists = ctx.EXISTS() != null\n                val action = RenameAction(TableId(newTable), ifexists)\n                return AlterView(tableId, action)\n            } else {\n                val tableId = parseTableName(ctx.qualified_name())\n                val newTable = ctx.name().get(0).text\n                val ifexists = ctx.EXISTS() != null\n                val action = RenameAction(TableId(newTable), ifexists)\n                return AlterMaterializedView(tableId, action)\n            }\n        } else {\n\n            return null\n        }\n    }\n\n    override fun visitSelectstmt(ctx: RedshiftParser.SelectstmtContext): Statement {\n        currentOptType = StatementType.SELECT\n        super.visitSelectstmt(ctx)\n\n        return QueryStmt(inputTables, limit, offset)\n    }\n\n    override fun visitCreateasstmt(ctx: RedshiftParser.CreateasstmtContext): Statement {\n        currentOptType = StatementType.CREATE_TABLE_AS_SELECT\n        val tableId = parseTableName(ctx.create_as_target().qualified_name())\n        val queryStmt = this.visitSelectstmt(ctx.selectstmt()) as QueryStmt\n        val createTable = CreateTableAsSelect(tableId, queryStmt)\n        return createTable\n    }\n\n    override fun visitUpdatestmt(ctx: RedshiftParser.UpdatestmtContext): Statement {\n        currentOptType = StatementType.UPDATE\n        val tableId = parseTableName(ctx.relation_expr_opt_alias().relation_expr())\n        addOutputTableId(tableId)\n\n        super.visitWhere_or_current_clause(ctx.where_or_current_clause())\n        super.visitFrom_clause(ctx.from_clause())\n\n        return UpdateTable(tableId, inputTables)\n    }\n\n    override fun visitDeletestmt(ctx: RedshiftParser.DeletestmtContext): Statement {\n        currentOptType = StatementType.DELETE\n        val tableId = parseTableName(ctx.relation_expr_opt_alias().relation_expr())\n        addOutputTableId(tableId)\n\n        super.visitWhere_or_current_clause(ctx.where_or_current_clause())\n        super.visitUsing_clause(ctx.using_clause())\n\n        return DeleteTable(tableId, inputTables)\n    }\n\n    override fun visitInsertstmt(ctx: RedshiftParser.InsertstmtContext): Statement {\n        currentOptType = StatementType.INSERT\n        if (ctx.opt_with_clause() != null) {\n            this.visitOpt_with_clause(ctx.opt_with_clause())\n        }\n\n        val tableId = parseTableName(ctx.insert_target().qualified_name())\n        addOutputTableId(tableId)\n\n        val queryStmt = this.visitSelectstmt(ctx.insert_rest().selectstmt()) as QueryStmt\n        val insertTable = InsertTable(InsertMode.INTO, queryStmt, tableId)\n        insertTable.outputTables.addAll(outputTables.subList(1, outputTables.size))\n        return insertTable\n    }\n\n    override fun visitMergestmt(ctx: RedshiftParser.MergestmtContext): Statement {\n        currentOptType = StatementType.MERGE\n\n        val mergeTableId = parseTableName(ctx.qualified_name(0))\n        val mergeTable = MergeTable(mergeTableId)\n\n        if (ctx.qualified_name().size == 2) {\n            val tableId = parseTableName(ctx.qualified_name(1))\n            inputTables.add(tableId)\n        } else if (ctx.select_with_parens() != null) {\n            super.visitSelect_with_parens(ctx.select_with_parens())\n        }\n        mergeTable.inputTables = inputTables\n        return mergeTable\n    }\n\n    override fun visitCte_list(ctx: RedshiftParser.Cte_listContext): Statement {\n        ctx.common_table_expr().forEach { cteTempTables.add(TableId(it.name().text)) }\n        return super.visitCte_list(ctx)\n    }\n\n    override fun visitQualified_name(ctx: RedshiftParser.Qualified_nameContext): Statement? {\n        if (\n            currentOptType == StatementType.SELECT ||\n                currentOptType == StatementType.CREATE_VIEW ||\n                currentOptType == StatementType.CREATE_MATERIALIZED_VIEW ||\n                currentOptType == StatementType.CREATE_TABLE_AS_SELECT ||\n                currentOptType == StatementType.UPDATE ||\n                currentOptType == StatementType.DELETE ||\n                currentOptType == StatementType.MERGE ||\n                currentOptType == StatementType.INSERT ||\n                currentOptType == StatementType.CREATE_FUNCTION ||\n                currentOptType == StatementType.CREATE_PROCEDURE\n        ) {\n\n            if (ctx.parent is RedshiftParser.OpttempTableNameContext) {\n                return null\n            }\n\n            val tableId = parseTableName(ctx)\n\n            if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {\n                inputTables.add(tableId)\n            }\n            return null\n        } else {\n            throw SQLParserException(\"not support\")\n        }\n    }\n\n    // create index\n    override fun visitIndexstmt(ctx: RedshiftParser.IndexstmtContext): Statement {\n        val tableId = parseTableName(ctx.relation_expr())\n        val indexName =\n            if (ctx.opt_index_name() != null) {\n                ctx.opt_index_name().text\n            } else {\n                ctx.name().text\n            }\n        val createIndex = CreateIndex(indexName)\n        return AlterTable(tableId, createIndex)\n    }\n\n    override fun visitDropstmt(ctx: RedshiftParser.DropstmtContext): Statement {\n        if (ctx.object_type_any_name() != null) {\n            val ifExists = ctx.IF_P() != null\n            if (ctx.object_type_any_name().INDEX() != null) {\n                val actions = ctx.any_name_list().any_name().map { indexName -> DropIndex(indexName.text, ifExists) }\n                val tableId = TableId(\"\")\n                val alterTable = AlterTable(tableId)\n                alterTable.ifExists = ifExists\n                alterTable.addActions(actions)\n                return alterTable\n            } else if (ctx.object_type_any_name().TABLE() != null) {\n                val tableIds = ctx.any_name_list().any_name().map { tableName -> parseTableName(tableName) }\n                val dropTable = DropTable(tableIds.first(), ifExists)\n                dropTable.tableIds.addAll(tableIds)\n                return dropTable\n            } else if (ctx.object_type_any_name().VIEW() != null) {\n                val isMaterialized =\n                    if (ctx.object_type_any_name().MATERIALIZED() != null) {\n                        true\n                    } else {\n                        false\n                    }\n                val tableIds = ctx.any_name_list().any_name().map { tableName -> parseTableName(tableName) }\n                if (isMaterialized) {\n                    val dropView = DropMaterializedView(tableIds.first(), ifExists)\n                    dropView.tableIds.addAll(tableIds)\n                    return dropView\n                } else {\n                    val dropView = DropView(tableIds.first(), ifExists)\n                    dropView.tableIds.addAll(tableIds)\n                    return dropView\n                }\n            } else if (ctx.object_type_any_name().SEQUENCE() != null) {\n                val tableIds = ctx.any_name_list().any_name().map { tableName -> parseTableName(tableName) }\n                val dropSequence =\n                    io.github.melin.superior.common.relational.drop.DropSequence(tableIds.first(), ifExists)\n                dropSequence.tableIds.addAll(tableIds)\n                return dropSequence\n            }\n        }\n\n        throw SQLParserException(\"not support\")\n    }\n\n    override fun visitTruncatestmt(ctx: RedshiftParser.TruncatestmtContext): Statement {\n        val tableIds = ctx.relation_expr_list().relation_expr().map { parseTableName(it) }\n        return TruncateTable(Lists.newArrayList(tableIds))\n    }\n\n    override fun visitAltertablestmt(ctx: RedshiftParser.AltertablestmtContext): Statement? {\n        if (ctx.TABLE() != null) {\n            if (ctx.relation_expr() != null) {\n                val tableId = parseTableName(ctx.relation_expr())\n\n                if (ctx.alter_table_cmds() != null) {\n                    val alterTable = AlterTable(tableId)\n                    val cmds = ctx.alter_table_cmds().alter_table_cmd()\n                    for (cmdContext in cmds) {\n                        if (cmdContext.ADD_P() != null && cmdContext.columnDef() != null) {\n                            val columnDef = cmdContext.columnDef()\n                            val columnName = columnDef.colid().text\n                            val dataType = source(columnDef.typename())\n                            val action = AlterColumnAction(ADD_COLUMN, columnName, dataType)\n                            action.ifNotExists = cmdContext.EXISTS() != null\n\n                            alterTable.actions.add(action)\n                        } else if (cmdContext.alter_column_default() != null) {\n                            val columnDefaultDef = cmdContext.alter_column_default()\n                            val columnName = cmdContext.colid().get(0).text\n\n                            if (columnDefaultDef.DROP() != null) {\n                                val action = AlterColumnAction(DROP_COLUMN_DRFAULT, columnName)\n                                alterTable.actions.add(action)\n                            } else {\n                                val value = source(columnDefaultDef.a_expr())\n                                val action = AlterColumnAction(SET_COLUMN_DEFAULT, columnName)\n                                action.defaultExpression = CommonUtils.cleanQuote(value)\n                                alterTable.actions.add(action)\n                            }\n                        }\n                    }\n\n                    return alterTable\n                } else {\n                    var alterTable: AlterTable? = null\n                    val partitionCmd = ctx.partition_cmd()\n                    if (partitionCmd.ATTACH() != null) {\n                        alterTable = AlterTable(tableId, AlterTableAction(ATTACH_PARTITION))\n                    } else {\n                        alterTable = AlterTable(tableId, AlterTableAction(DETACH_PARTITION))\n                    }\n\n                    return alterTable\n                }\n\n                return null\n            }\n        }\n\n        return null\n    }\n\n    override fun visitCommentstmt(ctx: RedshiftParser.CommentstmtContext): Statement {\n        val objType: String? =\n            if (ctx.object_type_any_name() != null) {\n                ctx.object_type_any_name().children.map { it.text }.joinToString(\" \")\n            } else if (ctx.object_type_name() != null) {\n                ctx.object_type_name().children.map { it.text }.joinToString(\" \")\n            } else if (ctx.object_type_name_on_any_name() != null) {\n                ctx.object_type_name_on_any_name().children.map { it.text }.joinToString(\" \")\n            } else if (ctx.COLUMN() != null) {\n                ctx.COLUMN().text\n            } else if (ctx.FUNCTION() != null) {\n                ctx.FUNCTION().text\n            } else {\n                null\n            }\n\n        val objValue = if (ctx.any_name() != null) ctx.any_name().text else null\n\n        val isNull = if (ctx.comment_text().NULL_P() != null) true else false\n        val text: String? =\n            if (ctx.comment_text().text != null) CommonUtils.cleanQuote(ctx.comment_text().sconst().text) else null\n        return CommentStatement(text, isNull, objType, objValue)\n    }\n\n    // ----------------------------------------private methods------------------------------------\n\n    override fun visitSelect_limit(ctx: RedshiftParser.Select_limitContext): Statement? {\n        val limitClause = ctx.limit_clause()\n        val offsetClause = ctx.offset_clause()\n        if (limitClause != null) {\n            if (limitClause.LIMIT() != null) {\n                if (limitClause.select_limit_value().a_expr() != null) {\n                    limit = limitClause.select_limit_value().a_expr().text.toInt()\n                }\n\n                if (limitClause.select_offset_value() != null) {\n                    offset = limitClause.select_offset_value().a_expr().text.toInt()\n                }\n            }\n\n            if (limitClause.FETCH() != null && limitClause.select_fetch_first_value() != null) {\n                if (limitClause.select_fetch_first_value().c_expr() != null) {\n                    limit = limitClause.select_fetch_first_value().c_expr().text.toInt()\n                }\n            }\n        }\n\n        if (offsetClause != null) {\n            if (offsetClause.select_offset_value() != null) {\n                offset = offsetClause.select_offset_value().text.toInt()\n            }\n\n            if (offsetClause.select_fetch_first_value() != null) {\n                if (offsetClause.select_fetch_first_value().c_expr() != null) {\n                    offset = offsetClause.select_fetch_first_value().c_expr().text.toInt()\n                }\n            }\n        }\n        return super.visitSelect_limit(ctx)\n    }\n\n    fun parseTableName(ctx: RedshiftParser.Any_nameContext): TableId {\n        val attrNames = ctx.attrs()?.attr_name()\n        if (attrNames == null) {\n            return TableId(null, null, ctx.colid().text)\n        }\n\n        if (attrNames.size == 2) {\n            return TableId(ctx.colid().text, attrNames.get(0).text, attrNames.get(1).text)\n        } else if (attrNames.size == 1) {\n            return TableId(null, ctx.colid().text, attrNames.get(0).text)\n        }\n\n        throw SQLParserException(\"parse schema qualified name error\")\n    }\n\n    fun parseTableName(ctx: RedshiftParser.Relation_exprContext): TableId {\n        return parseTableName(ctx.qualified_name())\n    }\n\n    fun parseTableName(ctx: RedshiftParser.Qualified_nameContext): TableId {\n        if (ctx.childCount == 2) {\n            val obj = ctx.getChild(1)\n            if (obj.childCount == 2) {\n                return TableId(ctx.getChild(0).text, obj.getChild(0).getChild(1).text, obj.getChild(1).getChild(1).text)\n            } else if (obj.childCount == 1) {\n                val inEl = obj.getChild(0) as RedshiftParser.Indirection_elContext\n                return TableId(ctx.colid().text, inEl.attr_name().text)\n            }\n        } else if (ctx.childCount == 1) {\n            return TableId(ctx.getChild(0).text)\n        }\n\n        throw SQLParserException(\"parse schema qualified name error\")\n    }\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/RedshiftSqlHelper.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.redshift.antlr4.RedshiftLexer\nimport io.github.melin.superior.parser.redshift.antlr4.RedshiftParser\nimport io.github.melin.superior.parser.redshift.antlr4.RedshiftParserBaseVisitor\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2020/6/30 9:58 上午 */\nobject RedshiftSqlHelper {\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until RedshiftLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = RedshiftLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement {\n        val statements = this.parseMultiStatement(command)\n        if (statements.size != 1) {\n            throw IllegalStateException(\"only parser one sql, sql count: \" + statements.size)\n        } else {\n            return statements.get(0)\n        }\n    }\n\n    @JvmStatic\n    fun parseMultiStatement(command: String): List<Statement> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = RedshiftSqlAntlr4Visitor(false)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSqlStatements()\n    }\n\n    @JvmStatic\n    fun splitSql(command: String): List<String> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = RedshiftSqlAntlr4Visitor(true)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSplitSqls()\n    }\n\n    @JvmStatic\n    fun checkSqlSyntax(command: String) {\n        val sqlVisitor = RedshiftParserBaseVisitor<Statement>()\n        innerParseStatement(command, sqlVisitor)\n    }\n\n    private fun innerParseStatement(command: String, sqlVisitor: RedshiftParserBaseVisitor<Statement>) {\n        val charStream = UpperCaseCharStream(CharStreams.fromString(command))\n        val lexer = RedshiftLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = RedshiftParser(tokenStream)\n        AbstractSqlParser.installCaches(parser)\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n\n        // parser.interpreter.predictionMode = PredictionMode.SLL\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visit(parser.root())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                sqlVisitor.visit(parser.root())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(command)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/relational/CreatePartitionTable.kt",
    "content": "package io.github.melin.superior.parser.postgre.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class CreatePartitionTable(override val tableId: TableId, val partitionTableId: TableId) :\n    AbsTableStatement() { // 是否存在 if exists 关键字\n    override val statementType = StatementType.CREATE_TABLE\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DDL\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/BooleanType.kt",
    "content": "package io.github.melin.superior.parser.postgre.type\n\nimport io.github.melin.superior.common.type.AbsType\n\nclass BooleanType : AbsType() {\n    override val name: String = \"boolean\"\n    override val alias: String = \"bool\"\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/JsonType.kt",
    "content": "package io.github.melin.superior.parser.postgre.type\n\nimport io.github.melin.superior.common.type.AbsType\n\nclass JsonType : AbsType() {\n    override val name: String = \"json\"\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/datetime.kt",
    "content": "package io.github.melin.superior.parser.postgre.type\n\nimport io.github.melin.superior.common.type.AbsDataTimeType\n\nclass DateType : AbsDataTimeType() {\n    override val name: String = \"date\"\n}\n\ndata class TimeType(val precision: Int = 0, val timezone: Boolean = false) : AbsDataTimeType() {\n    override val name: String = \"time\"\n    override val alias: String = \"timez\"\n}\n\ndata class TimeStampType(val precision: Int = 0, val timezone: Boolean = false) : AbsDataTimeType() {\n    override val name: String = \"timestamp\"\n    override val alias: String = \"timestampz\"\n}\n\nclass IntervalType : AbsDataTimeType() {\n    override val name: String = \"interval\"\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/numeric.kt",
    "content": "package io.github.melin.superior.parser.postgre.type\n\nimport io.github.melin.superior.common.type.AbsNumericType\n\ndata class SmallIntType(val length: Int) : AbsNumericType() {\n    override val name: String = \"smallint\"\n    override val alias: String = \"int2\"\n\n    companion object {\n        const val MIN_VALUE: Int = -32768\n        const val MAX_VALUE: Int = 32767\n    }\n}\n\ndata class IntegerType(val length: Int) : AbsNumericType() {\n    override val name: String = \"integer\"\n    override val alias: String = \"int\"\n    override val alias2: String = \"int4\"\n\n    companion object {\n        const val MIN_VALUE: Long = -2147483648L\n        const val MAX_VALUE: Long = 2147483647L\n    }\n}\n\ndata class BigIntType(val length: Int) : AbsNumericType() {\n    override val name: String = \"bigint\"\n    override val alias: String = \"int8\"\n}\n\ndata class NumericType(val precision: Int = 10, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"numeric\"\n    override val alias: String = \"decimal\"\n}\n\ndata class FloatType(val precision: Int, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"float\"\n}\n\ndata class DoubleType(val precision: Int, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"double precision\"\n    override val alias: String = \"float8\"\n}\n\ndata class RealType(val precision: Int, val scale: Int = 0) : AbsNumericType() {\n    override val name: String = \"real\"\n    override val alias: String = \"float4\"\n}\n\ndata class SmallserialType(val length: Int) : AbsNumericType() {\n    override val name: String = \"smallserial\"\n    override val alias: String = \"serial2\"\n\n    companion object {\n        const val MIN_VALUE: Int = 1\n        const val MAX_VALUE: Int = 32767\n    }\n}\n\ndata class SerialType(val length: Int) : AbsNumericType() {\n    override val name: String = \"serial\"\n    override val alias: String = \"serial4\"\n\n    companion object {\n        const val MIN_VALUE: Long = 1\n        const val MAX_VALUE: Long = 2147483647L\n    }\n}\n\ndata class BigserialType(val length: Int) : AbsNumericType() {\n    override val name: String = \"bigserial\"\n    override val alias: String = \"serial8\"\n}\n\ndata class BitType(val length: Int) : AbsNumericType() {\n    override val name: String = \"bit\"\n}\n\ndata class VarbitType(val length: Int) : AbsNumericType() {\n    override val name: String = \"bit varying\"\n    override val alias: String = \"varbit\"\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/string.kt",
    "content": "package io.github.melin.superior.parser.postgre.type\n\nimport io.github.melin.superior.common.type.AbsStringType\n\ndata class CharType(val length: Int) : AbsStringType() {\n    override val name: String = \"char\"\n    override val alias: String = \"character\"\n\n    companion object {\n        const val MAX_LENGTH: Int = 255\n    }\n}\n\ndata class VarcharType(val length: Int) : AbsStringType() {\n    override val name: String = \"varchar\"\n    override val alias: String = \"character varying\"\n\n    companion object {\n        const val MAX_LENGTH: Int = 65535\n    }\n}\n\nclass TextType : AbsStringType() {\n    override val name: String = \"text\"\n}\n\nclass ByteaType : AbsStringType() {\n    override val name: String = \"bytea\"\n}\n\ndata class EnumType(val typeName: String, val values: List<String>) : AbsStringType() {\n    override val name: String = \"enum\"\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/test/java/io/github/melin/superior/parser/postgre/RedshiftSqlParserDdlTest.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport io.github.melin.superior.common.AlterActionType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.*\nimport io.github.melin.superior.common.relational.alter.*\nimport io.github.melin.superior.common.relational.common.CommentStatement\nimport io.github.melin.superior.common.relational.common.RefreshMaterializedView\nimport io.github.melin.superior.common.relational.create.*\nimport io.github.melin.superior.common.relational.drop.DropDatabase\nimport io.github.melin.superior.common.relational.drop.DropMaterializedView\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport io.github.melin.superior.parser.postgre.relational.CreatePartitionTable\nimport org.junit.Assert\nimport org.junit.Test\n\n/**\n * Created by libinsong on 2020/6/30 11:04 上午\n */\nclass RedshiftSqlParserDdlTest {\n\n    @Test\n    fun createDatabaseTest() {\n        val sql = \"\"\"\n            CREATE DATABASE bigdata1;\n            drop DATABASE bigdata2\n        \"\"\".trimIndent()\n\n        val statements = RedshiftSqlHelper.parseMultiStatement(sql)\n\n        val createDatabse = statements.get(0)\n        val dropDatabase = statements.get(1)\n        if (createDatabse is CreateDatabase) {\n            Assert.assertEquals(\"bigdata1\", createDatabse.databaseName)\n        } else {\n            Assert.fail()\n        }\n        if (dropDatabase is DropDatabase) {\n            Assert.assertEquals(\"bigdata2\", dropDatabase.databaseName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createSchemaTest() {\n        val sql = \"\"\"\n            CREATE schema bigdata1;\n            CREATE schema bigdata2;\n        \"\"\".trimIndent()\n\n        val statements = RedshiftSqlHelper.parseMultiStatement(sql)\n\n        val createSchema1 = statements.get(0)\n        val createSchema2 = statements.get(1)\n        if (createSchema1 is CreateSchema) {\n            Assert.assertEquals(\"bigdata1\", createSchema1.schemaName)\n        } else {\n            Assert.fail()\n        }\n        if (createSchema2 is CreateSchema) {\n            Assert.assertEquals(\"bigdata2\", createSchema2.schemaName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTable0() {\n        val sql = \"\"\"\n            CREATE TEMPORARY TABLE test.public.authors (\n                id INTEGER NOT NULL PRIMARY KEY,\n                last_name TEXT,\n                first_name TEXT,\n                age int not null\n            ) PARTITION BY RANGE (age); \n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertTrue(statement.temporary)\n            Assert.assertEquals(TableId(\"test\", \"public\", \"authors\"), statement.tableId)\n            Assert.assertEquals(4, statement.columnRels?.size)\n            Assert.assertTrue(statement.columnRels?.get(0)?.primaryKey!!)\n\n            Assert.assertEquals(PartitionType.RANGE, statement.partitionType)\n            Assert.assertEquals(1, statement.partitionColumnNames.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTable1() {\n        val sql = \"\"\"\n            CREATE TABLE IF NOT EXISTS sales_range_partitioned3 (\n                id INT,\n                sales_date DATE,\n                amount DECIMAL(10, 2)\n            )\n            PARTITION BY RANGE (sales_date) (\n                PARTITION p2022 VALUES LESS THAN ('2023-01-01'),\n                PARTITION p2023 VALUES LESS THAN ('2024-01-01'),\n                PARTITION p2024 VALUES LESS THAN ('2025-01-01')\n            );\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(TableId(\"sales_range_partitioned3\"), statement.tableId)\n            Assert.assertEquals(3, statement.columnRels?.size)\n            Assert.assertEquals(PartitionType.RANGE, statement.partitionType)\n            Assert.assertEquals(1, statement.partitionColumnNames.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createView0() {\n        val sql = \"\"\"\n            CREATE OR REPLACE VIEW comedies AS\n            SELECT f.*,\n                   country_code_to_name(f.country_code) AS country,\n                   (SELECT avg(r.rating)\n                    FROM user_ratings r\n                    WHERE r.film_id = f.id) AS avg_rating\n            FROM films f\n            WHERE f.kind = 'Comedy'\n            WITH CASCADED CHECK OPTION;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateView) {\n            Assert.assertEquals(StatementType.CREATE_VIEW, statement.statementType)\n            Assert.assertEquals(\"comedies\", statement.tableId.tableName)\n\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createMatView0() {\n        val sql = \"\"\"\n            CREATE MATERIALIZED VIEW sales_summary AS\n              SELECT\n                  seller_no,\n                  invoice_date,\n                  sum(invoice_amt)::numeric(13,2) as sales_amt\n                FROM invoice\n                WHERE invoice_date < CURRENT_DATE\n                GROUP BY\n                  seller_no,\n                  invoice_date;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateMaterializedView) {\n            Assert.assertEquals(StatementType.CREATE_MATERIALIZED_VIEW, statement.statementType)\n            Assert.assertEquals(\"sales_summary\", statement.tableId.tableName)\n\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropMvTest() {\n        val sql = \"\"\"\n            DROP MATERIALIZED VIEW tickets_mv;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n\n        if (statement is DropMaterializedView) {\n            Assert.assertEquals(StatementType.DROP_MATERIALIZED_VIEW, statement.statementType)\n            Assert.assertEquals(TableId(\"tickets_mv\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun refreshMvTest() {\n        val sql = \"\"\"\n            REFRESH MATERIALIZED VIEW tickets_mv;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n\n        if (statement is RefreshMaterializedView) {\n            Assert.assertEquals(StatementType.REFRESH_MV, statement.statementType)\n            Assert.assertEquals(TableId(\"tickets_mv\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun renameMvTest() {\n        val sql = \"\"\"\n            ALTER MATERIALIZED VIEW tickets_mv RENAME TO tickets_mv_1;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n\n        if (statement is AlterMaterializedView) {\n            Assert.assertEquals(StatementType.ALTER_MATERIALIZED_VIEW, statement.statementType)\n            Assert.assertEquals(TableId(\"tickets_mv\"), statement.tableId)\n            Assert.assertEquals(AlterActionType.RENAME, statement.firstAction().alterType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropTable0() {\n        val sql = \"\"\"\n            drop TABLE test.public.authors\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is DropTable) {\n            Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)\n            Assert.assertEquals(TableId(\"test\", \"public\", \"authors\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropTable1() {\n        val sql = \"\"\"\n            drop TABLE authors, tests\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is DropTable) {\n            Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)\n            Assert.assertEquals(TableId(\"authors\"), statement.tableId)\n            Assert.assertEquals(2, statement.tableIds.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createIndexTest() {\n        val sql = \"CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating);\\n\"\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        \n        if (statement is AlterTable) {\n            Assert.assertEquals(TableId(\"films\"), statement.tableId)\n            val createIndex = statement.firstAction() as CreateIndex\n            Assert.assertEquals(AlterActionType.ADD_INDEX, createIndex.alterType)\n            Assert.assertEquals(\"title_idx\", createIndex.indexName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropIndexTest() {\n        val sql = \"DROP INDEX title_idx\"\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        \n        if (statement is AlterTable) {\n            val dropIndex = statement.firstAction() as DropIndex\n            Assert.assertEquals(AlterActionType.DROP_INDEX, dropIndex.alterType)\n            Assert.assertEquals(\"title_idx\", dropIndex.indexName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createPartitonTableTest() {\n        val sql = \"create table pkslow_person_r1 partition of pkslow_person_r for values from (MINVALUE) to (10);  \\n\"\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n\n        if (statement is CreatePartitionTable) {\n            Assert.assertEquals(\"pkslow_person_r\", statement.tableId.tableName)\n            Assert.assertEquals(\"pkslow_person_r1\", statement.partitionTableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun commentTest0() {\n        val sql = \"\"\"\n            COMMENT ON TABLE my_schema.my_table IS 'Employee Information';\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is CommentStatement) {\n            Assert.assertEquals(StatementType.COMMENT, statement.statementType)\n            Assert.assertEquals(\"Employee Information\", statement.comment)\n            Assert.assertFalse(statement.isNull)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun alterTableTest() {\n        val sql = \"\"\"\n            ALTER TABLE distributors ADD COLUMN address varchar(30),\n            ALTER COLUMN status SET default 'current';\n        \"\"\".trimIndent()\n        val statements = RedshiftSqlHelper.parseMultiStatement(sql)\n\n        val alterTable1 = statements.get(0) as AlterTable\n        Assert.assertEquals(\"distributors\", alterTable1.tableId.tableName)\n        var action = alterTable1.actions.get(0) as AlterColumnAction\n        Assert.assertEquals(AlterActionType.ADD_COLUMN, action.alterType)\n        Assert.assertEquals(\"address\", action.columName)\n        Assert.assertEquals(\"varchar(30)\", action.dataType)\n\n        action = alterTable1.actions.get(1) as AlterColumnAction\n        Assert.assertEquals(AlterActionType.SET_COLUMN_DEFAULT, action.alterType)\n        Assert.assertEquals(\"status\", action.columName)\n        Assert.assertEquals(\"current\", action.defaultExpression)\n    }\n\n    @Test\n    fun showTest() {\n        val sql = \"\"\"\n            SHOW COLUMNS FROM TABLE awsdatacatalog.batman.nation LIMIT 2;\n            SHOW SCHEMAS FROM DATABASE awsdatacatalog LIMIT 5;\n            show table sales;\n            SHOW TABLES FROM SCHEMA dev.public;\n            show view LA_Venues_v;\n        \"\"\".trimIndent()\n        val statements = RedshiftSqlHelper.parseMultiStatement(sql)\n        Assert.assertEquals(5, statements.size)\n    }\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/test/java/io/github/melin/superior/parser/postgre/RedshiftSqlParserDmlTest.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.create.CreateTableAsSelect\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.table.TruncateTable\nimport org.junit.Assert\nimport org.junit.Test\n\n/**\n * Created by libinsong on 2020/6/30 11:04 上午\n */\nclass RedshiftSqlParserDmlTest {\n\n    @Test\n    fun queryTest0() {\n        val sql = \"\"\"\n            select a.* from datacompute1.datacompute.dc_job a left join datacompute1.datacompute.dc_job_scheduler b on a.id=b.job_id\n            LIMIT 3, 2\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(2, statement.inputTables.size)\n            Assert.assertEquals(3, statement.limit)\n            Assert.assertEquals(2, statement.offset)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest1() {\n        val sql = \"\"\"\n            SELECT * FROM public.usertest LIMIT 3 OFFSET 2;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(3, statement.limit)\n            Assert.assertEquals(2, statement.offset)\n            Assert.assertEquals(TableId(\"public\", \"usertest\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest2() {\n        val sql = \"\"\"\n            SELECT * FROM public.usertest FETCH FIRST 5 ROWS ONLY;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(5, statement.limit)\n            Assert.assertEquals(TableId(\"public\", \"usertest\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest3() {\n        val sql = \"\"\"\n            SELECT * FROM public.usertest \n            OFFSET 10\n            FETCH FIRST 10 ROWS ONLY;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(10, statement.limit)\n            Assert.assertEquals(10, statement.offset)\n            Assert.assertEquals(TableId(\"public\", \"usertest\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun cteSqlTest0() {\n        val sql = \"\"\"\n            WITH regional_sales AS (\n                SELECT region, SUM(amount) AS total_sales\n                FROM orders\n                GROUP BY region\n            ), \n            top_regions AS (\n                SELECT region\n                FROM regional_sales\n                WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)\n            )\n            SELECT region,\n                   product,\n                   SUM(quantity) AS product_units,\n                   SUM(amount) AS product_sales\n            FROM orders\n            WHERE region IN (SELECT region FROM top_regions)\n            GROUP BY region, product;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(TableId(\"orders\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createAsQueryTest0() {\n        val sql = \"\"\"\n            CREATE TABLE films_recent AS\n            SELECT * FROM films WHERE date_prod >= '2002-01-01';\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateTableAsSelect) {\n            Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n            Assert.assertEquals(\"films_recent\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(\"films\", statement.queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest0() {\n        val sql = \"\"\"\n            DELETE FROM films\n            WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest1() {\n        val sql = \"\"\"\n            DELETE FROM films USING producers\n            WHERE producer_id = producers.id AND producers.name = 'foo';\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n\n            Assert.assertEquals(\"producers\", statement.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest0() {\n        val sql = \"\"\"\n            UPDATE employees SET sales_count = sales_count + 1 WHERE id =\n            (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest1() {\n        val sql = \"\"\"\n            UPDATE product p\n            SET net_price = price - price * discount\n            FROM product_segment s\n            WHERE p.segment_id = s.id;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"product\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n\n            Assert.assertEquals(\"product_segment\", statement.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest0() {\n        val sql = \"\"\"\n            INSERT INTO films (code, title, did, date_prod, kind) VALUES\n            ('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),\n            ('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(0, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest1() {\n        val sql = \"\"\"\n            WITH upd AS (\n              UPDATE employees SET sales_count = sales_count + 1 WHERE id =\n                (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation')\n                RETURNING *\n            )\n            INSERT INTO employees_log SELECT *, current_timestamp FROM upd;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"employees_log\", statement.tableId?.tableName)\n            Assert.assertEquals(2, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest2() {\n        val sql = \"\"\"\n            truncate table films\n            INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';\n        \"\"\".trimIndent()\n\n        val statements = RedshiftSqlHelper.parseMultiStatement(sql)\n        var statement = statements.get(0)\n        if (statement is TruncateTable) {\n            Assert.assertEquals(StatementType.TRUNCATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n\n        statement = statements.get(1)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.outputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deltaMergeTest() {\n        val sql = \"\"\"\n            MERGE INTO wines w\n            USING wine_stock_changes s\n            ON s.winename = w.winename\n            WHEN NOT MATCHED AND s.stock_delta > 0 THEN\n              INSERT VALUES(s.winename, s.stock_delta)\n            WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN\n              UPDATE SET stock = w.stock + s.stock_delta\n            WHEN MATCHED THEN\n              DELETE;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is MergeTable) {\n            Assert.assertEquals(StatementType.MERGE, statement.statementType)\n            Assert.assertEquals(\"wines\", statement.targetTable.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-redshift-parser/src/test/java/io/github/melin/superior/parser/postgre/RedshiftSqlProcessParserTest.kt",
    "content": "package io.github.melin.superior.parser.postgre\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.ProcedureId\nimport io.github.melin.superior.common.relational.create.CreateFunction\nimport io.github.melin.superior.common.relational.create.CreateProcedure\nimport org.junit.Assert\nimport org.junit.Test\n\nclass RedshiftSqlProcessParserTest {\n    @Test\n    fun createFunctionTest() {\n        val sql = \"\"\"\n            CREATE FUNCTION public.myadd(integer, integer) RETURNS integer\n            AS 'select ${'$'}1 + ${'$'}2;'\n            LANGUAGE SQL\n            IMMUTABLE\n            RETURNS NULL ON NULL INPUT;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateFunction) {\n            Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId(\"public\", \"myadd\"), statement.functionId)\n            Assert.assertEquals(\"myadd\", statement.functionId.functionName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFunctionTest1() {\n        val sql = \"\"\"\n            CREATE FUNCTION myadd(integer, integer) RETURNS integer\n            AS 'select ${'$'}1 + ${'$'}2;'\n            LANGUAGE SQL\n            IMMUTABLE\n            RETURNS NULL ON NULL INPUT;\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateFunction) {\n            Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId(\"myadd\"), statement.functionId)\n            Assert.assertEquals(\"myadd\", statement.functionId.functionName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFunctionTest2() {\n        val sql = \"\"\"\n            CREATE FUNCTION check_password(uname TEXT, pass TEXT)\n            RETURNS BOOLEAN AS ${'$'}${'$'}\n            DECLARE passed BOOLEAN;\n            BEGIN\n                SELECT  (pwd = ${'$'}2) INTO passed\n                FROM    pwds\n                WHERE   username = ${'$'}1;\n                RETURN passed;\n            END;\n            ${'$'}${'$'}  LANGUAGE plpgsql\n                SECURITY DEFINER\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateFunction) {\n            Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId( \"check_password\"), statement.functionId)\n            Assert.assertEquals(1, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFunctionTest3() {\n        val sql = \"\"\"\n            create or replace procedure prac_transfer(\n               sender int,\n               receiver int, \n               amount dec\n            )\n            LANGUAGE plpgsql\n            as ${'$'}${'$'}\n            BEGIN\n                update accounts_1\n                set balance = balance - amount \n                where id = sender;\n            \n                update accounts_2\n                set balance = balance + amount \n                where id = receiver;\n            \n                commit;\n            END;${'$'}${'$'};\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(ProcedureId( \"prac_transfer\"), statement.procedureId)\n            Assert.assertEquals(2, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFunctionTest4() {\n        val sql = \"\"\"\n            create or replace procedure prac_transfer(\n               sender int,\n               receiver int, \n               amount dec\n            )\n            LANGUAGE plpgsql\n            as ${'$'}${'$'}\n            BEGIN\n                update accounts\n                set balance = balance - amount \n                where id = sender;\n            \n                update accounts\n                set balance = balance + amount \n                where id = receiver;\n            \n                commit;\n            END;${'$'}${'$'};\n        \"\"\".trimIndent()\n\n        val statement = RedshiftSqlHelper.parseStatement(sql)\n        \n        if (statement is CreateProcedure) {\n            Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)\n            Assert.assertEquals(ProcedureId( \"prac_transfer\"), statement.procedureId)\n            Assert.assertEquals(2, statement.childStatements.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}"
  },
  {
    "path": "superior-redshift-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-spark-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-spark-parser</artifactId>\n    <name>superior-spark-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "superior-spark-parser/src/main/antlr4/io/github/melin/superior/parser/spark/antlr4/SparkSqlLexer.g4",
    "content": "/*\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * This file is an adaptation of Presto's presto-parser/src/main/antlr4/com/facebook/presto/sql/parser/SqlBase.g4 grammar.\n */\n\nlexer grammar SparkSqlLexer;\n\n@members {\n  /**\n   * When true, parser should throw ParseException for unclosed bracketed comment.\n   */\n  public boolean has_unclosed_bracketed_comment = false;\n\n  /**\n   * Verify whether current token is a valid decimal token (which contains dot).\n   * Returns true if the character that follows the token is not a digit or letter or underscore.\n   *\n   * For example:\n   * For char stream \"2.3\", \"2.\" is not a valid decimal token, because it is followed by digit '3'.\n   * For char stream \"2.3_\", \"2.3\" is not a valid decimal token, because it is followed by '_'.\n   * For char stream \"2.3W\", \"2.3\" is not a valid decimal token, because it is followed by 'W'.\n   * For char stream \"12.0D 34.E2+0.12 \"  12.0D is a valid decimal token because it is followed\n   * by a space. 34.E2 is a valid decimal token because it is followed by symbol '+'\n   * which is not a digit or letter or underscore.\n   */\n  public boolean isValidDecimal() {\n    int nextChar = _input.LA(1);\n    if (nextChar >= 'A' && nextChar <= 'Z' || nextChar >= '0' && nextChar <= '9' ||\n      nextChar == '_') {\n      return false;\n    } else {\n      return true;\n    }\n  }\n\n  /**\n   * This method will be called when we see '/*' and try to match it as a bracketed comment.\n   * If the next character is '+', it should be parsed as hint later, and we cannot match\n   * it as a bracketed comment.\n   *\n   * Returns true if the next character is '+'.\n   */\n  public boolean isHint() {\n    int nextChar = _input.LA(1);\n    if (nextChar == '+') {\n      return true;\n    } else {\n      return false;\n    }\n  }\n\n  /**\n   * This method will be called when the character stream ends and try to find out the\n   * unclosed bracketed comment.\n   * If the method be called, it means the end of the entire character stream match,\n   * and we set the flag and fail later.\n   */\n  public void markUnclosedComment() {\n    has_unclosed_bracketed_comment = true;\n  }\n}\n\nSEMICOLON: ';';\n\nLEFT_PAREN: '(';\nRIGHT_PAREN: ')';\nCOMMA: ',';\nDOT: '.';\nLEFT_BRACKET: '[';\nRIGHT_BRACKET: ']';\nLEFT_BRACE: '{';\nRIGHT_BRACE: '}';\n\n// NOTE: If you add a new token in the list below, you should update the list of keywords\n// and reserved tag in `docs/sql-ref-ansi-compliance.md#sql-keywords`, and\n// modify `ParserUtils.toExprAlias()` which assumes all keywords are between `ADD` and `ZONE`.\n\n//============================\n// Start of the keywords list\n//============================\n//--SPARK-KEYWORD-LIST-START\nADD: 'ADD';\nAFTER: 'AFTER';\nALL: 'ALL';\nALTER: 'ALTER';\nALWAYS: 'ALWAYS';\nANALYZE: 'ANALYZE';\nAND: 'AND';\nANTI: 'ANTI';\nANY: 'ANY';\nANY_VALUE: 'ANY_VALUE';\nARCHIVE: 'ARCHIVE';\nARRAY: 'ARRAY';\nAS: 'AS';\nASC: 'ASC';\nAT: 'AT';\nAUTHORIZATION: 'AUTHORIZATION';\nBETWEEN: 'BETWEEN';\nBIGINT: 'BIGINT';\nBINARY: 'BINARY';\nBOOLEAN: 'BOOLEAN';\nBOTH: 'BOTH';\nBRANCH: 'BRANCH';\nBUCKET: 'BUCKET';\nBUCKETS: 'BUCKETS';\nBY: 'BY';\nBYTE: 'BYTE';\nCACHE: 'CACHE';\nCALL: 'CALL';\nCASCADE: 'CASCADE';\nCASE: 'CASE';\nCAST: 'CAST';\nCATALOG: 'CATALOG';\nCATALOGS: 'CATALOGS';\nCHANGE: 'CHANGE';\nCHAR: 'CHAR';\nCHARACTER: 'CHARACTER';\nCHECK: 'CHECK';\nCLEAR: 'CLEAR';\nCLUSTER: 'CLUSTER';\nCLUSTERED: 'CLUSTERED';\nCODEGEN: 'CODEGEN';\nCOLLATE: 'COLLATE';\nCOLLECTION: 'COLLECTION';\nCOLUMN: 'COLUMN';\nCOLUMNS: 'COLUMNS';\nCOMMENT: 'COMMENT';\nCOMMIT: 'COMMIT';\nCOMPACT: 'COMPACT';\nCOMPACTIONS: 'COMPACTIONS';\nCOMPRESSION: 'COMPRESSION';\nCOMPUTE: 'COMPUTE';\nCONCATENATE: 'CONCATENATE';\nCONSTRAINT: 'CONSTRAINT';\nCOST: 'COST';\nCREATE: 'CREATE';\nCROSS: 'CROSS';\nCUBE: 'CUBE';\nCURRENT: 'CURRENT';\nCURRENT_DATE: 'CURRENT_DATE';\nCURRENT_TIME: 'CURRENT_TIME';\nCURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP';\nCURRENT_USER: 'CURRENT_USER';\nDAY: 'DAY';\nDAYS: 'DAYS';\nDAYOFYEAR: 'DAYOFYEAR';\nDATA: 'DATA';\nDATE: 'DATE';\nDATABASE: 'DATABASE';\nDATABASES: 'DATABASES';\nDATATUNNEL: 'DATATUNNEL';\nDATEADD: 'DATEADD';\nDATE_ADD: 'DATE_ADD';\nDATEDIFF: 'DATEDIFF';\nDATE_DIFF: 'DATE_DIFF';\nDBPROPERTIES: 'DBPROPERTIES';\nDEC: 'DEC';\nDECIMAL: 'DECIMAL';\nDEFAULT: 'DEFAULT';\nDEFINED: 'DEFINED';\nDELETE: 'DELETE';\nDELIMITED: 'DELIMITED';\nDESC: 'DESC';\nDESCRIBE: 'DESCRIBE';\nDFS: 'DFS';\nDIRECTORIES: 'DIRECTORIES';\nDIRECTORY: 'DIRECTORY';\nDISTCP: 'DISTCP';\nDISTINCT: 'DISTINCT';\nDISTRIBUTE: 'DISTRIBUTE';\nDISTRIBUTED: 'DISTRIBUTED';\nDIV: 'DIV';\nDOUBLE: 'DOUBLE';\nDROP: 'DROP';\nELSE: 'ELSE';\nEND: 'END';\nESCAPE: 'ESCAPE';\nESCAPED: 'ESCAPED';\nEXCEPT: 'EXCEPT';\nEXCHANGE: 'EXCHANGE';\nEXCLUDE: 'EXCLUDE';\nEXISTS: 'EXISTS';\nEXPLAIN: 'EXPLAIN';\nEXPORT: 'EXPORT';\nEXTENDED: 'EXTENDED';\nEXTERNAL: 'EXTERNAL';\nEXTRACT: 'EXTRACT';\nFALSE: 'FALSE';\nFETCH: 'FETCH';\nFIELD: 'FIELD';\nFIELDS: 'FIELDS';\nFILTER: 'FILTER';\nFILE: 'FILE';\nFILEFORMAT: 'FILEFORMAT';\nFIRST: 'FIRST';\nFLOAT: 'FLOAT';\nFOLLOWING: 'FOLLOWING';\nFOR: 'FOR';\nFOREIGN: 'FOREIGN';\nFORMAT: 'FORMAT';\nFORMATTED: 'FORMATTED';\nFROM: 'FROM';\nFULL: 'FULL';\nFUNCTION: 'FUNCTION';\nFUNCTIONS: 'FUNCTIONS';\nGENERATED: 'GENERATED';\nGLOBAL: 'GLOBAL';\nGRANT: 'GRANT';\nGROUP: 'GROUP';\nGROUPING: 'GROUPING';\nHAVING: 'HAVING';\nBINARY_HEX: 'X';\nHELP: 'HELP';\nHOUR: 'HOUR';\nHOURS: 'HOURS';\nIDENTIFIER_KW: 'IDENTIFIER';\nIF: 'IF';\nIGNORE: 'IGNORE';\nIMPORT: 'IMPORT';\nIN: 'IN';\nINCLUDE: 'INCLUDE';\nINDEX: 'INDEX';\nINDEXES: 'INDEXES';\nINNER: 'INNER';\nINPATH: 'INPATH';\nINPUTFORMAT: 'INPUTFORMAT';\nINSERT: 'INSERT';\nINTERSECT: 'INTERSECT';\nINTERVAL: 'INTERVAL';\nINT: 'INT';\nINTEGER: 'INTEGER';\nINTO: 'INTO';\nIS: 'IS';\nITEMS: 'ITEMS';\nJOIN: 'JOIN';\nKEYS: 'KEYS';\nLAST: 'LAST';\nLATERAL: 'LATERAL';\nLAZY: 'LAZY';\nLEADING: 'LEADING';\nLEFT: 'LEFT';\nLIKE: 'LIKE';\nLIFECYCLE: 'LIFECYCLE';\nILIKE: 'ILIKE';\nLIMIT: 'LIMIT';\nLINES: 'LINES';\nLIST: 'LIST';\nLOAD: 'LOAD';\nLOCAL: 'LOCAL';\nLOCATION: 'LOCATION';\nLOCK: 'LOCK';\nLOCKS: 'LOCKS';\nLOGICAL: 'LOGICAL';\nLONG: 'LONG';\nLOCALLY: 'LOCALLY';\nMACRO: 'MACRO';\nMAP: 'MAP';\nMATCHED: 'MATCHED';\nMAX_FILE_SIZE: 'MAX_FILE_SIZE';\nMERGE: 'MERGE';\nMICROSECOND: 'MICROSECOND';\nMICROSECONDS: 'MICROSECONDS';\nMILLISECOND: 'MILLISECOND';\nMILLISECONDS: 'MILLISECONDS';\nMINUTE: 'MINUTE';\nMINUTES: 'MINUTES';\nMONTH: 'MONTH';\nMONTHS: 'MONTHS';\nMSCK: 'MSCK';\nNAME: 'NAME';\nNAMESPACE: 'NAMESPACE';\nNAMESPACES: 'NAMESPACES';\nNANOSECOND: 'NANOSECOND';\nNANOSECONDS: 'NANOSECONDS';\nNATURAL: 'NATURAL';\nNO: 'NO';\nNOT: 'NOT' | '!';\nNULL: 'NULL';\nNULLS: 'NULLS';\nNUMERIC: 'NUMERIC';\nOF: 'OF';\nOFFSET: 'OFFSET';\nON: 'ON';\nONLY: 'ONLY';\nOPTION: 'OPTION';\nOPTIONS: 'OPTIONS';\nOR: 'OR';\nORDER: 'ORDER';\nORDERED: 'ORDERED';\nOUT: 'OUT';\nOUTER: 'OUTER';\nOUTPUTFORMAT: 'OUTPUTFORMAT';\nOVER: 'OVER';\nOVERLAPS: 'OVERLAPS';\nOVERLAY: 'OVERLAY';\nOVERWRITE: 'OVERWRITE';\nOWNER: 'OWNER';\nPARTITION: 'PARTITION';\nPARTITIONED: 'PARTITIONED';\nPARTITIONS: 'PARTITIONS';\nPERCENTILE_CONT: 'PERCENTILE_CONT';\nPERCENTILE_DISC: 'PERCENTILE_DISC';\nPERCENTLIT: 'PERCENT';\nPIVOT: 'PIVOT';\nPLACING: 'PLACING';\nPOSITION: 'POSITION';\nPRECEDING: 'PRECEDING';\nPRIMARY: 'PRIMARY';\nPRINCIPALS: 'PRINCIPALS';\nPROPERTIES: 'PROPERTIES';\nPURGE: 'PURGE';\nQUARTER: 'QUARTER';\nQUERY: 'QUERY';\nRANGE: 'RANGE';\nREAL: 'REAL';\nRECORDREADER: 'RECORDREADER';\nRECORDWRITER: 'RECORDWRITER';\nRECOVER: 'RECOVER';\nREDUCE: 'REDUCE';\nREFERENCES: 'REFERENCES';\nREFRESH: 'REFRESH';\nRENAME: 'RENAME';\nREPAIR: 'REPAIR';\nREPEATABLE: 'REPEATABLE';\nREPLACE: 'REPLACE';\nRESET: 'RESET';\nRESPECT: 'RESPECT';\nRESTRICT: 'RESTRICT';\nRETAIN: 'RETAIN';\nRETENTION: 'RETENTION';\nREVOKE: 'REVOKE';\nRIGHT: 'RIGHT';\nRLIKE: 'RLIKE' | 'REGEXP';\nROLE: 'ROLE';\nROLES: 'ROLES';\nROLLBACK: 'ROLLBACK';\nROLLUP: 'ROLLUP';\nROW: 'ROW';\nROWS: 'ROWS';\nSNAPSHOT: 'SNAPSHOT';\nSNAPSHOTS: 'SNAPSHOTS';\nSECOND: 'SECOND';\nSECONDS: 'SECONDS';\nSCHEMA: 'SCHEMA';\nSCHEMAS: 'SCHEMAS';\nSELECT: 'SELECT';\nSEMI: 'SEMI';\nSEPARATED: 'SEPARATED';\nSERDE: 'SERDE';\nSERDEPROPERTIES: 'SERDEPROPERTIES';\nSESSION_USER: 'SESSION_USER';\nSET: 'SET';\nSETMINUS: 'MINUS';\nSETS: 'SETS';\nSHORT: 'SHORT';\nSHOW: 'SHOW';\nSIZE_LIMIT: 'SIZE_LIMIT';\nSINGLE: 'SINGLE';\nSINK: 'SINK';\nSKEWED: 'SKEWED';\nSMALLINT: 'SMALLINT';\nSOME: 'SOME';\nSORT: 'SORT';\nSORTED: 'SORTED';\nSOURCE: 'SOURCE';\nSTART: 'START';\nSTATISTICS: 'STATISTICS';\nSTORED: 'STORED';\nSTRATIFY: 'STRATIFY';\nSTRING: 'STRING';\nSTRUCT: 'STRUCT';\nSUBSTR: 'SUBSTR';\nSUBSTRING: 'SUBSTRING';\nSYNC: 'SYNC';\nSYSTEM_TIME: 'SYSTEM_TIME';\nSYSTEM_VERSION: 'SYSTEM_VERSION';\nTABLE: 'TABLE';\nTABLES: 'TABLES';\nTABLESAMPLE: 'TABLESAMPLE';\nTAG: 'TAG';\nTARGET: 'TARGET';\nTBLPROPERTIES: 'TBLPROPERTIES';\nTEMPORARY: 'TEMPORARY' | 'TEMP';\nTERMINATED: 'TERMINATED';\nTHEN: 'THEN';\nTIME: 'TIME';\nTIMESTAMP: 'TIMESTAMP';\nTIMESTAMP_LTZ: 'TIMESTAMP_LTZ';\nTIMESTAMP_NTZ: 'TIMESTAMP_NTZ';\nTIMESTAMPADD: 'TIMESTAMPADD';\nTIMESTAMPDIFF: 'TIMESTAMPDIFF';\nTINYINT: 'TINYINT';\nTO: 'TO';\nTOUCH: 'TOUCH';\nTRAILING: 'TRAILING';\nTRANSACTION: 'TRANSACTION';\nTRANSACTIONS: 'TRANSACTIONS';\nTRANSFORM: 'TRANSFORM';\nTRIM: 'TRIM';\nTRUE: 'TRUE';\nTRUNCATE: 'TRUNCATE';\nTRY_CAST: 'TRY_CAST';\nTYPE: 'TYPE';\nUNARCHIVE: 'UNARCHIVE';\nUNBOUNDED: 'UNBOUNDED';\nUNCACHE: 'UNCACHE';\nUNION: 'UNION';\nUNIQUE: 'UNIQUE';\nUNKNOWN: 'UNKNOWN';\nUNLOCK: 'UNLOCK';\nUNPIVOT: 'UNPIVOT';\nUNSET: 'UNSET';\nUPDATE: 'UPDATE';\nUNORDERED: 'UNORDERED';\nUSE: 'USE';\nUSER: 'USER';\nUSING: 'USING';\nVALUES: 'VALUES';\nVARCHAR: 'VARCHAR';\nVERSION: 'VERSION';\nVIEW: 'VIEW';\nVIEWS: 'VIEWS';\nVOID: 'VOID';\nWEEK: 'WEEK';\nWEEKS: 'WEEKS';\nWHEN: 'WHEN';\nWHERE: 'WHERE';\nWINDOW: 'WINDOW';\nWITH: 'WITH';\nWITHIN: 'WITHIN';\nWRITE: 'WRITE';\nYEAR: 'YEAR';\nYEARS: 'YEARS';\nZONE: 'ZONE';\n\n// delta\nVACUUM: 'VACUUM';\nINVENTORY: 'INVENTORY';\nDRY: 'DRY';\nRUN: 'RUN';\nOPTIMIZE: 'OPTIMIZE';\nZORDER: 'ZORDER';\nDETAIL: 'DETAIL';\nHISTORY: 'HISTORY';\nFEATURE: 'FEATURE';\nNONE: 'NONE';\nIDENTITY: 'IDENTITY';\n\nINCLUDING: 'INCLUDING';\nEXCLUDING: 'EXCLUDING';\n//--SPARK-KEYWORD-LIST-END\n//============================\n// End of the keywords list\n//============================\n\nEQ  : '=' | '==';\nNSEQ: '<=>';\nNEQ : '<>';\nNEQJ: '!=';\nLT  : '<';\nLTE : '<=' | '!>';\nGT  : '>';\nGTE : '>=' | '!<';\n\nPLUS: '+';\nMINUS: '-';\nASTERISK: '*';\nSLASH: '/';\nPERCENT: '%';\nTILDE: '~';\nAMPERSAND: '&';\nPIPE: '|';\nCONCAT_PIPE: '||';\nHAT: '^';\nCOLON: ':';\nARROW: '->';\nFAT_ARROW : '=>';\nHENT_START: '/*+';\nHENT_END: '*/';\nQUESTION: '?';\n\nSTRING_LITERAL\n    : '\\'' ( ~('\\''|'\\\\') | ('\\\\' .) )* '\\''\n    | 'R\\'' (~'\\'')* '\\''\n    | 'R\"'(~'\"')* '\"'\n    ;\n\nDOUBLEQUOTED_STRING\n    :'\"' ( ~('\"'|'\\\\') | ('\\\\' .) )* '\"'\n    ;\n\n// NOTE: If you move a numeric literal, you should modify `ParserUtils.toExprAlias()`\n// which assumes all numeric literals are between `BIGINT_LITERAL` and `BIGDECIMAL_LITERAL`.\n\nBIGINT_LITERAL\n    : DIGIT+ 'L'\n    ;\n\nSMALLINT_LITERAL\n    : DIGIT+ 'S'\n    ;\n\nTINYINT_LITERAL\n    : DIGIT+ 'Y'\n    ;\n\nINTEGER_VALUE\n    : DIGIT+\n    ;\n\nEXPONENT_VALUE\n    : DIGIT+ EXPONENT\n    | DECIMAL_DIGITS EXPONENT {isValidDecimal()}?\n    ;\n\nDECIMAL_VALUE\n    : DECIMAL_DIGITS {isValidDecimal()}?\n    ;\n\nFLOAT_LITERAL\n    : DIGIT+ EXPONENT? 'F'\n    | DECIMAL_DIGITS EXPONENT? 'F' {isValidDecimal()}?\n    ;\n\nDOUBLE_LITERAL\n    : DIGIT+ EXPONENT? 'D'\n    | DECIMAL_DIGITS EXPONENT? 'D' {isValidDecimal()}?\n    ;\n\nBIGDECIMAL_LITERAL\n    : DIGIT+ EXPONENT? 'BD'\n    | DECIMAL_DIGITS EXPONENT? 'BD' {isValidDecimal()}?\n    ;\n\nIDENTIFIER\n    : (LETTER | DIGIT | '_')+\n    ;\n\nBACKQUOTED_IDENTIFIER\n    : '`' ( ~'`' | '``' )* '`'\n    ;\n\nfragment DECIMAL_DIGITS\n    : DIGIT+ '.' DIGIT*\n    | '.' DIGIT+\n    ;\n\nfragment EXPONENT\n    : 'E' [+-]? DIGIT+\n    ;\n\nfragment DIGIT\n    : [0-9]\n    ;\n\nfragment LETTER\n    : [A-Z]\n    ;\n\nSIMPLE_COMMENT\n    : '--' ('\\\\\\n' | ~[\\r\\n])* '\\r'? '\\n'? -> channel(HIDDEN)\n    ;\n\nBRACKETED_COMMENT\n    : '/*' {!isHint()}? ( BRACKETED_COMMENT | . )*? ('*/' | {markUnclosedComment();} EOF) -> channel(HIDDEN)\n    ;\n\nWS\n    : [ \\r\\n\\t]+ -> channel(HIDDEN)\n    ;\n\n// Catch-all for anything we can't recognize.\n// We use this to be able to ignore and recover all the text\n// when splitting statements with DelimiterLexer\nUNRECOGNIZED\n    : .\n    ;\n"
  },
  {
    "path": "superior-spark-parser/src/main/antlr4/io/github/melin/superior/parser/spark/antlr4/SparkSqlParser.g4",
    "content": "/*\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * This file is an adaptation of Presto's presto-parser/src/main/antlr4/com/facebook/presto/sql/parser/SqlBase.g4 grammar.\n */\n\nparser grammar SparkSqlParser;\n\noptions { tokenVocab = SparkSqlLexer; }\n\n@members {\n  /**\n   * When false, INTERSECT is given the greater precedence over the other set\n   * operations (UNION, EXCEPT and MINUS) as per the SQL standard.\n   */\n  public boolean legacy_setops_precedence_enabled = false;\n\n  /**\n   * When false, a literal with an exponent would be converted into\n   * double type rather than decimal type.\n   */\n  public boolean legacy_exponent_literal_as_decimal_enabled = false;\n\n  /**\n   * When true, the behavior of keywords follows ANSI SQL standard.\n   */\n  public boolean SQL_standard_keyword_behavior = false;\n\n  /**\n   * When true, double quoted literals are identifiers rather than STRINGs.\n   */\n  public boolean double_quoted_identifiers = false;\n}\n\nsqlStatements\n    : singleStatement* EOF\n    ;\n\nsingleStatement\n    : statement SEMICOLON?\n    ;\n\nsingleExpression\n    : namedExpression EOF\n    ;\n\nsingleTableIdentifier\n    : tableIdentifier EOF\n    ;\n\nsingleMultipartIdentifier\n    : multipartIdentifier EOF\n    ;\n\nsingleFunctionIdentifier\n    : functionIdentifier EOF\n    ;\n\nsingleDataType\n    : dataType EOF\n    ;\n\nsingleTableSchema\n    : colTypeList EOF\n    ;\n\nstatement\n    : query                                                            #statementDefault\n    | ctes? dmlStatementNoWith                                         #dmlStatement\n    | USE identifierReference                                          #use\n    | USE namespace identifierReference                                #useNamespace\n    | SET CATALOG (identifier | stringLit)                             #setCatalog\n    | CREATE namespace (IF NOT EXISTS)? identifierReference\n        (commentSpec |\n         locationSpec |\n         (WITH (DBPROPERTIES | PROPERTIES) propertyList))*             #createNamespace\n    | ALTER namespace identifierReference\n        SET (DBPROPERTIES | PROPERTIES) propertyList                   #setNamespaceProperties\n    | ALTER namespace identifierReference\n        SET locationSpec                                               #setNamespaceLocation\n    | DROP namespace (IF EXISTS)? identifierReference\n        (RESTRICT | CASCADE)?                                          #dropNamespace\n    | SHOW namespaces ((FROM | IN) multipartIdentifier)?\n        (LIKE? pattern=stringLit)?                                     #showNamespaces\n    | createTableHeader (LEFT_PAREN createOrReplaceTableColTypeList RIGHT_PAREN)? tableProvider?\n        createTableClauses\n        (AS? query)?                                                   #createTable\n    | CREATE TABLE (IF NOT EXISTS)? target=tableIdentifier\n        LIKE source=tableIdentifier\n        (tableProvider |\n        rowFormat |\n        createFileFormat |\n        locationSpec |\n        (LIFECYCLE lifecycle=INTEGER_VALUE) |\n        (TBLPROPERTIES tableProps=propertyList))*                      #createTableLike\n    | replaceTableHeader (LEFT_PAREN createOrReplaceTableColTypeList RIGHT_PAREN)? tableProvider?\n        createTableClauses\n        (AS? query)?                                                   #replaceTable\n    | ANALYZE TABLE identifierReference partitionSpec? COMPUTE STATISTICS\n        (identifier | FOR COLUMNS identifierSeq | FOR ALL COLUMNS)?    #analyze\n    | ANALYZE TABLES ((FROM | IN) identifierReference)? COMPUTE STATISTICS\n        (identifier)?                                                  #analyzeTables\n    | ALTER TABLE identifierReference\n        ADD (COLUMN | COLUMNS)\n        columns=qualifiedColTypeWithPositionList                       #addTableColumns\n    | ALTER TABLE identifierReference\n        ADD (COLUMN | COLUMNS)\n        LEFT_PAREN columns=qualifiedColTypeWithPositionList RIGHT_PAREN #addTableColumns\n    | ALTER TABLE table=identifierReference\n        RENAME COLUMN\n        from=multipartIdentifier TO to=errorCapturingIdentifier        #renameTableColumn\n    | ALTER TABLE identifierReference\n        DROP (COLUMN | COLUMNS) (IF EXISTS)?\n        LEFT_PAREN columns=multipartIdentifierList RIGHT_PAREN         #dropTableColumns\n    | ALTER TABLE identifierReference\n        DROP (COLUMN | COLUMNS) (IF EXISTS)?\n        columns=multipartIdentifierList                                #dropTableColumns\n    | ALTER (TABLE | VIEW) from=identifierReference\n        RENAME TO to=multipartIdentifier                               #renameTable\n    | ALTER (TABLE | VIEW) identifierReference\n        SET TBLPROPERTIES propertyList                                 #setTableProperties\n    | ALTER (TABLE | VIEW) identifierReference\n        UNSET TBLPROPERTIES (IF EXISTS)? propertyList                  #unsetTableProperties\n    | ALTER TABLE table=identifierReference\n        (ALTER | CHANGE) COLUMN? column=multipartIdentifier\n        alterColumnAction?                                             #alterTableAlterColumn\n    | ALTER TABLE table=identifierReference partitionSpec?\n        CHANGE COLUMN?\n        colName=multipartIdentifier colType colPosition?               #hiveChangeColumn\n    | ALTER TABLE table=identifierReference partitionSpec?\n        REPLACE COLUMNS\n        LEFT_PAREN columns=qualifiedColTypeWithPositionList\n        RIGHT_PAREN                                                    #hiveReplaceColumns\n    | ALTER TABLE identifierReference (partitionSpec)?\n        SET SERDE stringLit (WITH SERDEPROPERTIES propertyList)?       #setTableSerDe\n    | ALTER TABLE identifierReference (partitionSpec)?\n        SET SERDEPROPERTIES propertyList                               #setTableSerDe\n    | ALTER (TABLE | VIEW) identifierReference ADD (IF NOT EXISTS)?\n        partitionSpecLocation+                                         #addTablePartition\n    | ALTER TABLE identifierReference\n        from=partitionSpec RENAME TO to=partitionSpec                  #renameTablePartition\n    | ALTER TABLE table=identifierReference\n        TOUCH partitionSpec?                                           #touchTable\n    | ALTER (TABLE | VIEW) identifierReference DROP (IF EXISTS)?\n        dropPartitionSpec (',' dropPartitionSpec)* PURGE?        #dropTablePartitions\n    | ALTER TABLE identifierReference\n        (partitionSpec)? SET locationSpec                              #setTableLocation\n    | ALTER TABLE identifierReference RECOVER PARTITIONS               #recoverPartitions\n    | DROP TABLE (IF EXISTS)? identifierReference PURGE?               #dropTable\n    | DROP VIEW (IF EXISTS)? identifierReference                       #dropView\n    | CREATE (OR REPLACE)? (GLOBAL? TEMPORARY)?\n        VIEW (IF NOT EXISTS)? identifierReference\n        identifierCommentList?\n        (commentSpec |\n         (PARTITIONED ON identifierList) |\n         (TBLPROPERTIES propertyList))*\n        AS query                                                       #createView\n    | CREATE (OR REPLACE)? GLOBAL? TEMPORARY VIEW\n        tableIdentifier (LEFT_PAREN colTypeList RIGHT_PAREN)? tableProvider\n        (OPTIONS propertyList)?                                        #createTempViewUsing\n    | ALTER VIEW identifierReference AS? query                         #alterViewQuery\n    | CREATE (OR REPLACE)? TEMPORARY? FUNCTION (IF NOT EXISTS)?\n        identifierReference AS className=stringLit\n        (USING resource (COMMA resource)*)?                            #createFunction\n    | DROP TEMPORARY? FUNCTION (IF EXISTS)? identifierReference        #dropFunction\n    | EXPLAIN (LOGICAL | FORMATTED | EXTENDED | CODEGEN | COST)?\n        statement                                                      #explain\n    | SHOW TABLES ((FROM | IN) identifierReference)?\n        (LIKE? pattern=stringLit)?                                     #showTables\n    | SHOW TABLE EXTENDED ((FROM | IN) ns=identifierReference)?\n        LIKE pattern=stringLit partitionSpec?                          #showTableExtended\n    | SHOW TBLPROPERTIES table=identifierReference\n        (LEFT_PAREN key=propertyKey RIGHT_PAREN)?                      #showTblProperties\n    | SHOW COLUMNS (FROM | IN) table=identifierReference\n        ((FROM | IN) ns=multipartIdentifier)?                          #showColumns\n    | SHOW VIEWS ((FROM | IN) identifierReference)?\n        (LIKE? pattern=stringLit)?                                     #showViews\n    | SHOW PARTITIONS identifierReference partitionSpec?               #showPartitions\n    | SHOW identifier? FUNCTIONS ((FROM | IN) ns=identifierReference)?\n        (LIKE? (legacy=multipartIdentifier | pattern=stringLit))?      #showFunctions\n    | SHOW CREATE TABLE identifierReference (AS SERDE)?                #showCreateTable\n    | SHOW CURRENT namespace                                           #showCurrentNamespace\n    | SHOW CATALOGS (LIKE? pattern=stringLit)?                         #showCatalogs\n    | (DESC | DESCRIBE) FUNCTION EXTENDED? describeFuncName            #describeFunction\n    | (DESC | DESCRIBE) namespace EXTENDED?\n        identifierReference                                            #describeNamespace\n    | (DESC | DESCRIBE) DETAIL multipartIdentifier                                          #describeDeltaDetail\n    | (DESC | DESCRIBE) HISTORY multipartIdentifier (LIMIT limit=INTEGER_VALUE)?            #describeDeltaHistory\n    | (DESC | DESCRIBE) TABLE? option=(EXTENDED | FORMATTED)?\n        identifierReference partitionSpec? describeColName?            #describeRelation\n    | (DESC | DESCRIBE) QUERY? query                                   #describeQuery\n    | COMMENT ON namespace identifierReference IS\n        comment                                                        #commentNamespace\n    | COMMENT ON TABLE identifierReference IS comment                  #commentTable\n    | REFRESH TABLE identifierReference                                #refreshTable\n    | REFRESH FUNCTION identifierReference                             #refreshFunction\n    | REFRESH (stringLit | .*?)                                        #refreshResource\n    | CACHE LAZY? TABLE identifierReference\n        (OPTIONS options=propertyList)? (AS? query)?                   #cacheTable\n    | UNCACHE TABLE (IF EXISTS)? identifierReference                   #uncacheTable\n    | CLEAR CACHE                                                      #clearCache\n    | LOAD DATA LOCAL? INPATH path=stringLit OVERWRITE? INTO TABLE\n        identifierReference partitionSpec?                             #loadData\n    | TRUNCATE TABLE identifierReference partitionSpec?                #truncateTable\n    | (MSCK)? REPAIR TABLE identifierReference\n        (option=(ADD|DROP|SYNC) PARTITIONS)?                           #repairTable\n    | op=(ADD | LIST) identifier .*?                                   #manageResource\n    | SET ROLE setKey                                                     #failNativeCommand\n    | SET TIME ZONE interval                                           #setTimeZone\n    | SET TIME ZONE timezone                                           #setTimeZone\n    | SET TIME ZONE setKey                                                #setTimeZone\n    | SET setKey EQ configValue                                           #setQuotedConfiguration\n    | SET setKey                                                          #setConfiguration\n    | RESET setKey                                                       #resetConfiguration\n    | CREATE INDEX (IF NOT EXISTS)? identifier ON TABLE?\n        identifierReference (USING indexType=identifier)?\n        LEFT_PAREN columns=multipartIdentifierPropertyList RIGHT_PAREN\n        (OPTIONS options=propertyList)?                                #createIndex\n    | DROP INDEX (IF EXISTS)? identifier ON TABLE? identifierReference #dropIndex\n\n    | MERGE TABLE multipartIdentifier partitionSpec?\n            (OPTIONS options=propertyList)?                            #mergeFile\n\n    | CREATE TEMPORARY? VIEW multipartIdentifier tableProvider\n        FILE path=stringLit\n        (OPTIONS options=propertyList)?\n        createFileViewClauses                                          #createFileView\n    | ctes? EXPORT TABLE multipartIdentifier partitionSpec?\n        TO filePath=stringLit\n        (OPTIONS options=propertyList)?\n        exportTableClauses                                             #exportTable\n\n    | ctes? DATATUNNEL SOURCE LEFT_PAREN sourceName=stringLit RIGHT_PAREN OPTIONS\n        sourceOpts=dtPropertyList\n        (TRANSFORM EQ transfromSql=stringLit)?\n        SINK LEFT_PAREN sinkName=stringLit RIGHT_PAREN\n        (OPTIONS sinkOpts=dtPropertyList)?\n        (PROPERTIES properties=dtPropertyList)?                        #datatunnelExpr\n\n    | DISTCP OPTIONS options=dtPropertyList\n        (PROPERTIES properties=dtPropertyList)?                        #distCpExpr\n\n    | DATATUNNEL HELP dtType=(SOURCE | SINK | ALL)\n        LEFT_PAREN value=stringLit RIGHT_PAREN                         #datatunnelHelp\n    | CALL HELP callHelpExpr?                                          #callHelp\n    | CALL multipartIdentifier\n        LEFT_PAREN callArgument (COMMA callArgument)* RIGHT_PAREN      #call\n    | SYNC dtType=(DATABASE|TABLE) FROM source=multipartIdentifier\n      (SET OWNER principal=identifier)?                                #syncTableMeta\n\n    // iceberg sql extensions\n    | ALTER TABLE multipartIdentifier ADD PARTITION FIELD transform (AS name=identifier)?   #addPartitionField\n    | ALTER TABLE multipartIdentifier DROP PARTITION FIELD transform                        #dropPartitionField\n    | ALTER TABLE multipartIdentifier REPLACE PARTITION FIELD transform\n        WITH transform (AS name=identifier)?                                                #replacePartitionField\n    | ALTER TABLE multipartIdentifier WRITE writeSpec                                       #setWriteDistributionAndOrdering\n    | ALTER TABLE multipartIdentifier SET IDENTIFIER_KW FIELDS fieldList                    #setIdentifierFields\n    | ALTER TABLE multipartIdentifier DROP IDENTIFIER_KW FIELDS fieldList                   #dropIdentifierFields\n    | ALTER TABLE multipartIdentifier createReplaceBranchClause                             #createOrReplaceBranch\n    | ALTER TABLE multipartIdentifier createReplaceTagClause                                #createOrReplaceTag\n    | ALTER TABLE multipartIdentifier DROP BRANCH (IF EXISTS)? identifier                   #dropBranch\n    | ALTER TABLE multipartIdentifier DROP TAG (IF EXISTS)? identifier                      #dropTag\n\n    // delta sql extensions\n    | VACUUM table=multipartIdentifier\n            (USING INVENTORY (inventoryTable=multipartIdentifier | LEFT_PAREN inventoryQuery=query RIGHT_PAREN))?\n            (RETAIN number HOURS)? (DRY RUN)?                                               #vacuumTable\n    | ALTER TABLE multipartIdentifier ADD CONSTRAINT name=identifier constraint             #addTableConstraint\n    | ALTER TABLE multipartIdentifier\n            DROP CONSTRAINT (IF EXISTS)? name=identifier                                    #dropTableConstraint\n    | ALTER TABLE multipartIdentifier\n            DROP FEATURE featureName=featureNameValue (TRUNCATE HISTORY)?                   #alterTableDropFeature\n    | ALTER TABLE multipartIdentifier (clusterBySpec | CLUSTER BY NONE)                     #alterTableClusterBy\n    | ALTER TABLE table=multipartIdentifier\n            (ALTER | CHANGE) COLUMN? column=multipartIdentifier SYNC IDENTITY               #alterTableSyncIdentity\n    | OPTIMIZE multipartIdentifier whereClause? (zorderSpec)?                               #optimizeTable\n\n    | unsupportedHiveNativeCommands .*?                                                     #failNativeCommand\n    ;\n\nsetKey\n    : (identifier | DECIMAL_VALUE | '.' | MINUS)+\n    | DOUBLEQUOTED_STRING\n    ;\n\ntimezone\n    : stringLit\n    | LOCAL\n    ;\n\nconfigKey\n    : quotedIdentifier\n    ;\n\nconfigValue\n    : number\n    | (identifier | '.' | MINUS)+\n    | booleanValue\n    | DOUBLEQUOTED_STRING\n    ;\n\ncallArgument\n    : expression\n    | identifier FAT_ARROW expression\n    ;\n\ncallHelpExpr\n    : LEFT_PAREN callArgument RIGHT_PAREN\n    | identifier\n    ;\n\ndtPropertyList\n    : LEFT_PAREN dtProperty (COMMA dtProperty)* RIGHT_PAREN\n    ;\n\ncolumnDef\n    : LEFT_BRACE dtColProperty (COMMA dtColProperty)* RIGHT_BRACE\n    ;\n\ndtProperty\n    : key=dtPropertyKey (EQ? value=dtPropertyValue)?\n    ;\n\ndtColProperty\n    : key=dtPropertyKey (COLON? value=dtPropertyValue)?\n    ;\n\ndtPropertyKey\n    : identifier (DOT identifier)*\n    | DOUBLEQUOTED_STRING\n    | stringLit\n    ;\n\ndtPropertyValue\n    : INTEGER_VALUE\n    | DECIMAL_VALUE\n    | booleanValue\n    | DOUBLEQUOTED_STRING\n    | stringLit\n    | LEFT_BRACKET dtPropertyValue (',' dtPropertyValue)* RIGHT_BRACKET\n    | LEFT_BRACKET columnDef (COMMA columnDef)* RIGHT_BRACKET\n    ;\n\ncreateFileViewClauses\n    : ((COMPRESSION compressionName = identifier) |\n      (SIZE_LIMIT sizelimit = identifier))*\n    ;\n\nexportTableClauses\n    : ((FORMAT fileformatName = identifier) |\n      (COMPRESSION compressionName = identifier) |\n      (OVERWRITE overwrite = booleanValue) |\n      (MAX_FILE_SIZE maxfilesize = identifier) |\n      (SINGLE single = booleanValue))*\n    ;\n\ncreateReplaceTagClause\n    : (CREATE OR)? REPLACE TAG identifier tagOptions\n    | CREATE TAG (IF NOT EXISTS)? identifier tagOptions\n    ;\n\ncreateReplaceBranchClause\n    : (CREATE OR)? REPLACE BRANCH identifier branchOptions\n    | CREATE BRANCH (IF NOT EXISTS)? identifier branchOptions\n    ;\n\ntagOptions\n    : (AS OF VERSION snapshotId)? (refRetain)?\n    ;\n\nbranchOptions\n    : (AS OF VERSION snapshotId)? (refRetain)? (snapshotRetention)?\n    ;\n\nsnapshotId\n    : number\n    ;\n\ntimeUnit\n    : DAYS\n    | HOURS\n    | MINUTES\n    ;\n\nsnapshotRetention\n    : WITH SNAPSHOT RETENTION minSnapshotsToKeep\n    | WITH SNAPSHOT RETENTION maxSnapshotAge\n    | WITH SNAPSHOT RETENTION minSnapshotsToKeep maxSnapshotAge\n    ;\n\nrefRetain\n    : RETAIN number timeUnit\n    ;\n\nmaxSnapshotAge\n    : number timeUnit\n    ;\n\nminSnapshotsToKeep\n    : number SNAPSHOTS\n    ;\n\nwriteSpec\n    : (writeDistributionSpec | writeOrderingSpec)*\n    ;\n\nwriteDistributionSpec\n    : DISTRIBUTED BY PARTITION\n    ;\n\nwriteOrderingSpec\n    : LOCALLY? ORDERED BY orderExpr\n    | UNORDERED\n    ;\n\norderExpr\n    : fields+=orderField (',' fields+=orderField)*\n    | '(' fields+=orderField (',' fields+=orderField)* ')'\n    ;\n\norderField\n    : transform direction=(ASC | DESC)? (NULLS nullOrder=(FIRST | LAST))?\n    ;\n\nfieldList\n    : fields+=multipartIdentifier (',' fields+=multipartIdentifier)*\n    ;\n\nzorderSpec\n    : ZORDER BY LEFT_PAREN interleave+=qualifiedName (COMMA interleave+=qualifiedName)* RIGHT_PAREN\n    | ZORDER BY interleave+=qualifiedName (COMMA interleave+=qualifiedName)*\n    ;\n\nclusterBySpec\n    : CLUSTER BY LEFT_PAREN interleave+=qualifiedName (COMMA interleave+=qualifiedName)* RIGHT_PAREN\n    ;\n\nconstraint\n    : CHECK '(' exprToken+ ')'                                 #checkConstraint\n    ;\n\nexprToken\n    :  .+?\n    ;\n\nfeatureNameValue\n    : identifier\n    | stringLit\n    ;\n\nunsupportedHiveNativeCommands\n    : kw1=CREATE kw2=ROLE\n    | kw1=DROP kw2=ROLE\n    | kw1=GRANT kw2=ROLE?\n    | kw1=REVOKE kw2=ROLE?\n    | kw1=SHOW kw2=GRANT\n    | kw1=SHOW kw2=ROLE kw3=GRANT?\n    | kw1=SHOW kw2=PRINCIPALS\n    | kw1=SHOW kw2=ROLES\n    | kw1=SHOW kw2=CURRENT kw3=ROLES\n    | kw1=EXPORT kw2=TABLE\n    | kw1=IMPORT kw2=TABLE\n    | kw1=SHOW kw2=COMPACTIONS\n    | kw1=SHOW kw2=CREATE kw3=TABLE\n    | kw1=SHOW kw2=TRANSACTIONS\n    | kw1=SHOW kw2=INDEXES\n    | kw1=SHOW kw2=LOCKS\n    | kw1=CREATE kw2=INDEX\n    | kw1=DROP kw2=INDEX\n    | kw1=ALTER kw2=INDEX\n    | kw1=LOCK kw2=TABLE\n    | kw1=LOCK kw2=DATABASE\n    | kw1=UNLOCK kw2=TABLE\n    | kw1=UNLOCK kw2=DATABASE\n    | kw1=CREATE kw2=TEMPORARY kw3=MACRO\n    | kw1=DROP kw2=TEMPORARY kw3=MACRO\n    | kw1=ALTER kw2=TABLE tableIdentifier kw3=NOT kw4=CLUSTERED\n    | kw1=ALTER kw2=TABLE tableIdentifier kw3=CLUSTERED kw4=BY\n    | kw1=ALTER kw2=TABLE tableIdentifier kw3=NOT kw4=SORTED\n    | kw1=ALTER kw2=TABLE tableIdentifier kw3=SKEWED kw4=BY\n    | kw1=ALTER kw2=TABLE tableIdentifier kw3=NOT kw4=SKEWED\n    | kw1=ALTER kw2=TABLE tableIdentifier kw3=NOT kw4=STORED kw5=AS kw6=DIRECTORIES\n    | kw1=ALTER kw2=TABLE tableIdentifier kw3=SET kw4=SKEWED kw5=LOCATION\n    | kw1=ALTER kw2=TABLE tableIdentifier kw3=EXCHANGE kw4=PARTITION\n    | kw1=ALTER kw2=TABLE tableIdentifier kw3=ARCHIVE kw4=PARTITION\n    | kw1=ALTER kw2=TABLE tableIdentifier kw3=UNARCHIVE kw4=PARTITION\n    | kw1=ALTER kw2=TABLE tableIdentifier kw3=TOUCH\n    | kw1=ALTER kw2=TABLE tableIdentifier partitionSpec? kw3=COMPACT\n    | kw1=ALTER kw2=TABLE tableIdentifier partitionSpec? kw3=CONCATENATE\n    | kw1=ALTER kw2=TABLE tableIdentifier partitionSpec? kw3=SET kw4=FILEFORMAT\n    | kw1=ALTER kw2=TABLE tableIdentifier partitionSpec? kw3=REPLACE kw4=COLUMNS\n    | kw1=START kw2=TRANSACTION\n    | kw1=COMMIT\n    | kw1=ROLLBACK\n    | kw1=DFS\n    ;\n\ncreateTableHeader\n    : CREATE TEMPORARY? EXTERNAL? TABLE (IF NOT EXISTS)? identifierReference\n    ;\n\nreplaceTableHeader\n    : (CREATE OR)? REPLACE TABLE identifierReference\n    ;\n\nbucketSpec\n    : CLUSTERED BY identifierList\n      (SORTED BY orderedIdentifierList)?\n      INTO INTEGER_VALUE BUCKETS\n    ;\n\nskewSpec\n    : SKEWED BY identifierList\n      ON (constantList | nestedConstantList)\n      (STORED AS DIRECTORIES)?\n    ;\n\nlocationSpec\n    : LOCATION stringLit\n    ;\n\ncommentSpec\n    : COMMENT stringLit\n    ;\n\nquery\n    : ctes? queryTerm queryOrganization\n    ;\n\ninsertInto\n    : INSERT (hints+=hint)* OVERWRITE TABLE? identifierReference (partitionSpec (IF NOT EXISTS)?)?  ((BY NAME) | identifierList)? #insertOverwriteTable\n    | INSERT (hints+=hint)* INTO TABLE? identifierReference partitionSpec? (IF NOT EXISTS)? ((BY NAME) | identifierList)?   #insertIntoTable\n    | INSERT (hints+=hint)* INTO TABLE? identifierReference REPLACE whereClause                                             #insertIntoReplaceWhere\n    | INSERT (hints+=hint)* OVERWRITE LOCAL? DIRECTORY path=stringLit rowFormat? createFileFormat?                     #insertOverwriteHiveDir\n    | INSERT (hints+=hint)* OVERWRITE LOCAL? DIRECTORY (path=stringLit)? tableProvider (OPTIONS options=propertyList)? #insertOverwriteDir\n    ;\n\npartitionSpecLocation\n    : partitionSpec locationSpec?\n    ;\n\npartitionSpec\n    : PARTITION LEFT_PAREN partitionVal (COMMA partitionVal)* RIGHT_PAREN\n    ;\n\npartitionVal\n    : identifier (EQ constant)?\n    | identifier EQ DEFAULT\n    ;\n\nnamespace\n    : NAMESPACE\n    | DATABASE\n    | SCHEMA\n    ;\n\nnamespaces\n    : NAMESPACES\n    | DATABASES\n    | SCHEMAS\n    ;\n\ndropPartitionSpec\n    : PARTITION '(' dropPartitionVal (',' dropPartitionVal)* ')'\n    ;\n\ndropPartitionVal\n    : identifier (comparisonOperator constant)?\n    ;\n\ndescribeFuncName\n    : identifierReference\n    | stringLit\n    | comparisonOperator\n    | arithmeticOperator\n    | predicateOperator\n    ;\n\ndescribeColName\n    : nameParts+=identifier (DOT nameParts+=identifier)*\n    ;\n\nctes\n    : WITH namedQuery (COMMA namedQuery)*\n    ;\n\nnamedQuery\n    : name=errorCapturingIdentifier (columnAliases=identifierList)? AS? LEFT_PAREN query RIGHT_PAREN\n    ;\n\ntableProvider\n    : USING multipartIdentifier\n    ;\n\ncreateTableClauses\n    :((OPTIONS options=expressionPropertyList) |\n     (PARTITIONED BY partitioning=partitionFieldList) |\n     skewSpec |\n     bucketSpec |\n     rowFormat |\n     createFileFormat |\n     locationSpec |\n     commentSpec |\n     (LIFECYCLE lifecycle=INTEGER_VALUE) |\n     (TBLPROPERTIES tableProps=propertyList))*\n    ;\n\npropertyList\n    : LEFT_PAREN property (COMMA property)* RIGHT_PAREN\n    ;\n\nproperty\n    : key=propertyKey (EQ? value=propertyValue)?\n    ;\n\npropertyKey\n    : identifier (DOT identifier)*\n    | stringLit\n    ;\n\npropertyValue\n    : INTEGER_VALUE\n    | DECIMAL_VALUE\n    | booleanValue\n    | stringLit\n    ;\n\nexpressionPropertyList\n    : LEFT_PAREN expressionProperty (COMMA expressionProperty)* RIGHT_PAREN\n    ;\n\nexpressionProperty\n    : key=propertyKey (EQ? value=expression)?\n    ;\n\nconstantList\n    : LEFT_PAREN constant (COMMA constant)* RIGHT_PAREN\n    ;\n\nnestedConstantList\n    : LEFT_PAREN constantList (COMMA constantList)* RIGHT_PAREN\n    ;\n\ncreateFileFormat\n    : STORED AS fileFormat\n    | STORED BY storageHandler\n    ;\n\nfileFormat\n    : INPUTFORMAT inFmt=stringLit OUTPUTFORMAT outFmt=stringLit    #tableFileFormat\n    | identifier                                             #genericFileFormat\n    ;\n\nstorageHandler\n    : stringLit (WITH SERDEPROPERTIES propertyList)?\n    ;\n\nresource\n    : identifier stringLit\n    ;\n\ndmlStatementNoWith\n    : insertInto query                                                             #singleInsertQuery\n    | fromClause multiInsertQueryBody+                                             #multiInsertQuery\n    | DELETE FROM identifierReference tableAlias whereClause?                      #deleteFromTable\n    | UPDATE identifierReference tableAlias setClause whereClause?                 #updateTable\n    | MERGE INTO target=identifierReference targetAlias=tableAlias\n        USING (source=identifierReference |\n          LEFT_PAREN sourceQuery=query RIGHT_PAREN) sourceAlias=tableAlias\n        ON mergeCondition=booleanExpression\n        matchedClause*\n        notMatchedClause*\n        notMatchedBySourceClause*                                                  #mergeIntoTable\n    ;\n\nidentifierReference\n    : IDENTIFIER_KW LEFT_PAREN expression RIGHT_PAREN\n    | multipartIdentifier\n    ;\n\nqueryOrganization\n    : (ORDER BY order+=sortItem (COMMA order+=sortItem)*)?\n      (CLUSTER BY clusterBy+=expression (COMMA clusterBy+=expression)*)?\n      (DISTRIBUTE BY distributeBy+=expression (COMMA distributeBy+=expression)*)?\n      (SORT BY sort+=sortItem (COMMA sort+=sortItem)*)?\n      windowClause?\n      (LIMIT (ALL | limit=expression))?\n      (OFFSET offset=expression)?\n    ;\n\nmultiInsertQueryBody\n    : insertInto fromStatementBody\n    ;\n\nqueryTerm\n    : queryPrimary                                                                       #queryTermDefault\n    | left=queryTerm {legacy_setops_precedence_enabled}?\n        operator=(INTERSECT | UNION | EXCEPT | SETMINUS) setQuantifier? right=queryTerm  #setOperation\n    | left=queryTerm {!legacy_setops_precedence_enabled}?\n        operator=INTERSECT setQuantifier? right=queryTerm                                #setOperation\n    | left=queryTerm {!legacy_setops_precedence_enabled}?\n        operator=(UNION | EXCEPT | SETMINUS) setQuantifier? right=queryTerm              #setOperation\n    ;\n\nqueryPrimary\n    : querySpecification                                                    #queryPrimaryDefault\n    | fromStatement                                                         #fromStmt\n    | TABLE identifierReference                                             #table\n    | inlineTable                                                           #inlineTableDefault1\n    | LEFT_PAREN query RIGHT_PAREN                                          #subquery\n    ;\n\nsortItem\n    : expression ordering=(ASC | DESC)? (NULLS nullOrder=(LAST | FIRST))?\n    ;\n\nfromStatement\n    : fromClause fromStatementBody+\n    ;\n\nfromStatementBody\n    : selectClause\n      lateralView*\n      whereClause?\n      aggregationClause?\n      havingClause?\n      windowClause?\n      queryOrganization\n    | transformClause\n      whereClause?\n      queryOrganization\n    ;\n\nquerySpecification\n    : transformClause\n      fromClause?\n      lateralView*\n      whereClause?\n      aggregationClause?\n      havingClause?\n      windowClause?                                                         #transformQuerySpecification\n    | selectClause\n      fromClause?\n      lateralView*\n      whereClause?\n      aggregationClause?\n      havingClause?\n      windowClause?                                                         #regularQuerySpecification\n    ;\n\ntransformClause\n    : (SELECT kind=TRANSFORM LEFT_PAREN setQuantifier? expressionSeq RIGHT_PAREN\n            | kind=MAP setQuantifier? expressionSeq\n            | kind=REDUCE setQuantifier? expressionSeq)\n      inRowFormat=rowFormat?\n      (RECORDWRITER recordWriter=stringLit)?\n      USING script=stringLit\n      (AS (identifierSeq | colTypeList | (LEFT_PAREN (identifierSeq | colTypeList) RIGHT_PAREN)))?\n      outRowFormat=rowFormat?\n      (RECORDREADER recordReader=stringLit)?\n    ;\n\nselectClause\n    : SELECT (hints+=hint)* setQuantifier? namedExpressionSeq\n    ;\n\nsetClause\n    : SET assignmentList\n    ;\n\nmatchedClause\n    : WHEN MATCHED (AND matchedCond=booleanExpression)? THEN matchedAction\n    ;\nnotMatchedClause\n    : WHEN NOT MATCHED (BY TARGET)? (AND notMatchedCond=booleanExpression)? THEN notMatchedAction\n    ;\n\nnotMatchedBySourceClause\n    : WHEN NOT MATCHED BY SOURCE (AND notMatchedBySourceCond=booleanExpression)? THEN notMatchedBySourceAction\n    ;\n\nmatchedAction\n    : DELETE\n    | UPDATE SET ASTERISK\n    | UPDATE SET assignmentList\n    ;\n\nnotMatchedAction\n    : INSERT ASTERISK\n    | INSERT LEFT_PAREN columns=multipartIdentifierList RIGHT_PAREN\n        VALUES LEFT_PAREN expression (COMMA expression)* RIGHT_PAREN\n    ;\n\nnotMatchedBySourceAction\n    : DELETE\n    | UPDATE SET assignmentList\n    ;\n\nassignmentList\n    : assignment (COMMA assignment)*\n    ;\n\nassignment\n    : key=multipartIdentifier EQ value=expression\n    ;\n\nwhereClause\n    : WHERE booleanExpression\n    ;\n\nhavingClause\n    : HAVING booleanExpression\n    ;\n\nhint\n    : HENT_START hintStatements+=hintStatement (COMMA? hintStatements+=hintStatement)* HENT_END\n    ;\n\nhintStatement\n    : hintName=identifier\n    | hintName=identifier LEFT_PAREN parameters+=primaryExpression (COMMA parameters+=primaryExpression)* RIGHT_PAREN\n    ;\n\nfromClause\n    : FROM relation (COMMA relation)* lateralView* pivotClause? unpivotClause?\n    ;\n\ntemporalClause\n    : FOR? (SYSTEM_VERSION | VERSION) AS OF version\n    | FOR? (SYSTEM_TIME | TIMESTAMP) AS OF timestamp=valueExpression\n    ;\n\naggregationClause\n    : GROUP BY groupingExpressionsWithGroupingAnalytics+=groupByClause\n        (COMMA groupingExpressionsWithGroupingAnalytics+=groupByClause)*\n    | GROUP BY groupingExpressions+=expression (COMMA groupingExpressions+=expression)* (\n      WITH kind=ROLLUP\n    | WITH kind=CUBE\n    | kind=GROUPING SETS LEFT_PAREN groupingSet (COMMA groupingSet)* RIGHT_PAREN)?\n    ;\n\ngroupByClause\n    : groupingAnalytics\n    | expression\n    ;\n\ngroupingAnalytics\n    : (ROLLUP | CUBE) LEFT_PAREN groupingSet (COMMA groupingSet)* RIGHT_PAREN\n    | GROUPING SETS LEFT_PAREN groupingElement (COMMA groupingElement)* RIGHT_PAREN\n    ;\n\ngroupingElement\n    : groupingAnalytics\n    | groupingSet\n    ;\n\ngroupingSet\n    : LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN\n    | expression\n    ;\n\npivotClause\n    : PIVOT LEFT_PAREN aggregates=namedExpressionSeq FOR pivotColumn IN LEFT_PAREN pivotValues+=pivotValue (COMMA pivotValues+=pivotValue)* RIGHT_PAREN RIGHT_PAREN\n    ;\n\npivotColumn\n    : identifiers+=identifier\n    | LEFT_PAREN identifiers+=identifier (COMMA identifiers+=identifier)* RIGHT_PAREN\n    ;\n\npivotValue\n    : expression (AS? identifier)?\n    ;\n\nunpivotClause\n    : UNPIVOT nullOperator=unpivotNullClause? LEFT_PAREN\n        operator=unpivotOperator\n      RIGHT_PAREN (AS? identifier)?\n    ;\n\nunpivotNullClause\n    : (INCLUDE | EXCLUDE) NULLS\n    ;\n\nunpivotOperator\n    : (unpivotSingleValueColumnClause | unpivotMultiValueColumnClause)\n    ;\n\nunpivotSingleValueColumnClause\n    : unpivotValueColumn FOR unpivotNameColumn IN LEFT_PAREN unpivotColumns+=unpivotColumnAndAlias (COMMA unpivotColumns+=unpivotColumnAndAlias)* RIGHT_PAREN\n    ;\n\nunpivotMultiValueColumnClause\n    : LEFT_PAREN unpivotValueColumns+=unpivotValueColumn (COMMA unpivotValueColumns+=unpivotValueColumn)* RIGHT_PAREN\n      FOR unpivotNameColumn\n      IN LEFT_PAREN unpivotColumnSets+=unpivotColumnSet (COMMA unpivotColumnSets+=unpivotColumnSet)* RIGHT_PAREN\n    ;\n\nunpivotColumnSet\n    : LEFT_PAREN unpivotColumns+=unpivotColumn (COMMA unpivotColumns+=unpivotColumn)* RIGHT_PAREN unpivotAlias?\n    ;\n\nunpivotValueColumn\n    : identifier\n    ;\n\nunpivotNameColumn\n    : identifier\n    ;\n\nunpivotColumnAndAlias\n    : unpivotColumn unpivotAlias?\n    ;\n\nunpivotColumn\n    : multipartIdentifier\n    ;\n\nunpivotAlias\n    : AS? identifier\n    ;\n\nlateralView\n    : LATERAL VIEW (OUTER)? qualifiedName LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN tblName=identifier (AS? colName+=identifier (COMMA colName+=identifier)*)?\n    ;\n\nsetQuantifier\n    : DISTINCT\n    | ALL\n    ;\n\nrelation\n    : LATERAL? relationPrimary relationExtension*\n    ;\n\nrelationExtension\n    : joinRelation\n    | pivotClause\n    | unpivotClause\n    ;\n\njoinRelation\n    : (joinType) JOIN LATERAL? right=relationPrimary joinCriteria?\n    | NATURAL joinType JOIN LATERAL? right=relationPrimary\n    ;\n\njoinType\n    : INNER?\n    | CROSS\n    | LEFT OUTER?\n    | LEFT? SEMI\n    | RIGHT OUTER?\n    | FULL OUTER?\n    | LEFT? ANTI\n    ;\n\njoinCriteria\n    : ON booleanExpression\n    | USING identifierList\n    ;\n\nsample\n    : TABLESAMPLE LEFT_PAREN sampleMethod? RIGHT_PAREN (REPEATABLE LEFT_PAREN seed=INTEGER_VALUE RIGHT_PAREN)?\n    ;\n\nsampleMethod\n    : negativeSign=MINUS? percentage=(INTEGER_VALUE | DECIMAL_VALUE) PERCENTLIT   #sampleByPercentile\n    | expression ROWS                                                             #sampleByRows\n    | sampleType=BUCKET numerator=INTEGER_VALUE OUT OF denominator=INTEGER_VALUE\n        (ON (identifier | qualifiedName LEFT_PAREN RIGHT_PAREN))?                 #sampleByBucket\n    | bytes=expression                                                            #sampleByBytes\n    ;\n\nidentifierList\n    : LEFT_PAREN identifierSeq RIGHT_PAREN\n    ;\n\nidentifierSeq\n    : ident+=errorCapturingIdentifier (COMMA ident+=errorCapturingIdentifier)*\n    ;\n\norderedIdentifierList\n    : LEFT_PAREN orderedIdentifier (COMMA orderedIdentifier)* RIGHT_PAREN\n    ;\n\norderedIdentifier\n    : ident=errorCapturingIdentifier ordering=(ASC | DESC)?\n    ;\n\nidentifierCommentList\n    : LEFT_PAREN identifierComment (COMMA identifierComment)* RIGHT_PAREN\n    ;\n\nidentifierComment\n    : identifier commentSpec?\n    ;\n\nrelationPrimary\n    : identifierReference temporalClause?\n      sample? tableAlias                                    #tableName\n    | LEFT_PAREN query RIGHT_PAREN sample? tableAlias       #aliasedQuery\n    | LEFT_PAREN relation RIGHT_PAREN sample? tableAlias    #aliasedRelation\n    | inlineTable                                           #inlineTableDefault2\n    | functionTable                                         #tableValuedFunction\n    ;\n\ninlineTable\n    : VALUES expression (COMMA expression)* tableAlias\n    ;\n\nfunctionTableSubqueryArgument\n    : TABLE identifierReference\n    | TABLE LEFT_PAREN identifierReference RIGHT_PAREN\n    | TABLE LEFT_PAREN query RIGHT_PAREN\n    ;\n\nfunctionTableNamedArgumentExpression\n    : key=identifier FAT_ARROW table=functionTableSubqueryArgument\n    ;\n\nfunctionTableReferenceArgument\n    : functionTableSubqueryArgument\n    | functionTableNamedArgumentExpression\n    ;\n\nfunctionTableArgument\n    : functionTableReferenceArgument\n    | functionArgument\n    ;\n\nfunctionTable\n    : funcName=functionName LEFT_PAREN\n      (functionTableArgument (COMMA functionTableArgument)*)?\n      RIGHT_PAREN tableAlias\n    ;\n\ntableAlias\n    : (AS? strictIdentifier identifierList?)?\n    ;\n\nrowFormat\n    : ROW FORMAT SERDE name=stringLit (WITH SERDEPROPERTIES props=propertyList)?       #rowFormatSerde\n    | ROW FORMAT DELIMITED\n      (FIELDS TERMINATED BY fieldsTerminatedBy=stringLit (ESCAPED BY escapedBy=stringLit)?)?\n      (COLLECTION ITEMS TERMINATED BY collectionItemsTerminatedBy=stringLit)?\n      (MAP KEYS TERMINATED BY keysTerminatedBy=stringLit)?\n      (LINES TERMINATED BY linesSeparatedBy=stringLit)?\n      (NULL DEFINED AS nullDefinedAs=stringLit)?                                       #rowFormatDelimited\n    ;\n\nmultipartIdentifierList\n    : multipartIdentifier (COMMA multipartIdentifier)*\n    ;\n\nmultipartIdentifier\n    : parts+=errorCapturingIdentifier (DOT parts+=errorCapturingIdentifier)*\n    ;\n\nmultipartIdentifierPropertyList\n    : multipartIdentifierProperty (COMMA multipartIdentifierProperty)*\n    ;\n\nmultipartIdentifierProperty\n    : multipartIdentifier (OPTIONS options=propertyList)?\n    ;\n\ntableIdentifier\n    : (db=errorCapturingIdentifier DOT)? table=errorCapturingIdentifier\n    ;\n\nfunctionIdentifier\n    : (db=errorCapturingIdentifier DOT)? function=errorCapturingIdentifier\n    ;\n\nnamedExpression\n    : expression (AS? (name=errorCapturingIdentifier | identifierList))?\n    ;\n\nnamedExpressionSeq\n    : namedExpression (COMMA namedExpression)*\n    ;\n\npartitionFieldList\n    : LEFT_PAREN fields+=partitionField (COMMA fields+=partitionField)* RIGHT_PAREN\n    ;\n\npartitionField\n    : transform  #partitionTransform\n    | colType    #partitionColumn\n    ;\n\ntransform\n    : qualifiedName                                                                             #identityTransform\n    | transformName=identifier\n      LEFT_PAREN argument+=transformArgument (COMMA argument+=transformArgument)* RIGHT_PAREN   #applyTransform\n    ;\n\ntransformArgument\n    : qualifiedName\n    | constant\n    ;\n\nexpression\n    : booleanExpression\n    ;\n\nnamedArgumentExpression\n    : key=identifier FAT_ARROW value=expression\n    ;\n\nfunctionArgument\n    : expression\n    | namedArgumentExpression\n    ;\n\nexpressionSeq\n    : expression (COMMA expression)*\n    ;\n\nbooleanExpression\n    : NOT booleanExpression                                        #logicalNot\n    | EXISTS LEFT_PAREN query RIGHT_PAREN                          #exists\n    | valueExpression predicate?                                   #predicated\n    | left=booleanExpression operator=AND right=booleanExpression  #logicalBinary\n    | left=booleanExpression operator=OR right=booleanExpression   #logicalBinary\n    ;\n\npredicate\n    : NOT? kind=BETWEEN lower=valueExpression AND upper=valueExpression\n    | NOT? kind=IN LEFT_PAREN expression (COMMA expression)* RIGHT_PAREN\n    | NOT? kind=IN LEFT_PAREN query RIGHT_PAREN\n    | NOT? kind=RLIKE pattern=valueExpression\n    | NOT? kind=(LIKE | ILIKE) quantifier=(ANY | SOME | ALL) (LEFT_PAREN RIGHT_PAREN | LEFT_PAREN expression (COMMA expression)* RIGHT_PAREN)\n    | NOT? kind=(LIKE | ILIKE) pattern=valueExpression (ESCAPE escapeChar=stringLit)?\n    | IS NOT? kind=NULL\n    | IS NOT? kind=(TRUE | FALSE | UNKNOWN)\n    | IS NOT? kind=DISTINCT FROM right=valueExpression\n    ;\n\nvalueExpression\n    : primaryExpression                                                                      #valueExpressionDefault\n    | operator=(MINUS | PLUS | TILDE) valueExpression                                        #arithmeticUnary\n    | left=valueExpression operator=(ASTERISK | SLASH | PERCENT | DIV) right=valueExpression #arithmeticBinary\n    | left=valueExpression operator=(PLUS | MINUS | CONCAT_PIPE) right=valueExpression       #arithmeticBinary\n    | left=valueExpression operator=AMPERSAND right=valueExpression                          #arithmeticBinary\n    | left=valueExpression operator=HAT right=valueExpression                                #arithmeticBinary\n    | left=valueExpression operator=PIPE right=valueExpression                               #arithmeticBinary\n    | left=valueExpression comparisonOperator right=valueExpression                          #comparison\n    ;\n\ndatetimeUnit\n    : YEAR | QUARTER | MONTH\n    | WEEK | DAY | DAYOFYEAR\n    | HOUR | MINUTE | SECOND | MILLISECOND | MICROSECOND\n    ;\n\nprimaryExpression\n    : name=(CURRENT_DATE | CURRENT_TIMESTAMP | CURRENT_USER | USER)                                   #currentLike\n    | name=(TIMESTAMPADD | DATEADD | DATE_ADD) LEFT_PAREN (unit=datetimeUnit | invalidUnit=stringLit) COMMA unitsAmount=valueExpression COMMA timestamp=valueExpression RIGHT_PAREN             #timestampadd\n    | name=(TIMESTAMPDIFF | DATEDIFF | DATE_DIFF) LEFT_PAREN (unit=datetimeUnit | invalidUnit=stringLit) COMMA startTimestamp=valueExpression COMMA endTimestamp=valueExpression RIGHT_PAREN    #timestampdiff\n    | CASE whenClause+ (ELSE elseExpression=expression)? END                                   #searchedCase\n    | CASE value=expression whenClause+ (ELSE elseExpression=expression)? END                  #simpleCase\n    | name=(CAST | TRY_CAST) LEFT_PAREN expression AS dataType RIGHT_PAREN                     #cast\n    | STRUCT LEFT_PAREN (argument+=namedExpression (COMMA argument+=namedExpression)*)? RIGHT_PAREN #struct\n    | FIRST LEFT_PAREN expression (IGNORE NULLS)? RIGHT_PAREN                                  #first\n    | ANY_VALUE LEFT_PAREN expression (IGNORE NULLS)? RIGHT_PAREN                              #any_value\n    | LAST LEFT_PAREN expression (IGNORE NULLS)? RIGHT_PAREN                                   #last\n    | POSITION LEFT_PAREN substr=valueExpression IN str=valueExpression RIGHT_PAREN            #position\n    | constant                                                                                 #constantDefault\n    | ASTERISK                                                                                 #star\n    | qualifiedName DOT ASTERISK                                                               #star\n    | LEFT_PAREN namedExpression (COMMA namedExpression)+ RIGHT_PAREN                          #rowConstructor\n    | LEFT_PAREN query RIGHT_PAREN                                                             #subqueryExpression\n    | IDENTIFIER_KW LEFT_PAREN expression RIGHT_PAREN                                          #identifierClause\n    | functionName LEFT_PAREN (setQuantifier? argument+=functionArgument\n       (COMMA argument+=functionArgument)*)? RIGHT_PAREN\n       (FILTER LEFT_PAREN WHERE where=booleanExpression RIGHT_PAREN)?\n       (nullsOption=(IGNORE | RESPECT) NULLS)? ( OVER windowSpec)?                             #functionCall\n    | identifier ARROW expression                                                              #lambda\n    | LEFT_PAREN identifier (COMMA identifier)+ RIGHT_PAREN ARROW expression                   #lambda\n    | value=primaryExpression LEFT_BRACKET index=valueExpression RIGHT_BRACKET                 #subscript\n    | identifier                                                                               #columnReference\n    | base=primaryExpression DOT fieldName=identifier                                          #dereference\n    | LEFT_PAREN expression RIGHT_PAREN                                                        #parenthesizedExpression\n    | EXTRACT LEFT_PAREN field=identifier FROM source=valueExpression RIGHT_PAREN              #extract\n    | (SUBSTR | SUBSTRING) LEFT_PAREN str=valueExpression (FROM | COMMA) pos=valueExpression\n      ((FOR | COMMA) len=valueExpression)? RIGHT_PAREN                                         #substring\n    | TRIM LEFT_PAREN trimOption=(BOTH | LEADING | TRAILING)? (trimStr=valueExpression)?\n       FROM srcStr=valueExpression RIGHT_PAREN                                                 #trim\n    | OVERLAY LEFT_PAREN input=valueExpression PLACING replace=valueExpression\n      FROM position=valueExpression (FOR length=valueExpression)? RIGHT_PAREN                  #overlay\n    | name=(PERCENTILE_CONT | PERCENTILE_DISC) LEFT_PAREN percentage=valueExpression RIGHT_PAREN\n        WITHIN GROUP LEFT_PAREN ORDER BY sortItem RIGHT_PAREN\n        (FILTER LEFT_PAREN WHERE where=booleanExpression RIGHT_PAREN)? ( OVER windowSpec)?     #percentile\n    ;\n\nliteralType\n    : DATE\n    | TIMESTAMP | TIMESTAMP_LTZ | TIMESTAMP_NTZ\n    | INTERVAL\n    | BINARY_HEX\n    | unsupportedType=identifier\n    ;\n\nconstant\n    : NULL                                                                                     #nullLiteral\n    | QUESTION                                                                                 #posParameterLiteral\n    | COLON identifier                                                                         #namedParameterLiteral\n    | interval                                                                                 #intervalLiteral\n    | literalType stringLit                                                                    #typeConstructor\n    | number                                                                                   #numericLiteral\n    | booleanValue                                                                             #booleanLiteral\n    | stringLit+                                                                               #stringLiteral\n    ;\n\ncomparisonOperator\n    : EQ | NEQ | NEQJ | LT | LTE | GT | GTE | NSEQ\n    ;\n\narithmeticOperator\n    : PLUS | MINUS | ASTERISK | SLASH | PERCENT | DIV | TILDE | AMPERSAND | PIPE | CONCAT_PIPE | HAT\n    ;\n\npredicateOperator\n    : OR | AND | IN | NOT\n    ;\n\nbooleanValue\n    : TRUE | FALSE\n    ;\n\ninterval\n    : INTERVAL (errorCapturingMultiUnitsInterval | errorCapturingUnitToUnitInterval)\n    ;\n\nerrorCapturingMultiUnitsInterval\n    : body=multiUnitsInterval unitToUnitInterval?\n    ;\n\nmultiUnitsInterval\n    : (intervalValue unit+=unitInMultiUnits)+\n    ;\n\nerrorCapturingUnitToUnitInterval\n    : body=unitToUnitInterval (error1=multiUnitsInterval | error2=unitToUnitInterval)?\n    ;\n\nunitToUnitInterval\n    : value=intervalValue from=unitInUnitToUnit TO to=unitInUnitToUnit\n    ;\n\nintervalValue\n    : (PLUS | MINUS)?\n      (INTEGER_VALUE | DECIMAL_VALUE | stringLit)\n    ;\n\nunitInMultiUnits\n    : NANOSECOND | NANOSECONDS | MICROSECOND | MICROSECONDS | MILLISECOND | MILLISECONDS\n    | SECOND | SECONDS | MINUTE | MINUTES | HOUR | HOURS | DAY | DAYS | WEEK | WEEKS\n    | MONTH | MONTHS | YEAR | YEARS\n    ;\n\nunitInUnitToUnit\n    : SECOND | MINUTE | HOUR | DAY | MONTH | YEAR\n    ;\n\ncolPosition\n    : position=FIRST | position=AFTER afterCol=errorCapturingIdentifier\n    ;\n\ntype\n    : BOOLEAN\n    | TINYINT | BYTE\n    | SMALLINT | SHORT\n    | INT | INTEGER\n    | BIGINT | LONG\n    | FLOAT | REAL\n    | DOUBLE\n    | DATE\n    | TIMESTAMP | TIMESTAMP_NTZ | TIMESTAMP_LTZ\n    | STRING\n    | CHARACTER | CHAR\n    | VARCHAR\n    | BINARY\n    | DECIMAL | DEC | NUMERIC\n    | VOID\n    | INTERVAL\n    | ARRAY | STRUCT | MAP\n    | unsupportedType=identifier\n    ;\n\ndataType\n    : complex=ARRAY LT dataType GT                              #complexDataType\n    | complex=MAP LT dataType COMMA dataType GT                 #complexDataType\n    | complex=STRUCT (LT complexColTypeList? GT | NEQ)          #complexDataType\n    | INTERVAL from=(YEAR | MONTH) (TO to=MONTH)?               #yearMonthIntervalDataType\n    | INTERVAL from=(DAY | HOUR | MINUTE | SECOND)\n      (TO to=(HOUR | MINUTE | SECOND))?                         #dayTimeIntervalDataType\n    | type (LEFT_PAREN INTEGER_VALUE\n      (COMMA INTEGER_VALUE)* RIGHT_PAREN)?                      #primitiveDataType\n    ;\n\nqualifiedColTypeWithPositionList\n    : qualifiedColTypeWithPosition (COMMA qualifiedColTypeWithPosition)*\n    ;\n\nqualifiedColTypeWithPosition\n    : name=multipartIdentifier dataType colDefinitionDescriptorWithPosition*\n    ;\n\ncolDefinitionDescriptorWithPosition\n    : NOT NULL\n    | defaultExpression\n    | commentSpec\n    | colPosition\n    ;\n\ndefaultExpression\n    : DEFAULT expression\n    ;\n\ncolTypeList\n    : colType (COMMA colType)*\n    ;\n\ncolType\n    : colName=errorCapturingIdentifier dataType (NOT NULL)? commentSpec?\n    ;\n\ncreateOrReplaceTableColTypeList\n    : createOrReplaceTableColType (COMMA createOrReplaceTableColType)*\n    ;\n\ncreateOrReplaceTableColType\n    : colName=errorCapturingIdentifier dataType colDefinitionOption*\n    ;\n\ncolDefinitionOption\n    : NOT NULL\n    | defaultExpression\n    | generationExpression\n    | commentSpec\n    ;\n\ngenerationExpression\n    : GENERATED ALWAYS AS LEFT_PAREN expression RIGHT_PAREN\n    ;\n\ncomplexColTypeList\n    : complexColType (COMMA complexColType)*\n    ;\n\ncomplexColType\n    : identifier COLON? dataType (NOT NULL)? commentSpec?\n    ;\n\nwhenClause\n    : WHEN condition=expression THEN result=expression\n    ;\n\nwindowClause\n    : WINDOW namedWindow (COMMA namedWindow)*\n    ;\n\nnamedWindow\n    : name=errorCapturingIdentifier AS windowSpec\n    ;\n\nwindowSpec\n    : name=errorCapturingIdentifier                         #windowRef\n    | LEFT_PAREN name=errorCapturingIdentifier RIGHT_PAREN  #windowRef\n    | LEFT_PAREN\n      ( CLUSTER BY partition+=expression (COMMA partition+=expression)*\n      | ((PARTITION | DISTRIBUTE) BY partition+=expression (COMMA partition+=expression)*)?\n        ((ORDER | SORT) BY sortItem (COMMA sortItem)*)?)\n      windowFrame?\n      RIGHT_PAREN                                           #windowDef\n    ;\n\nwindowFrame\n    : frameType=RANGE start=frameBound\n    | frameType=ROWS start=frameBound\n    | frameType=RANGE BETWEEN start=frameBound AND end=frameBound\n    | frameType=ROWS BETWEEN start=frameBound AND end=frameBound\n    ;\n\nframeBound\n    : UNBOUNDED boundType=(PRECEDING | FOLLOWING)\n    | boundType=CURRENT ROW\n    | expression boundType=(PRECEDING | FOLLOWING)\n    ;\n\nqualifiedNameList\n    : qualifiedName (COMMA qualifiedName)*\n    ;\n\nfunctionName\n    : IDENTIFIER_KW LEFT_PAREN expression RIGHT_PAREN\n    | qualifiedName\n    | FILTER\n    | LEFT\n    | RIGHT\n    ;\n\nqualifiedName\n    : identifier (DOT identifier)*\n    ;\n\n// this rule is used for explicitly capturing wrong identifiers such as test-table, which should actually be `test-table`\n// replace identifier with errorCapturingIdentifier where the immediate follow symbol is not an expression, otherwise\n// valid expressions such as \"a-b\" can be recognized as an identifier\nerrorCapturingIdentifier\n    : identifier errorCapturingIdentifierExtra\n    ;\n\n// extra left-factoring grammar\nerrorCapturingIdentifierExtra\n    : (MINUS identifier)+    #errorIdent\n    |                        #realIdent\n    ;\n\nidentifier\n    : strictIdentifier\n    | {!SQL_standard_keyword_behavior}? strictNonReserved\n    ;\n\nstrictIdentifier\n    : IDENTIFIER              #unquotedIdentifier\n    | quotedIdentifier        #quotedIdentifierAlternative\n    | {SQL_standard_keyword_behavior}? ansiNonReserved #unquotedIdentifier\n    | {!SQL_standard_keyword_behavior}? nonReserved    #unquotedIdentifier\n    ;\n\nquotedIdentifier\n    : BACKQUOTED_IDENTIFIER\n    | {double_quoted_identifiers}? DOUBLEQUOTED_STRING\n    ;\n\nbackQuotedIdentifier\n    : BACKQUOTED_IDENTIFIER\n    ;\n\nnumber\n    : {!legacy_exponent_literal_as_decimal_enabled}? MINUS? EXPONENT_VALUE #exponentLiteral\n    | {!legacy_exponent_literal_as_decimal_enabled}? MINUS? DECIMAL_VALUE  #decimalLiteral\n    | {legacy_exponent_literal_as_decimal_enabled}? MINUS? (EXPONENT_VALUE | DECIMAL_VALUE) #legacyDecimalLiteral\n    | MINUS? INTEGER_VALUE            #integerLiteral\n    | MINUS? BIGINT_LITERAL           #bigIntLiteral\n    | MINUS? SMALLINT_LITERAL         #smallIntLiteral\n    | MINUS? TINYINT_LITERAL          #tinyIntLiteral\n    | MINUS? DOUBLE_LITERAL           #doubleLiteral\n    | MINUS? FLOAT_LITERAL            #floatLiteral\n    | MINUS? BIGDECIMAL_LITERAL       #bigDecimalLiteral\n    ;\n\nalterColumnAction\n    : TYPE dataType\n    | commentSpec\n    | colPosition\n    | setOrDrop=(SET | DROP) NOT NULL\n    | SET defaultExpression\n    | dropDefault=DROP DEFAULT\n    ;\n\nstringLit\n    : STRING_LITERAL\n    | {!double_quoted_identifiers}? DOUBLEQUOTED_STRING\n    ;\n\ncomment\n    : stringLit\n    | NULL\n    ;\n\nversion\n    : INTEGER_VALUE\n    | stringLit\n    ;\n\n// When `SQL_standard_keyword_behavior=true`, there are 2 kinds of keywords in Spark SQL.\n// - Reserved keywords:\n//     Keywords that are reserved and can't be used as identifiers for table, view, column,\n//     function, alias, etc.\n// - Non-reserved keywords:\n//     Keywords that have a special meaning only in particular contexts and can be used as\n//     identifiers in other contexts. For example, `EXPLAIN SELECT ...` is a command, but EXPLAIN\n//     can be used as identifiers in other places.\n// You can find the full keywords list by searching \"Start of the keywords list\" in this file.\n// The non-reserved keywords are listed below. Keywords not in this list are reserved keywords.\nansiNonReserved\n//--ANSI-NON-RESERVED-START\n    : ADD\n    | AFTER\n    | ALTER\n    | ALWAYS\n    | ANALYZE\n    | ANTI\n    | ANY_VALUE\n    | ARCHIVE\n    | ARRAY\n    | ASC\n    | AT\n    | BETWEEN\n    | BIGINT\n    | BINARY\n    | BINARY_HEX\n    | BOOLEAN\n    | BUCKET\n    | BUCKETS\n    | BY\n    | BYTE\n    | CACHE\n    | CASCADE\n    | CATALOG\n    | CATALOGS\n    | CHANGE\n    | CHAR\n    | CHARACTER\n    | CLEAR\n    | CLUSTER\n    | CLUSTERED\n    | CODEGEN\n    | COLLECTION\n    | COLUMNS\n    | COMMENT\n    | COMMIT\n    | COMPACT\n    | COMPACTIONS\n    | COMPUTE\n    | CONCATENATE\n    | COST\n    | CUBE\n    | CURRENT\n    | DATA\n    | DATABASE\n    | DATABASES\n    | DATE\n    | DATEADD\n    | DATE_ADD\n    | DATEDIFF\n    | DATE_DIFF\n    | DAY\n    | DAYS\n    | DAYOFYEAR\n    | DBPROPERTIES\n    | DEC\n    | DECIMAL\n    | DEFAULT\n    | DEFINED\n    | DELETE\n    | DELIMITED\n    | DESC\n    | DESCRIBE\n    | DFS\n    | DIRECTORIES\n    | DIRECTORY\n    | DISTRIBUTE\n    | DIV\n    | DOUBLE\n    | DROP\n    | ESCAPED\n    | EXCHANGE\n    | EXCLUDE\n    | EXISTS\n    | EXPLAIN\n    | EXPORT\n    | EXTENDED\n    | EXTERNAL\n    | EXTRACT\n    | FIELD\n    | FIELDS\n    | FILEFORMAT\n    | FIRST\n    | FLOAT\n    | FOLLOWING\n    | FORMAT\n    | FORMATTED\n    | FUNCTION\n    | FUNCTIONS\n    | GENERATED\n    | GLOBAL\n    | GROUPING\n    | HOUR\n    | HOURS\n    | IDENTIFIER_KW\n    | IF\n    | IGNORE\n    | IMPORT\n    | INCLUDE\n    | INDEX\n    | INDEXES\n    | INPATH\n    | INPUTFORMAT\n    | INSERT\n    | INT\n    | INTEGER\n    | INTERVAL\n    | ITEMS\n    | KEYS\n    | LAST\n    | LAZY\n    | LIKE\n    | ILIKE\n    | LIMIT\n    | LINES\n    | LIST\n    | LOAD\n    | LOCAL\n    | LOCATION\n    | LOCK\n    | LOCKS\n    | LOGICAL\n    | LONG\n    | MACRO\n    | MAP\n    | MATCHED\n    | MERGE\n    | MICROSECOND\n    | MICROSECONDS\n    | MILLISECOND\n    | MILLISECONDS\n    | MINUTE\n    | MINUTES\n    | MONTH\n    | MONTHS\n    | MSCK\n    | NAME\n    | NAMESPACE\n    | NAMESPACES\n    | NANOSECOND\n    | NANOSECONDS\n    | NO\n    | NULLS\n    | NUMERIC\n    | OF\n    | OPTION\n    | OPTIONS\n    | OUT\n    | OUTPUTFORMAT\n    | OVER\n    | OVERLAY\n    | OVERWRITE\n    | PARTITION\n    | PARTITIONED\n    | PARTITIONS\n    | PERCENTLIT\n    | PIVOT\n    | PLACING\n    | POSITION\n    | PRECEDING\n    | PRINCIPALS\n    | PROPERTIES\n    | PURGE\n    | QUARTER\n    | QUERY\n    | RANGE\n    | REAL\n    | RECORDREADER\n    | RECORDWRITER\n    | RECOVER\n    | REDUCE\n    | REFRESH\n    | RENAME\n    | REPAIR\n    | REPEATABLE\n    | REPLACE\n    | RESET\n    | RESPECT\n    | RESTRICT\n    | REVOKE\n    | RLIKE\n    | ROLE\n    | ROLES\n    | ROLLBACK\n    | ROLLUP\n    | ROW\n    | ROWS\n    | SCHEMA\n    | SCHEMAS\n    | SECOND\n    | SECONDS\n    | SEMI\n    | SEPARATED\n    | SERDE\n    | SERDEPROPERTIES\n    | SET\n    | SETMINUS\n    | SETS\n    | SHORT\n    | SHOW\n    | SKEWED\n    | SMALLINT\n    | SORT\n    | SORTED\n    | SOURCE\n    | START\n    | STATISTICS\n    | STORED\n    | STRATIFY\n    | STRING\n    | STRUCT\n    | SUBSTR\n    | SUBSTRING\n    | SYNC\n    | SYSTEM_TIME\n    | SYSTEM_VERSION\n    | TABLES\n    | TABLESAMPLE\n    | TARGET\n    | TBLPROPERTIES\n    | TEMPORARY\n    | TERMINATED\n    | TIMESTAMP\n    | TIMESTAMP_LTZ\n    | TIMESTAMP_NTZ\n    | TIMESTAMPADD\n    | TIMESTAMPDIFF\n    | TINYINT\n    | TOUCH\n    | TRANSACTION\n    | TRANSACTIONS\n    | TRANSFORM\n    | TRIM\n    | TRUE\n    | TRUNCATE\n    | TRY_CAST\n    | TYPE\n    | UNARCHIVE\n    | UNBOUNDED\n    | UNCACHE\n    | UNLOCK\n    | UNPIVOT\n    | UNSET\n    | UPDATE\n    | USE\n    | VALUES\n    | VARCHAR\n    | VERSION\n    | VIEW\n    | VIEWS\n    | VOID\n    | WEEK\n    | WEEKS\n    | WINDOW\n    | YEAR\n    | YEARS\n    | ZONE\n\n    | COMPRESSION\n    | FILE\n    | HELP\n    | LIFECYCLE\n    | DATATUNNEL\n    | DISTCP\n    | SINK\n    | CALL\n    | OWNER\n    | SIZE_LIMIT\n    | SINGLE\n    | MAX_FILE_SIZE\n    | INCLUDING\n                                                                                                                                                                                                            //--ANSI-NON-RESERVED-END\n    ;\n\n// When `SQL_standard_keyword_behavior=false`, there are 2 kinds of keywords in Spark SQL.\n// - Non-reserved keywords:\n//     Same definition as the one when `SQL_standard_keyword_behavior=true`.\n// - Strict-non-reserved keywords:\n//     A strict version of non-reserved keywords, which can not be used as table alias.\n// You can find the full keywords list by searching \"Start of the keywords list\" in this file.\n// The strict-non-reserved keywords are listed in `strictNonReserved`.\n// The non-reserved keywords are listed in `nonReserved`.\n// These 2 together contain all the keywords.\nstrictNonReserved\n    : ANTI\n    | CROSS\n    | EXCEPT\n    | FULL\n    | INNER\n    | INTERSECT\n    | JOIN\n    | LATERAL\n    | LEFT\n    | NATURAL\n    | ON\n    | RIGHT\n    | SEMI\n    | SETMINUS\n    | UNION\n    | USING\n    ;\n\nnonReserved\n//--DEFAULT-NON-RESERVED-START\n    : ADD\n    | AFTER\n    | ALL\n    | ALTER\n    | ALWAYS\n    | ANALYZE\n    | AND\n    | ANY\n    | ANY_VALUE\n    | ARCHIVE\n    | ARRAY\n    | AS\n    | ASC\n    | AT\n    | AUTHORIZATION\n    | BETWEEN\n    | BIGINT\n    | BINARY\n    | BINARY_HEX\n    | BOOLEAN\n    | BOTH\n    | BRANCH\n    | BUCKET\n    | BUCKETS\n    | BY\n    | BYTE\n    | CACHE\n    | CASCADE\n    | CASE\n    | CAST\n    | CATALOG\n    | CATALOGS\n    | CHANGE\n    | CHAR\n    | CHARACTER\n    | CHECK\n    | CLEAR\n    | CLUSTER\n    | CLUSTERED\n    | CODEGEN\n    | COLLATE\n    | COLLECTION\n    | COLUMN\n    | COLUMNS\n    | COMMENT\n    | COMMIT\n    | COMPACT\n    | COMPACTIONS\n    | COMPUTE\n    | CONCATENATE\n    | CONSTRAINT\n    | COST\n    | CREATE\n    | CUBE\n    | CURRENT\n    | CURRENT_DATE\n    | CURRENT_TIME\n    | CURRENT_TIMESTAMP\n    | CURRENT_USER\n    | DATA\n    | DATABASE\n    | DATABASES\n    | DATE\n    | DATEADD\n    | DATE_ADD\n    | DATEDIFF\n    | DATE_DIFF\n    | DAY\n    | DAYS\n    | DAYOFYEAR\n    | DBPROPERTIES\n    | DEC\n    | DECIMAL\n    | DEFAULT\n    | DEFINED\n    | DELETE\n    | DELIMITED\n    | DESC\n    | DESCRIBE\n    | DFS\n    | DIRECTORIES\n    | DIRECTORY\n    | DISTINCT\n    | DISTRIBUTE\n    | DISTRIBUTED\n    | DIV\n    | DOUBLE\n    | DROP\n    | ELSE\n    | END\n    | ESCAPE\n    | ESCAPED\n    | EXCHANGE\n    | EXCLUDE\n    | EXISTS\n    | EXPLAIN\n    | EXPORT\n    | EXTENDED\n    | EXTERNAL\n    | EXTRACT\n    | FALSE\n    | FETCH\n    | FILTER\n    | FIELD\n    | FIELDS\n    | FILEFORMAT\n    | FIRST\n    | FLOAT\n    | FOLLOWING\n    | FOR\n    | FOREIGN\n    | FORMAT\n    | FORMATTED\n    | FROM\n    | FUNCTION\n    | FUNCTIONS\n    | GENERATED\n    | GLOBAL\n    | GRANT\n    | GROUP\n    | GROUPING\n    | HAVING\n    | HOUR\n    | HOURS\n    | IDENTIFIER_KW\n    | IF\n    | IGNORE\n    | IMPORT\n    | IN\n    | INCLUDE\n    | INDEX\n    | INDEXES\n    | INPATH\n    | INPUTFORMAT\n    | INSERT\n    | INT\n    | INTEGER\n    | INTERVAL\n    | INTO\n    | IS\n    | ITEMS\n    | KEYS\n    | LAST\n    | LAZY\n    | LEADING\n    | LIKE\n    | LONG\n    | ILIKE\n    | LIMIT\n    | LINES\n    | LIST\n    | LOAD\n    | LOCAL\n    | LOCATION\n    | LOCK\n    | LOCKS\n    | LOGICAL\n    | LONG\n    | LOCALLY\n    | MACRO\n    | MAP\n    | MATCHED\n    | MERGE\n    | MICROSECOND\n    | MICROSECONDS\n    | MILLISECOND\n    | MILLISECONDS\n    | MINUTE\n    | MINUTES\n    | MONTH\n    | MONTHS\n    | MSCK\n    | NAME\n    | NAMESPACE\n    | NAMESPACES\n    | NANOSECOND\n    | NANOSECONDS\n    | NO\n    | NOT\n    | NULL\n    | NULLS\n    | NUMERIC\n    | OF\n    | OFFSET\n    | ONLY\n    | OPTION\n    | OPTIONS\n    | OR\n    | ORDER\n    | ORDERED\n    | OUT\n    | OUTER\n    | OUTPUTFORMAT\n    | OVER\n    | OVERLAPS\n    | OVERLAY\n    | OVERWRITE\n    | PARTITION\n    | PARTITIONED\n    | PARTITIONS\n    | PERCENTILE_CONT\n    | PERCENTILE_DISC\n    | PERCENTLIT\n    | PIVOT\n    | PLACING\n    | POSITION\n    | PRECEDING\n    | PRIMARY\n    | PRINCIPALS\n    | PROPERTIES\n    | PURGE\n    | QUARTER\n    | QUERY\n    | RANGE\n    | REAL\n    | RECORDREADER\n    | RECORDWRITER\n    | RECOVER\n    | REDUCE\n    | REFERENCES\n    | REFRESH\n    | RENAME\n    | REPAIR\n    | REPEATABLE\n    | REPLACE\n    | RESET\n    | RESPECT\n    | RESTRICT\n    | RETAIN\n    | RETENTION\n    | REVOKE\n    | RLIKE\n    | ROLE\n    | ROLES\n    | ROLLBACK\n    | ROLLUP\n    | ROW\n    | ROWS\n    | SNAPSHOT\n    | SNAPSHOTS\n    | SCHEMA\n    | SCHEMAS\n    | SECOND\n    | SECONDS\n    | SELECT\n    | SEPARATED\n    | SERDE\n    | SERDEPROPERTIES\n    | SESSION_USER\n    | SET\n    | SETS\n    | SHORT\n    | SHOW\n    | SKEWED\n    | SMALLINT\n    | SOME\n    | SORT\n    | SORTED\n    | SOURCE\n    | START\n    | STATISTICS\n    | STORED\n    | STRATIFY\n    | STRING\n    | STRUCT\n    | SUBSTR\n    | SUBSTRING\n    | SYNC\n    | SYSTEM_TIME\n    | SYSTEM_VERSION\n    | TABLE\n    | TABLES\n    | TABLESAMPLE\n    | TAG\n    | TARGET\n    | TBLPROPERTIES\n    | TEMPORARY\n    | TERMINATED\n    | THEN\n    | TIME\n    | TIMESTAMP\n    | TIMESTAMP_LTZ\n    | TIMESTAMP_NTZ\n    | TIMESTAMPADD\n    | TIMESTAMPDIFF\n    | TINYINT\n    | TO\n    | TOUCH\n    | TRAILING\n    | TRANSACTION\n    | TRANSACTIONS\n    | TRANSFORM\n    | TRIM\n    | TRUE\n    | TRUNCATE\n    | TRY_CAST\n    | TYPE\n    | UNARCHIVE\n    | UNBOUNDED\n    | UNCACHE\n    | UNIQUE\n    | UNKNOWN\n    | UNLOCK\n    | UNPIVOT\n    | UNSET\n    | UPDATE\n    | USE\n    | USER\n    | UNORDERED\n    | VALUES\n    | VARCHAR\n    | VERSION\n    | VIEW\n    | VIEWS\n    | VOID\n    | WEEK\n    | WEEKS\n    | WHEN\n    | WHERE\n    | WINDOW\n    | WITH\n    | WITHIN\n    | WRITE\n    | YEAR\n    | YEARS\n    | ZONE\n\n    | COMPRESSION\n    | FILE\n    | HELP\n    | LIFECYCLE\n    | DATATUNNEL\n    | DISTCP\n    | SINK\n    | CALL\n    | OWNER\n    | SIZE_LIMIT\n    | SINGLE\n    | MAX_FILE_SIZE\n    | INCLUDING\n    | EXCLUDING\n\n    | VACUUM\n    | INVENTORY\n    | DRY\n    | RUN\n    | OPTIMIZE\n    | ZORDER\n    | DETAIL\n    | HISTORY\n    | FEATURE\n    | NONE\n    | IDENTITY\n//--DEFAULT-NON-RESERVED-END\n    ;\n"
  },
  {
    "path": "superior-spark-parser/src/main/antlr4/io/github/melin/superior/parser/spark/antlr4/SparkStreamSqlLexer.g4",
    "content": "lexer grammar SparkStreamSqlLexer;\n\nchannels { DCSTREAMCOMMENT, ERRORCHANNEL }\n\n// SKIP\n\nSPACE:                               [ \\t\\r\\n]+    -> channel(HIDDEN);\nSPEC_MYSQL_COMMENT:                  '/*!' .+? '*/' -> channel(DCSTREAMCOMMENT);\nCOMMENT_INPUT:                       '/*' .*? '*/' -> channel(HIDDEN);\nLINE_COMMENT:                        (\n                                       ('-- ' | '#') ~[\\r\\n]* ('\\r'? '\\n' | EOF)\n                                       | '--' ('\\r'? '\\n' | EOF)\n                                     ) -> channel(HIDDEN);\n\n// Keywords\n// Common Keywords\nCREATE:                              'CREATE';\nTABLE:                               'TABLE';\nSTREAM:                              'STREAM';\nWITH:                                'WITH';\nCOMMENT:                             'COMMENT';\nTRUE:                                'TRUE';\nFALSE:                               'FALSE';\nAS:                                  'AS';\nBY:                                  'BY';\nSET:                                 'SET';\nDELAY:                               'DELAY';\nINSERT:                              'INSERT';\nINTO:                                'INTO';\nUSING:                               'USING';\nPATTERN:                             'PATTERN';\n\nMINUSMINUS:                          '--';\n\n// DATA TYPE Keywords\nSTRING:                              'STRING';\nBOOLEAN:                             'BOOLEAN';\nINT:                                 'INT';\nBIGINT:                              'BIGINT';\nFLOAT:                               'FLOAT';\nDOUBLE:                              'DOUBLE';\nDATE:                                'DATE';\nTIMESTAMP:                           'TIMESTAMP';\n\n// Operators. Arithmetics\nSTAR:                                '*';\nDIVIDE:                              '/';\nMODULE:                              '%';\nPLUS:                                '+';\nMINUS:                               '-';\n\n// Operators. Comparation\nEQUAL_SYMBOL:                        '=';\nGREATER_SYMBOL:                      '>';\nLESS_SYMBOL:                         '<';\nEXCLAMATION_SYMBOL:                  '!';\n\n\n// Operators. Bit\nBIT_NOT_OP:                          '~';\nBIT_OR_OP:                           '|';\nBIT_AND_OP:                          '&';\nBIT_XOR_OP:                          '^';\n\n// Constructors symbols\nDOT:                                 '.';\nLR_BRACKET:                          '(';\nRR_BRACKET:                          ')';\nCOMMA:                               ',';\nSEMI:                                ';';\n\nID:                                  ID_LITERAL;\nREVERSE_QUOTE_ID:                    '`' ~'`'+ '`';\nSTRING_LITERAL:                      DQUOTA_STRING | SQUOTA_STRING;\nDECIMAL_LITERAL:                     DEC_DIGIT+;\nREAL_LITERAL:                        (DEC_DIGIT+)? '.' DEC_DIGIT+\n                                     | DEC_DIGIT+ '.' EXPONENT_NUM_PART\n                                     | (DEC_DIGIT+)? '.' (DEC_DIGIT+ EXPONENT_NUM_PART)\n                                     | DEC_DIGIT+ EXPONENT_NUM_PART;\n\nfragment EXPONENT_NUM_PART:          'E' '-'? DEC_DIGIT+;\nfragment ID_LITERAL:                 [A-Z_$0-9]*?[A-Z_$]+?[A-Z_$0-9]*;\nfragment DQUOTA_STRING:              '\"' ( '\\\\'. | '\"\"' | ~('\"'| '\\\\') )* '\"';\nfragment SQUOTA_STRING:              '\\'' ('\\\\'. | '\\'\\'' | ~('\\'' | '\\\\'))* '\\'';\nfragment DEC_DIGIT:                  [0-9];\n\nERROR_RECONGNIGION:                  .    -> channel(ERRORCHANNEL);\n"
  },
  {
    "path": "superior-spark-parser/src/main/antlr4/io/github/melin/superior/parser/spark/antlr4/SparkStreamSqlParser.g4",
    "content": "parser grammar SparkStreamSqlParser;\n\noptions { tokenVocab=SparkStreamSqlLexer; }\n\nroot\n    : sqlStatements? MINUSMINUS? EOF\n    ;\n\nsqlStatements\n    : (sqlStatement MINUSMINUS? SEMI | emptyStatement)*\n    (sqlStatement (MINUSMINUS? SEMI)? | emptyStatement)\n    ;\n\nsqlStatement\n    : createStreamTable | insertStatement\n    | setStatement\n    ;\n\ncreateStreamTable\n    : CREATE STREAM TABLE tableName=tableIdentifier\n      ('(' columns=colTypeList ')')?\n      WITH tableProps=tablePropertyList\n    ;\n\ninsertStatement\n    : INSERT INTO tableName=tableIdentifier\n      select = selectExpr\n    ;\n\nsetStatement\n    : SET setKeyExpr EQUAL_SYMBOL valueKeyExpr\n    ;\n\nemptyStatement\n    : SEMI\n    ;\n\nsetKeyExpr\n    : ID ('.' ID)*\n    ;\n\nvalueKeyExpr\n    : word (word)*\n    ;\n\nselectExpr\n    : word (word)*\n    ;\n\nword\n    : ID\n    | ('.' ID)\n    | STRING_LITERAL | DECIMAL_LITERAL | REAL_LITERAL | booleanValue\n    | AS | BY | SET\n    | STAR | DIVIDE | MODULE | PLUS | MINUS\n    | EQUAL_SYMBOL | GREATER_SYMBOL | LESS_SYMBOL | EXCLAMATION_SYMBOL\n    | BIT_NOT_OP | BIT_OR_OP | BIT_AND_OP | BIT_XOR_OP\n    | LR_BRACKET | RR_BRACKET | COMMA | TABLE\n    ;\n\ncolTypeList\n    : colType (',' colType)*\n    ;\n\ncolType\n    : ID (jsonPath=STRING_LITERAL)? dataType (PATTERN pattern=STRING_LITERAL)? (COMMENT comment=STRING_LITERAL)?\n    ;\n\ndataType\n    : STRING | BOOLEAN | INT | BIGINT\n    | FLOAT | DOUBLE\n    | DATE  | TIMESTAMP\n    ;\n\ntablePropertyList\n    : '(' tableProperty (',' tableProperty)* ')'\n    ;\n\ntableProperty\n    : key=tablePropertyKey EQUAL_SYMBOL value=tablePropertyValue\n    ;\n\ntablePropertyKey\n    : ID ('.' ID)*\n    | STRING_LITERAL\n    ;\n\ntablePropertyValue\n    : DECIMAL_LITERAL\n    | booleanValue\n    | STRING_LITERAL\n    ;\n\nbooleanValue\n    : TRUE | FALSE\n    ;\n\ntableIdentifier\n    : (db=identifier '.')? table=identifier\n    ;\n\nidentifier\n    : ID\n    ;\n"
  },
  {
    "path": "superior-spark-parser/src/main/java/io/github/melin/superior/parser/spark/SparkSqlPostProcessor.java",
    "content": "package io.github.melin.superior.parser.spark;\n\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser;\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParserBaseListener;\nimport org.antlr.v4.runtime.CommonToken;\nimport org.antlr.v4.runtime.ParserRuleContext;\nimport org.antlr.v4.runtime.Token;\nimport org.antlr.v4.runtime.misc.Pair;\n\npublic class SparkSqlPostProcessor extends SparkSqlParserBaseListener {\n\n    /** Remove the back ticks from an Identifier. */\n    @Override\n    public void exitQuotedIdentifier(SparkSqlParser.QuotedIdentifierContext ctx) {\n        ParserRuleContext parent = ctx.getParent();\n        parent.removeLastChild();\n        Token token = (Token) ctx.getChild(0).getPayload();\n\n        CommonToken commonToken = new CommonToken(\n                new org.antlr.v4.runtime.misc.Pair(token.getTokenSource(), token.getInputStream()),\n                SparkSqlParser.IDENTIFIER,\n                token.getChannel(),\n                token.getStartIndex() + 1,\n                token.getStopIndex() - 1);\n\n        commonToken.setText(commonToken.getText().replace(\"``\", \"`\"));\n        parent.addChild(commonToken);\n    }\n\n    /** Treat non-reserved keywords as Identifiers. */\n    @Override\n    public void exitNonReserved(SparkSqlParser.NonReservedContext ctx) {\n        ParserRuleContext parent = ctx.getParent();\n        parent.removeLastChild();\n        Token token = (Token) ctx.getChild(0).getPayload();\n\n        parent.addChild(new CommonToken(\n                new Pair(token.getTokenSource(), token.getInputStream()),\n                SparkSqlParser.IDENTIFIER,\n                token.getChannel(),\n                token.getStartIndex() + 0,\n                token.getStopIndex() - 0));\n    }\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/AbstractSparkStreamSqlParser.kt",
    "content": "package io.github.melin.superior.parser.spark\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.spark.antlr4.SparkStreamSqlParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSparkStreamSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(SparkStreamSqlParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: SparkStreamSqlParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(SparkStreamSqlParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/AbstractSqlParser.kt",
    "content": "package io.github.melin.superior.parser.spark\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(SparkSqlParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: SparkSqlParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(SparkSqlParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/SparkSqlAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.spark\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport com.google.common.collect.Lists\nimport io.github.melin.superior.common.AlterActionType\nimport io.github.melin.superior.common.AlterActionType.*\nimport io.github.melin.superior.common.SQLParserException\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.TableType\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.*\nimport io.github.melin.superior.common.relational.alter.*\nimport io.github.melin.superior.common.relational.common.*\nimport io.github.melin.superior.common.relational.create.*\nimport io.github.melin.superior.common.relational.delta.OptimizeTable\nimport io.github.melin.superior.common.relational.delta.VacuumTable\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.drop.DropDatabase\nimport io.github.melin.superior.common.relational.drop.DropFunction\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport io.github.melin.superior.common.relational.drop.DropView\nimport io.github.melin.superior.common.relational.io.ExportTable\nimport io.github.melin.superior.common.relational.table.ColumnRel\nimport io.github.melin.superior.common.relational.table.RepairTable\nimport io.github.melin.superior.common.relational.table.TruncateTable\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.AlterColumnActionContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.ColDefinitionOptionContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.CreateOrReplaceTableColTypeListContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.CreateTableClausesContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.DtColPropertyContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.DtPropertyContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.DtPropertyListContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.FromClauseContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.HintContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.IdentifierContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.InsertIntoContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.MultiInsertQueryContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.PartitionSpecContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.PropertyListContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.QueryContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.SingleInsertQueryContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser.TableProviderContext\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParserBaseVisitor\nimport io.github.melin.superior.parser.spark.relational.*\nimport java.util.LinkedList\nimport java.util.regex.Pattern\nimport org.antlr.v4.runtime.tree.RuleNode\nimport org.apache.commons.lang3.StringUtils\n\nclass SparkSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) :\n    SparkSqlParserBaseVisitor<Statement>() {\n\n    private var currentOptType: StatementType = StatementType.UNKOWN\n    private var currentAlterActionType: AlterActionType = UNKOWN\n    private var multiInsertToken: String? = null\n\n    private var limit: Int? = null\n    private var offset: Int? = null\n    private var inputTables: ArrayList<TableId> = arrayListOf()\n    private var outputTables: ArrayList<TableId> = arrayListOf()\n    private var inCte = false\n\n    private var cteTempTables: ArrayList<TableId> = arrayListOf()\n    private var functionNames: HashSet<FunctionId> = hashSetOf()\n\n    private var rows: ArrayList<List<String>> = ArrayList()\n\n    private var insertSql: Boolean = false\n\n    private var statements: ArrayList<Statement> = arrayListOf()\n    private val sqls: ArrayList<String> = arrayListOf()\n\n    fun getSqlStatements(): List<Statement> {\n        return statements\n    }\n\n    fun getSplitSqls(): List<String> {\n        return sqls\n    }\n\n    override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {\n        return if (currentResult == null) true else false\n    }\n\n    override fun visitSqlStatements(ctx: SparkSqlParser.SqlStatementsContext): Statement? {\n        ctx.singleStatement().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else {\n                        var statement = this.visitSingleStatement(it)\n                        if (statement == null) {\n                            statement = DefaultStatement(StatementType.UNKOWN)\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n\n                clean()\n            }\n        }\n        return null\n    }\n\n    private fun clean() {\n        currentOptType = StatementType.UNKOWN\n        currentAlterActionType = UNKOWN\n        multiInsertToken = null\n\n        limit = null\n        offset = null\n        inputTables = arrayListOf()\n        outputTables = arrayListOf()\n        inCte = false\n        cteTempTables = arrayListOf()\n        functionNames = hashSetOf()\n\n        rows = arrayListOf()\n\n        insertSql = false\n    }\n\n    override fun visitSingleStatement(ctx: SparkSqlParser.SingleStatementContext): Statement? {\n        val statement = super.visitSingleStatement(ctx)\n\n        if (statement == null) {\n            throw SQLParserException(\"不支持的SQL: \" + command)\n        }\n        return statement\n    }\n\n    fun parseNamespace(ctx: SparkSqlParser.IdentifierReferenceContext): Pair<String?, String> {\n        if (ctx.multipartIdentifier() == null) {\n            throw IllegalAccessException(\"not support: \" + source(ctx))\n        } else {\n            return parseNamespace(ctx.multipartIdentifier())\n        }\n    }\n\n    fun parseNamespace(ctx: SparkSqlParser.MultipartIdentifierContext): Pair<String?, String> {\n        return if (ctx.parts.size == 2) {\n            Pair(ctx.parts.get(0).text, ctx.parts.get(1).text)\n        } else if (ctx.parts.size == 1) {\n            Pair(null, ctx.parts.get(0).text)\n        } else {\n            throw SQLParserException(\"parse multipart error: \" + ctx.parts.size)\n        }\n    }\n\n    fun parseTableName(ctx: SparkSqlParser.IdentifierReferenceContext): TableId {\n        if (ctx.multipartIdentifier() == null) {\n            throw IllegalAccessException(\"not support: \" + source(ctx))\n        } else {\n            return parseTableName(ctx.multipartIdentifier())\n        }\n    }\n\n    fun parseTableName(ctx: SparkSqlParser.MultipartIdentifierContext): TableId {\n        return if (ctx.parts.size == 4) {\n            TableId(ctx.parts.get(0).text, ctx.parts.get(1).text, ctx.parts.get(2).text, ctx.parts.get(3).text)\n        } else if (ctx.parts.size == 3) {\n            TableId(ctx.parts.get(0).text, ctx.parts.get(1).text, ctx.parts.get(2).text)\n        } else if (ctx.parts.size == 2) {\n            TableId(null, ctx.parts.get(0).text, ctx.parts.get(1).text)\n        } else if (ctx.parts.size == 1) {\n            TableId(null, null, ctx.parts.get(0).text)\n        } else {\n            throw SQLParserException(\"parse multipart error: \" + ctx.parts.size)\n        }\n    }\n\n    fun parseFunctionName(ctx: SparkSqlParser.MultipartIdentifierContext): FunctionId {\n        return if (ctx.parts.size == 3) {\n            FunctionId(ctx.parts.get(0).text, ctx.parts.get(1).text, ctx.parts.get(2).text)\n        } else if (ctx.parts.size == 2) {\n            FunctionId(null, ctx.parts.get(0).text, ctx.parts.get(1).text)\n        } else if (ctx.parts.size == 1) {\n            FunctionId(null, null, ctx.parts.get(0).text)\n        } else {\n            throw SQLParserException(\"parse multipart error: \" + ctx.parts.size)\n        }\n    }\n\n    fun parseIdentifier(ctx: List<IdentifierContext>): String {\n        return ctx.map { iden -> iden.text }.joinToString(\",\")\n    }\n\n    // -----------------------------------database-------------------------------------------------\n\n    override fun visitCreateNamespace(ctx: SparkSqlParser.CreateNamespaceContext): Statement {\n        var location: String = \"\"\n        if (ctx.locationSpec().size > 0) {\n            location = ctx.locationSpec().get(0).stringLit().text\n            location = CommonUtils.cleanQuote(location)\n        }\n        val type = ctx.namespace().text.uppercase()\n\n        if (StringUtils.equalsIgnoreCase(\"database\", type) || StringUtils.equalsIgnoreCase(\"schema\", type)) {\n\n            val (catalogName, databaseName) = parseNamespace(ctx.identifierReference())\n            return CreateDatabase(catalogName, databaseName, location)\n        } else {\n            throw RuntimeException(\"not support: \" + type)\n        }\n    }\n\n    override fun visitDropNamespace(ctx: SparkSqlParser.DropNamespaceContext): Statement {\n        val type = ctx.namespace().text.uppercase()\n        if (StringUtils.equalsIgnoreCase(\"database\", type) || StringUtils.equalsIgnoreCase(\"schema\", type)) {\n\n            val (catalogName, databaseName) = parseNamespace(ctx.identifierReference())\n            return DropDatabase(catalogName, databaseName)\n        } else {\n            throw RuntimeException(\"not support: \" + type)\n        }\n    }\n\n    // -----------------------------------table-------------------------------------------------\n    override fun visitCreateTable(ctx: SparkSqlParser.CreateTableContext): Statement {\n        val tableId = parseTableName(ctx.createTableHeader().identifierReference())\n        return createTable(\n            tableId,\n            false,\n            ctx.createTableHeader().TEMPORARY() != null,\n            ctx.createTableHeader().EXTERNAL() != null,\n            ctx.createTableHeader().IF() != null,\n            ctx.createOrReplaceTableColTypeList(),\n            ctx.createTableClauses(),\n            ctx.tableProvider(),\n            ctx.query()\n        )\n    }\n\n    override fun visitReplaceTable(ctx: SparkSqlParser.ReplaceTableContext): Statement {\n        val tableId = parseTableName(ctx.replaceTableHeader().identifierReference())\n        return createTable(\n            tableId,\n            true,\n            false,\n            false,\n            false,\n            ctx.createOrReplaceTableColTypeList(),\n            ctx.createTableClauses(),\n            ctx.tableProvider(),\n            ctx.query()\n        )\n    }\n\n    private fun createTable(\n        tableId: TableId,\n        replace: Boolean,\n        temporary: Boolean,\n        external: Boolean,\n        ifNotExists: Boolean,\n        createOrReplaceTableColTypeList: CreateOrReplaceTableColTypeListContext?,\n        createTableClauses: CreateTableClausesContext,\n        tableProvider: TableProviderContext?,\n        query: QueryContext?\n    ): Statement {\n\n        val comment =\n            if (createTableClauses.commentSpec().size > 0)\n                CommonUtils.cleanQuote(createTableClauses.commentSpec(0).stringLit().text)\n            else null\n        val lifeCycle = createTableClauses.lifecycle?.text?.toInt()\n\n        var partitionColumnRels: List<ColumnRel>? = null\n        val partitionColumnNames: ArrayList<String> = arrayListOf()\n        var columnRels: List<ColumnRel>? = null\n        var modelType = \"hive\"\n        if (query == null) {\n            columnRels =\n                createOrReplaceTableColTypeList?.createOrReplaceTableColType()?.map {\n                    val colName = it.colName.text\n                    val dataType = it.dataType().text\n                    val (nullable, defaultExpr, colComment) = parseColDefinition(it.colDefinitionOption())\n                    ColumnRel(colName, dataType, colComment, nullable, defaultExpr)\n                }\n\n            if (tableProvider != null) {\n                modelType = \"spark\"\n            }\n\n            if (createTableClauses.partitioning != null) {\n                if (\"spark\" == modelType) {\n                    createTableClauses.partitioning.children\n                        .filter { it is SparkSqlParser.PartitionTransformContext }\n                        .forEach { item ->\n                            val column = item as SparkSqlParser.PartitionTransformContext\n                            partitionColumnNames.add(column.text)\n                        }\n\n                    if (partitionColumnNames.size == 0) {\n                        throw SQLParserException(\"spark create table 语法创建表，创建分区字段语法错误，请参考文档\")\n                    }\n                } else {\n                    partitionColumnRels =\n                        createTableClauses.partitioning.children\n                            .filter { it is SparkSqlParser.PartitionColumnContext }\n                            .map { item ->\n                                val column = item as SparkSqlParser.PartitionColumnContext\n                                val colName = column.colType().colName.text\n                                // primitiveDataType\n                                val dataType = column.colType().dataType().getChild(0).text\n                                checkPartitionDataType(dataType)\n\n                                partitionColumnNames.add(colName)\n                                val colComment =\n                                    if (column.colType().commentSpec() != null)\n                                        CommonUtils.cleanQuote(column.colType().commentSpec().stringLit().text)\n                                    else null\n                                ColumnRel(colName, dataType, colComment)\n                            }\n                }\n            }\n        } else {\n            if (createTableClauses.partitioning != null) {\n                createTableClauses.partitioning.children\n                    .filter { it is SparkSqlParser.PartitionTransformContext }\n                    .forEach { item ->\n                        val column = item as SparkSqlParser.PartitionTransformContext\n                        partitionColumnNames.add(column.text)\n                    }\n            }\n        }\n\n        val properties = HashMap<String, String>()\n        val options = HashMap<String, String>()\n        if (createTableClauses.tableProps != null) {\n            createTableClauses.tableProps.children\n                .filter { it is SparkSqlParser.PropertyContext }\n                .forEach { item ->\n                    val property = item as SparkSqlParser.PropertyContext\n                    val key = CommonUtils.cleanQuote(property.key.text)\n                    val value = CommonUtils.cleanQuote(property.value.text)\n                    properties.put(key, value)\n                }\n        } else if (createTableClauses.options != null) {\n            createTableClauses.options.children\n                .filter { it is SparkSqlParser.ExpressionPropertyContext }\n                .forEach { item ->\n                    val property = item as SparkSqlParser.ExpressionPropertyContext\n                    val key = CommonUtils.cleanQuote(property.key.text)\n                    val value = CommonUtils.cleanQuote(property.value.text)\n                    options.put(key, value)\n                }\n        }\n\n        var fileFormat = tableProvider?.multipartIdentifier()?.text\n        var storageHandler: String? = null\n        createTableClauses.createFileFormat()\n        if (createTableClauses.createFileFormat().size == 1) {\n            val createFileFormatContext = createTableClauses.createFileFormat().get(0)\n            if (createFileFormatContext.fileFormat() != null) {\n                fileFormat = createFileFormatContext.fileFormat().text\n            } else if (createFileFormatContext.storageHandler() != null) {\n                storageHandler = createFileFormatContext.storageHandler().stringLit().STRING_LITERAL().text\n                storageHandler = CommonUtils.cleanQuote(storageHandler)\n            }\n        }\n\n        if (query != null) {\n            currentOptType = StatementType.CREATE_TABLE_AS_SELECT\n            val queryStmt = parseQuery(query)\n\n            val createTable =\n                CreateTableAsSelect(\n                    tableId,\n                    queryStmt,\n                    comment,\n                    lifeCycle,\n                    partitionColumnRels,\n                    columnRels,\n                    properties,\n                    fileFormat,\n                    ifNotExists\n                )\n            createTable.modelType = modelType\n            createTable.replace = replace\n            createTable.options = options\n            createTable.storageHandler = storageHandler\n\n            if (partitionColumnNames.size > 0) {\n                createTable.partitionColumnNames.addAll(partitionColumnNames)\n                createTable.partitionType = PartitionType.LIST\n            }\n            return createTable\n        } else {\n            currentOptType = StatementType.CREATE_TABLE\n            val createTable =\n                CreateTable(\n                    tableId,\n                    TableType.HIVE,\n                    comment,\n                    lifeCycle,\n                    partitionColumnRels,\n                    columnRels,\n                    properties,\n                    fileFormat,\n                    ifNotExists\n                )\n            createTable.modelType = modelType\n            createTable.options = options\n            createTable.replace = replace\n            createTable.external = external\n            createTable.temporary = temporary\n            createTable.storageHandler = storageHandler\n\n            if (createTableClauses.locationSpec().size > 0) {\n                var location = createTableClauses.locationSpec().get(0).stringLit().text\n                createTable.location = CommonUtils.cleanQuote(location);\n            }\n\n            if (partitionColumnNames.size > 0) {\n                createTable.partitionColumnNames.addAll(partitionColumnNames)\n                createTable.partitionType = PartitionType.LIST\n            }\n            return createTable\n        }\n    }\n\n    override fun visitCreateTableLike(ctx: SparkSqlParser.CreateTableLikeContext): Statement {\n        val newDatabaseName = ctx.target.db?.text\n        val newTableName = ctx.target.table.text\n\n        val oldDatabaseName = ctx.source.db?.text\n        val oldTableName = ctx.source.table.text\n\n        val createTableLike =\n            CreateTableLike(TableId(oldDatabaseName, oldTableName), TableId(newDatabaseName, newTableName))\n\n        createTableLike.ifNotExists = ctx.NOT() != null\n        return createTableLike\n    }\n\n    override fun visitDropTable(ctx: SparkSqlParser.DropTableContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n\n        val dropTable = DropTable(tableId)\n        dropTable.ifExists = ctx.EXISTS() != null\n        return dropTable\n    }\n\n    override fun visitDropView(ctx: SparkSqlParser.DropViewContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        return DropView(tableId, ctx.EXISTS() != null)\n    }\n\n    override fun visitTruncateTable(ctx: SparkSqlParser.TruncateTableContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        return TruncateTable(tableId)\n    }\n\n    override fun visitRepairTable(ctx: SparkSqlParser.RepairTableContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        return RepairTable(tableId)\n    }\n\n    override fun visitRenameTable(ctx: SparkSqlParser.RenameTableContext): Statement {\n        val tableId = parseTableName(ctx.from)\n        val newTableId = parseTableName(ctx.to)\n\n        return if (ctx.VIEW() != null) {\n            val action = RenameAction(newTableId)\n            AlterView(tableId, action)\n        } else {\n            val action = RenameAction(newTableId)\n            AlterTable(tableId, action)\n        }\n    }\n\n    override fun visitSetTableProperties(ctx: SparkSqlParser.SetTablePropertiesContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        val properties = parseOptions(ctx.propertyList())\n        val action = AlterPropsAction()\n        action.properties.putAll(properties)\n\n        return if (ctx.VIEW() == null) {\n            AlterTable(tableId, action)\n        } else {\n            AlterView(tableId, action)\n        }\n    }\n\n    override fun visitSetTableSerDe(ctx: SparkSqlParser.SetTableSerDeContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        val properties = parseOptions(ctx.propertyList())\n        val action = AlterSerDeAction(properties)\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitAddTableColumns(ctx: SparkSqlParser.AddTableColumnsContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n\n        val actions =\n            ctx.columns.children\n                .filter { it is SparkSqlParser.QualifiedColTypeWithPositionContext }\n                .map { item ->\n                    val column = item as SparkSqlParser.QualifiedColTypeWithPositionContext\n                    val columnName = column.multipartIdentifier().text\n                    val dataType = column.dataType().text\n                    var comment: String? = null\n                    var position: String? = null\n                    var afterCol: String? = null\n\n                    column.colDefinitionDescriptorWithPosition().forEach { colDesc ->\n                        if (colDesc.commentSpec() != null) {\n                            comment = CommonUtils.cleanQuote(colDesc.commentSpec().stringLit().text)\n                        } else if (colDesc.colPosition() != null) {\n                            if (colDesc.colPosition() != null) {\n                                if (colDesc.colPosition().FIRST() != null) {\n                                    position = \"first\"\n                                } else if (colDesc.colPosition().AFTER() != null) {\n                                    position = \"after\"\n                                    afterCol = colDesc.colPosition().afterCol.text\n                                }\n                            }\n                        }\n                    }\n\n                    AlterColumnAction(ADD_COLUMN, columnName, dataType, comment, position, afterCol)\n                }\n\n        val alterTable = AlterTable(tableId)\n        alterTable.addActions(actions)\n        return alterTable\n    }\n\n    override fun visitHiveChangeColumn(ctx: SparkSqlParser.HiveChangeColumnContext): Statement {\n        val tableId = parseTableName(ctx.table)\n\n        val columnName = ctx.colName.parts.get(0).text\n        val newColumnName = ctx.colType().colName.text\n        val dataType = ctx.colType().dataType().text\n        val commentNode = ctx.colType().commentSpec()?.stringLit()\n        val comment = if (commentNode != null) CommonUtils.cleanQuote(commentNode.text) else null\n\n        val action = AlterColumnAction(ALTER_COLUMN, columnName, dataType, comment)\n        action.newColumName = newColumnName\n        if (ctx.colPosition() != null) {\n            if (ctx.colPosition().FIRST() != null) {\n                action.position = \"first\"\n            } else if (ctx.colPosition().AFTER() != null) {\n                action.position = \"after\"\n                action.afterCol = ctx.colPosition().afterCol.text\n            }\n        }\n\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitRenameTableColumn(ctx: SparkSqlParser.RenameTableColumnContext): Statement {\n        val tableId = parseTableName(ctx.table)\n\n        val columnName = ctx.from.text\n        val newColumnName = ctx.to.text\n\n        val action = AlterColumnAction(RENAME, columnName)\n        action.newColumName = newColumnName\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitAlterTableAlterColumn(ctx: SparkSqlParser.AlterTableAlterColumnContext): Statement {\n        val tableId = parseTableName(ctx.table)\n\n        val action = parseAlterColumnAction(ctx.alterColumnAction())\n        action.columName = ctx.column.text\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitTouchTable(ctx: SparkSqlParser.TouchTableContext): Statement {\n        val tableId = parseTableName(ctx.table)\n        val partitionVals = if (ctx.partitionSpec() != null) parsePartitionSpec(ctx.partitionSpec()) else null\n        val action = AlterTouchPartitionAction(tableId, partitionVals)\n        val alterTable = AlterTable(tableId, action)\n        return alterTable\n    }\n\n    override fun visitDropTableColumns(ctx: SparkSqlParser.DropTableColumnsContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n\n        val columns = ctx.columns.multipartIdentifier().map { id -> id.text }\n        val action = DropColumnAction(columns.joinToString(\".\"))\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitSetTableLocation(ctx: SparkSqlParser.SetTableLocationContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        val location = CommonUtils.cleanQuote(ctx.locationSpec().stringLit().text)\n\n        val action = AlterPropsAction(location)\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitMergeFile(ctx: SparkSqlParser.MergeFileContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n\n        val partitionVals = parsePartitionSpec(ctx.partitionSpec())\n        val properties = parseOptions(ctx.propertyList())\n        return MergeFileData(tableId, properties, partitionVals)\n    }\n\n    override fun visitRefreshTable(ctx: SparkSqlParser.RefreshTableContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        return RefreshStatement(tableId)\n    }\n\n    override fun visitAnalyze(ctx: SparkSqlParser.AnalyzeContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        return AnalyzeTable(listOf(tableId))\n    }\n\n    override fun visitDistCpExpr(ctx: SparkSqlParser.DistCpExprContext): Statement {\n        val options = parseDtOptions(ctx.options)\n        val properties = parseDtOptions(ctx.properties)\n        return DistCpExpr(options, properties)\n    }\n\n    override fun visitDatatunnelExpr(ctx: SparkSqlParser.DatatunnelExprContext): Statement {\n        val sourceType = CommonUtils.cleanQuote(ctx.sourceName.text)\n        val sinkType = CommonUtils.cleanQuote(ctx.sinkName.text)\n\n        currentOptType = StatementType.DATATUNNEL\n\n        if (ctx.ctes() != null) {\n            visitCtes(ctx.ctes())\n        }\n\n        val sourceOptions = parseDtOptions(ctx.sourceOpts)\n\n        var transformSql: String? = null\n        if (ctx.transfromSql != null) {\n            transformSql = CommonUtils.cleanQuote(ctx.transfromSql.text)\n        }\n\n        val sinkOptions = parseDtOptions(ctx.sinkOpts)\n        val properties = parseDtOptions(ctx.properties)\n\n        val data = DataTunnelExpr(sourceType, sourceOptions, transformSql, sinkType, sinkOptions, properties)\n        data.inputTables.addAll(inputTables)\n        data.functionNames.addAll(functionNames)\n        return data\n    }\n\n    override fun visitDatatunnelHelp(ctx: SparkSqlParser.DatatunnelHelpContext): Statement {\n        val type = if (ctx.SOURCE() != null) \"source\" else \"sink\"\n        val value = CommonUtils.cleanQuote(ctx.value.text)\n        return DataTunnelHelp(type, value)\n    }\n\n    private fun parseDtOptions(ctx: DtPropertyListContext?): HashMap<String, Any> {\n        val options = LinkedHashMap<String, Any>()\n        if (ctx != null) {\n            ctx.dtProperty().map { item ->\n                val property = item as DtPropertyContext\n                val key = CommonUtils.cleanQuote(property.key.text)\n                if (property.value.columnDef().size > 0) {\n                    val list = arrayListOf<HashMap<String, String>>()\n                    property.value.columnDef().map { col ->\n                        val map = HashMap<String, String>()\n                        col.dtColProperty().map { pt ->\n                            val colProperty = pt as DtColPropertyContext\n                            val colKey = CommonUtils.cleanQuote(colProperty.key.text)\n                            val colValue = CommonUtils.cleanQuote(colProperty.value.text)\n                            map.put(colKey, colValue)\n                        }\n                        list.add(map)\n                    }\n                    options.put(key, list)\n                } else if (property.value.dtPropertyValue().size > 0) {\n                    val list = arrayListOf<String>()\n                    property.value.dtPropertyValue().map { col ->\n                        val value = CommonUtils.cleanQuote(col.text)\n                        list.add(value)\n                    }\n                    options.put(key, list)\n                } else {\n                    val value = CommonUtils.cleanQuote(property.value.text)\n                    options.put(key, value)\n                }\n            }\n        }\n\n        return options\n    }\n\n    override fun visitCall(ctx: SparkSqlParser.CallContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        val properties = HashMap<String, String>()\n        ctx.callArgument()\n            .filter { it.FAT_ARROW() != null }\n            .forEach { item ->\n                val key = CommonUtils.cleanQuote(item.identifier().text)\n                val value = CommonUtils.cleanQuote(item.expression().text)\n                properties.put(key.lowercase(), value)\n            }\n\n        return CallProcedure(ProcedureId(tableId.catalogName, tableId.schemaName, tableId.tableName), properties)\n    }\n\n    override fun visitCallHelp(ctx: SparkSqlParser.CallHelpContext): Statement {\n        var procedure: String? = null\n        if (ctx.callHelpExpr() != null) {\n            procedure =\n                if (ctx.callHelpExpr().callArgument() != null) {\n                    CommonUtils.cleanQuote(ctx.callHelpExpr().callArgument().expression().text)\n                } else {\n                    ctx.callHelpExpr().identifier().text\n                }\n        }\n\n        return CallHelp(procedure)\n    }\n\n    override fun visitSyncTableMeta(ctx: SparkSqlParser.SyncTableMetaContext): Statement {\n        val syncType = ctx.dtType.text.lowercase()\n        var owner: String? = null\n        if (ctx.principal != null) {\n            owner = ctx.principal.text\n        }\n\n        return if (\"database\" == syncType) {\n            val source = parseNamespace(ctx.source)\n            SyncDatabaseMetadata(source.first, source.second, owner)\n        } else {\n            val sourceTableId = parseTableName(ctx.source)\n            SyncTableMetadata(sourceTableId, owner)\n        }\n    }\n\n    // -----------------------------------partition-------------------------------------------------\n\n    override fun visitAddTablePartition(ctx: SparkSqlParser.AddTablePartitionContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n\n        val partitions = ctx.partitionSpecLocation().map { parsePartitionSpec(it.partitionSpec()) }\n\n        val ifNotExists = ctx.NOT() != null\n\n        val action = AddPartitionAction(ifNotExists, partitions)\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitDropTablePartitions(ctx: SparkSqlParser.DropTablePartitionsContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        val ifExists = ctx.EXISTS() != null\n        val action = DropPartitionAction(ifExists)\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitRenameTablePartition(ctx: SparkSqlParser.RenameTablePartitionContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        val fromPartition = parsePartitionSpec(ctx.from)\n        val toPartition = parsePartitionSpec(ctx.to)\n        val action = RenamePartitionAction(fromPartition, toPartition)\n        return AlterTable(tableId, action)\n    }\n\n    // -----------------------------------view-------------------------------------------------\n\n    override fun visitCreateView(ctx: SparkSqlParser.CreateViewContext): Statement {\n        var comment: String? = null\n        if (ctx.commentSpec().size > 0) {\n            comment = ctx.commentSpec().get(0).stringLit().text\n            comment = CommonUtils.cleanQuote(comment)\n        }\n\n        val tableId = parseTableName(ctx.identifierReference())\n        val ifNotExists = ctx.NOT() != null\n        val queryStmt = parseQuery(ctx.query())\n\n        currentOptType = StatementType.CREATE_VIEW\n        this.visitQuery(ctx.query())\n\n        val columnNameList = parseColumRefs(ctx.identifierCommentList())\n        val createView = CreateView(tableId, queryStmt, comment, ifNotExists, columnNameList)\n\n        if (ctx.REPLACE() != null) {\n            createView.replace = true\n        }\n        if (ctx.TEMPORARY() != null) {\n            createView.temporary = true\n        }\n        if (ctx.GLOBAL() != null) {\n            createView.global = true\n        }\n        return createView\n    }\n\n    override fun visitCreateTempViewUsing(ctx: SparkSqlParser.CreateTempViewUsingContext): Statement {\n        val tableName = ctx.tableIdentifier().table.text\n        var databaseName: String? = null\n        if (ctx.tableIdentifier().db != null) {\n            databaseName = ctx.tableIdentifier().db.text\n        }\n\n        currentOptType = StatementType.CREATE_TEMP_VIEW_USING\n\n        val tableId = TableId(null, databaseName, tableName)\n        val fileFormat = ctx.tableProvider().multipartIdentifier().text\n        val properties = parseOptions(ctx.propertyList())\n        val createView = CreateTempViewUsing(tableId, fileFormat, properties)\n        if (ctx.REPLACE() != null) {\n            createView.replace = true\n        }\n        if (ctx.GLOBAL() != null) {\n            createView.global = true\n        }\n        return createView\n    }\n\n    override fun visitAlterViewQuery(ctx: SparkSqlParser.AlterViewQueryContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        val queryStmt = parseQuery(ctx.query())\n\n        currentAlterActionType = ALTER_VIEW_QUERY\n        visitQuery(ctx.query())\n\n        val action = AlterViewAction(queryStmt)\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitCreateIndex(ctx: SparkSqlParser.CreateIndexContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        val indexName = parseIdentifier(ctx.identifier())\n        val createIndex = CreateIndex(indexName)\n        return AlterTable(tableId, createIndex)\n    }\n\n    override fun visitDropIndex(ctx: SparkSqlParser.DropIndexContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        val indexName = ctx.identifier().text\n        val dropIndex = DropIndex(indexName)\n        return AlterTable(tableId, dropIndex)\n    }\n\n    // -----------------------------------function-------------------------------------------------\n\n    override fun visitCreateFunction(ctx: SparkSqlParser.CreateFunctionContext): Statement {\n        val functionId = parseFunctionName(ctx.identifierReference().multipartIdentifier())\n        val classNmae = ctx.className.text\n\n        var temporary = false\n        var file: String? = null\n        if (ctx.TEMPORARY() != null) {\n            temporary = true\n        } else {\n            file = ctx.resource(0).stringLit().text\n        }\n\n        val replace = if (ctx.REPLACE() != null) true else false\n        return CreateFunction(functionId, arrayListOf(), replace, temporary, classNmae, file)\n    }\n\n    override fun visitDropFunction(ctx: SparkSqlParser.DropFunctionContext): Statement {\n        val functionId = parseFunctionName(ctx.identifierReference().multipartIdentifier())\n        return DropFunction(functionId)\n    }\n\n    override fun visitDescribeNamespace(ctx: SparkSqlParser.DescribeNamespaceContext): Statement {\n        if (ctx.namespace().NAMESPACE() != null) {\n            return DescCatalog(ctx.identifierReference().multipartIdentifier().text)\n        } else {\n            val (catalogName, schemaName) = parseNamespace(ctx.identifierReference())\n            return DescSchema(SchemaId(catalogName, schemaName))\n        }\n    }\n\n    override fun visitDescribeFuncName(ctx: SparkSqlParser.DescribeFuncNameContext): Statement {\n        val functionId = parseFunctionName(ctx.identifierReference().multipartIdentifier())\n        return DescFunction(functionId)\n    }\n\n    override fun visitDescribeQuery(ctx: SparkSqlParser.DescribeQueryContext): Statement {\n        val query = parseQuery(ctx.query())\n        return DescQuery(query)\n    }\n\n    override fun visitDescribeRelation(ctx: SparkSqlParser.DescribeRelationContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference().multipartIdentifier())\n        return DescTable(tableId)\n    }\n\n    // -----------------------------------iceberg sql start -------------------------------------\n\n    override fun visitAddPartitionField(ctx: SparkSqlParser.AddPartitionFieldContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        return AlterTable(tableId, AlterTableAction(ADD_PARTITION_FIELD))\n    }\n\n    override fun visitDropPartitionField(ctx: SparkSqlParser.DropPartitionFieldContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        return AlterTable(tableId, AlterTableAction(DROP_PARTITION_FIELD))\n    }\n\n    override fun visitReplacePartitionField(ctx: SparkSqlParser.ReplacePartitionFieldContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        return AlterTable(tableId, AlterTableAction(REPLACE_PARTITION_FIELD))\n    }\n\n    override fun visitSetWriteDistributionAndOrdering(\n        ctx: SparkSqlParser.SetWriteDistributionAndOrderingContext\n    ): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        return AlterTable(tableId, AlterTableAction(SET_WRITE_DISTRIBUTION_AND_ORDERING))\n    }\n\n    override fun visitSetIdentifierFields(ctx: SparkSqlParser.SetIdentifierFieldsContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        val fields = ctx.fieldList().fields.map { field -> field.text }.toList()\n        return AlterTable(tableId, AlterSetIdentifierFieldsAction(fields))\n    }\n\n    override fun visitDropIdentifierFields(ctx: SparkSqlParser.DropIdentifierFieldsContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        val fields = ctx.fieldList().fields.map { field -> field.text }.toList()\n        return AlterTable(tableId, AlterDropIdentifierFieldsAction(fields))\n    }\n\n    override fun visitCreateOrReplaceTag(ctx: SparkSqlParser.CreateOrReplaceTagContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        val tagName = CommonUtils.cleanQuote(ctx.createReplaceTagClause().identifier().text)\n        return AlterTable(tableId, AlterCreateTagAction(tagName))\n    }\n\n    override fun visitDropTag(ctx: SparkSqlParser.DropTagContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        val tagName = CommonUtils.cleanQuote(ctx.identifier().text)\n        return AlterTable(tableId, AlterDropTagAction(tagName))\n    }\n\n    override fun visitCreateOrReplaceBranch(ctx: SparkSqlParser.CreateOrReplaceBranchContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        val branchName = CommonUtils.cleanQuote(ctx.createReplaceBranchClause().identifier().text)\n        return AlterTable(tableId, AlterCreateBranchAction(branchName))\n    }\n\n    override fun visitDropBranch(ctx: SparkSqlParser.DropBranchContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        val branchName = CommonUtils.cleanQuote(ctx.identifier().text)\n        return AlterTable(tableId, AlterDropBranchAction(branchName))\n    }\n\n    // -----------------------------------iceberg sql end -------------------------------------\n\n    // -----------------------------------delta sql start -------------------------------------\n\n    override fun visitVacuumTable(ctx: SparkSqlParser.VacuumTableContext): Statement {\n        val tableId = parseTableName(ctx.table)\n        return VacuumTable(tableId)\n    }\n\n    override fun visitOptimizeTable(ctx: SparkSqlParser.OptimizeTableContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        return OptimizeTable(tableId)\n    }\n\n    override fun visitDescribeDeltaDetail(ctx: SparkSqlParser.DescribeDeltaDetailContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        return DescDeltaDetail(tableId)\n    }\n\n    override fun visitDescribeDeltaHistory(ctx: SparkSqlParser.DescribeDeltaHistoryContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n\n        if (ctx.limit != null) {\n            return DescDeltaHistory(tableId, ctx.limit.text.toInt())\n        } else {\n            return DescDeltaHistory(tableId)\n        }\n    }\n\n    override fun visitAddTableConstraint(ctx: SparkSqlParser.AddTableConstraintContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        return AlterTable(tableId, AlterAddConstraintAction())\n    }\n\n    override fun visitDropTableConstraint(ctx: SparkSqlParser.DropTableConstraintContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        return AlterTable(tableId, AlterDropConstraintAction())\n    }\n\n    override fun visitAlterTableDropFeature(ctx: SparkSqlParser.AlterTableDropFeatureContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        return AlterTable(tableId, AlterDropFeatureAction())\n    }\n\n    override fun visitAlterTableClusterBy(ctx: SparkSqlParser.AlterTableClusterByContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        return AlterTable(tableId, AlterClusterByAction())\n    }\n\n    override fun visitAlterTableSyncIdentity(ctx: SparkSqlParser.AlterTableSyncIdentityContext): Statement {\n        val tableId = parseTableName(ctx.table)\n        return AlterTable(tableId, AlterSyncIdentityAction())\n    }\n\n    // -----------------------------------delta sql start -------------------------------------\n\n    // -----------------------------------cache-------------------------------------------------\n\n    override fun visitCacheTable(ctx: SparkSqlParser.CacheTableContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        val options = parseOptions(ctx.propertyList())\n        if (ctx.query() != null) {\n            val query = parseQuery(ctx.query())\n            return CacheTable(tableId, options, query)\n        } else {\n            return CacheTable(tableId, options)\n        }\n    }\n\n    private fun parseQuery(ctx: QueryContext): QueryStmt {\n        currentOptType = StatementType.SELECT\n        this.visitQuery(ctx)\n\n        val queryStmt = QueryStmt(inputTables, limit, offset)\n        queryStmt.functionNames.addAll(functionNames)\n        var querySql = source(ctx)\n        if (StringUtils.startsWith(querySql, \"(\") && StringUtils.endsWith(querySql, \")\")) {\n            querySql = StringUtils.substring(querySql, 1, -1)\n        }\n        queryStmt.setSql(querySql)\n        return queryStmt\n    }\n\n    private fun parseFromClause(ctx: FromClauseContext): QueryStmt {\n        currentOptType = StatementType.SELECT\n        this.visitFromClause(ctx)\n\n        val queryStmt = QueryStmt(inputTables, limit, offset)\n        queryStmt.functionNames.addAll(functionNames)\n        var querySql = source(ctx)\n        if (StringUtils.startsWith(querySql, \"(\") && StringUtils.endsWith(querySql, \")\")) {\n            querySql = StringUtils.substring(querySql, 1, -1)\n        }\n        queryStmt.setSql(querySql)\n        return queryStmt\n    }\n\n    override fun visitUncacheTable(ctx: SparkSqlParser.UncacheTableContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        return UnCacheTable(tableId)\n    }\n\n    override fun visitClearCache(ctx: SparkSqlParser.ClearCacheContext?): Statement {\n        return DefaultStatement(StatementType.CLEAR_CACHE)\n    }\n\n    // -----------------------------------other-------------------------------------------------\n\n    override fun visitExplain(ctx: SparkSqlParser.ExplainContext?): Statement {\n        return DefaultStatement(StatementType.EXPLAIN)\n    }\n\n    override fun visitCreateFileView(ctx: SparkSqlParser.CreateFileViewContext): Statement {\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        val path = CommonUtils.cleanQuote(ctx.path.text)\n\n        var compression: String? = null\n        var sizeLimit: String? = null\n\n        val fileFormat = ctx.tableProvider().multipartIdentifier().text\n\n        val causes = ctx.createFileViewClauses()\n        if (causes != null) {\n            if (causes.compressionName != null) compression = causes.compressionName.text\n            if (causes.sizelimit != null) sizeLimit = causes.sizelimit.text\n        }\n        val properties = parseOptions(ctx.propertyList())\n\n        return CreateFileView(tableId, path, properties, fileFormat, compression, sizeLimit)\n    }\n\n    override fun visitLoadData(ctx: SparkSqlParser.LoadDataContext): Statement {\n        val tableId = parseTableName(ctx.identifierReference())\n        val path = CommonUtils.cleanQuote(ctx.path.text)\n        val local: Boolean = ctx.LOCAL() != null\n        val mode: InsertMode = if (ctx.OVERWRITE() != null) InsertMode.OVERWRITE else InsertMode.INTO\n        val partitionVals = parsePartitionSpec(ctx.partitionSpec())\n        return LoadData(tableId, path, local, partitionVals, mode)\n    }\n\n    override fun visitExportTable(ctx: SparkSqlParser.ExportTableContext): Statement {\n        if (ctx.ctes() != null) {\n            visitCtes(ctx.ctes())\n        }\n        currentOptType = StatementType.EXPORT_TABLE\n        super.visitExportTable(ctx)\n\n        val tableId = parseTableName(ctx.multipartIdentifier())\n        val filePath = CommonUtils.cleanQuote(ctx.filePath.text)\n        val properties = parseOptions(ctx.propertyList())\n        val partitionVals = parsePartitionSpec(ctx.partitionSpec())\n\n        var fileFormat: String? = null\n        var compression: String? = null\n        var maxFileSize: String? = null\n        var overwrite: Boolean = false\n        var single: Boolean = false\n\n        val causes = ctx.exportTableClauses()\n        if (causes != null) {\n            if (causes.fileformatName != null) fileFormat = causes.fileformatName.text\n            if (causes.compressionName != null) compression = causes.compressionName.text\n            if (causes.maxfilesize != null) maxFileSize = causes.maxfilesize.text\n            if (causes.overwrite != null) overwrite = causes.overwrite.TRUE() != null\n            if (causes.single != null) single = causes.single.TRUE() != null\n        }\n\n        val exportTable =\n            ExportTable(\n                tableId,\n                filePath,\n                properties,\n                partitionVals,\n                fileFormat,\n                compression,\n                maxFileSize,\n                overwrite,\n                single,\n                inputTables\n            )\n\n        exportTable.functionNames.addAll(functionNames)\n        return exportTable\n    }\n\n    override fun visitUse(ctx: SparkSqlParser.UseContext): Statement {\n        val (catalogName, databaseName) = parseNamespace(ctx.identifierReference())\n        return UseDatabase(catalogName, databaseName)\n    }\n\n    override fun visitUseNamespace(ctx: SparkSqlParser.UseNamespaceContext): Statement {\n        val type = ctx.namespace().text.uppercase()\n\n        if (StringUtils.equalsIgnoreCase(\"database\", type) || StringUtils.equalsIgnoreCase(\"schema\", type)) {\n\n            val (catalogName, databaseName) = parseNamespace(ctx.identifierReference())\n            return UseDatabase(catalogName, databaseName)\n        } else if (StringUtils.equalsIgnoreCase(\"namespace\", type)) {\n            return UseCatalog(ctx.identifierReference().text)\n        } else {\n            throw RuntimeException(\"not support: \" + type)\n        }\n    }\n\n    override fun visitSetConfiguration(ctx: SparkSqlParser.SetConfigurationContext): Statement {\n        return SetStatement(ctx.setKey().text)\n    }\n\n    override fun visitSetQuotedConfiguration(ctx: SparkSqlParser.SetQuotedConfigurationContext): Statement {\n        assert(ctx.configValue() != null)\n        if (ctx.setKey() != null) {\n            val key = CommonUtils.cleanQuote(ctx.setKey().getText())\n            val value = CommonUtils.cleanQuote(ctx.configValue().getText())\n            return SetStatement(key, value)\n        } else {\n            throw SQLParserException(\"not support\" + source(ctx))\n        }\n    }\n\n    override fun visitResetConfiguration(ctx: SparkSqlParser.ResetConfigurationContext): Statement {\n        val key = StringUtils.trim(CommonUtils.subsql(command, ctx.RESET().symbol, ctx.stop))\n\n        return ReSetStatement(key)\n    }\n\n    // -----------------------------------insert &\n    // query-------------------------------------------------\n\n    override fun visitStatementDefault(ctx: SparkSqlParser.StatementDefaultContext): Statement? {\n        val node = ctx.getChild(0)\n        if (node is QueryContext) {\n            currentOptType = StatementType.SELECT\n            super.visitStatementDefault(ctx)\n\n            val queryStmt = QueryStmt(inputTables, limit, offset)\n            queryStmt.functionNames.addAll(functionNames)\n            return queryStmt\n        }\n\n        return null\n    }\n\n    override fun visitDmlStatement(ctx: SparkSqlParser.DmlStatementContext): Statement? {\n        currentOptType = StatementType.INSERT\n        val node =\n            if (ctx.ctes() != null) {\n                this.visitCtes(ctx.ctes())\n                ctx.getChild(1)\n            } else {\n                ctx.getChild(0)\n            }\n\n        if (node is SingleInsertQueryContext) {\n            insertSql = true\n            val queryStmt = parseQuery(node.query())\n            currentOptType = StatementType.INSERT\n            val insertTable = parseInsertInto(node.insertInto(), queryStmt)\n            insertTable.rows = rows\n\n            return insertTable\n        } else if (node is MultiInsertQueryContext) {\n            val queryStmt = parseFromClause(node.fromClause())\n            currentOptType = StatementType.INSERT\n\n            node.multiInsertQueryBody().forEach { this.visitMultiInsertQueryBody(it) }\n            val insertTable = InsertTable(InsertMode.OVERWRITE, queryStmt, outputTables.first())\n            insertTable.outputTables.addAll(outputTables.subList(1, outputTables.size))\n            return insertTable\n        } else if (\n            node is SparkSqlParser.UpdateTableContext ||\n                node is SparkSqlParser.DeleteFromTableContext ||\n                node is SparkSqlParser.MergeIntoTableContext\n        ) {\n            return super.visitDmlStatement(ctx)\n        } else {\n            return null\n        }\n    }\n\n    private fun parseInsertInto(ctx: InsertIntoContext, queryStmt: QueryStmt): InsertTable {\n        return if (ctx is SparkSqlParser.InsertIntoTableContext) {\n            val tableId = parseTableName(ctx.identifierReference())\n            val partitionVals = parsePartitionSpec(ctx.partitionSpec())\n            var columnNameList: List<ColumnRel>? = null\n            if (ctx.identifierList() != null) {\n                columnNameList =\n                    ctx.identifierList().identifierSeq().ident.map { ColumnRel(CommonUtils.cleanQuote(it.text)) }\n            }\n            val stmt = InsertTable(InsertMode.INTO, queryStmt, tableId, columnNameList)\n            stmt.partitionVals = partitionVals\n            stmt.hints = parseHints(ctx.hints)\n            stmt\n        } else if (ctx is SparkSqlParser.InsertOverwriteTableContext) {\n            val tableId = parseTableName(ctx.identifierReference())\n            val partitionVals = parsePartitionSpec(ctx.partitionSpec())\n            var columnNameList: List<ColumnRel>? = null\n            if (ctx.identifierList() != null) {\n                columnNameList =\n                    ctx.identifierList().identifierSeq().ident.map { ColumnRel(CommonUtils.cleanQuote(it.text)) }\n            }\n            val stmt = InsertTable(InsertMode.OVERWRITE, queryStmt, tableId, columnNameList)\n            stmt.partitionVals = partitionVals\n            stmt.hints = parseHints(ctx.hints)\n            stmt\n        } else if (ctx is SparkSqlParser.InsertIntoReplaceWhereContext) {\n            val tableId = parseTableName(ctx.identifierReference())\n            InsertTable(InsertMode.INTO_REPLACE, queryStmt, tableId)\n        } else if (ctx is SparkSqlParser.InsertOverwriteDirContext) {\n            val path = if (ctx.path != null) CommonUtils.cleanQuote(ctx.path.STRING_LITERAL().text) else \"\"\n            val properties = parseOptions(ctx.propertyList())\n            val fileFormat = ctx.tableProvider().multipartIdentifier().text\n\n            val stmt = InsertTable(InsertMode.OVERWRITE_DIR, queryStmt, TableId(path))\n            stmt.properties = properties\n            stmt.fileFormat = fileFormat\n            stmt.hints = parseHints(ctx.hints)\n            stmt\n        } else if (ctx is SparkSqlParser.InsertOverwriteHiveDirContext) {\n            val path = CommonUtils.cleanQuote(ctx.path.STRING_LITERAL().text)\n            val stmt = InsertTable(InsertMode.OVERWRITE_HIVE_DIR, queryStmt, TableId(path))\n            stmt.hints = parseHints(ctx.hints)\n            stmt\n        } else {\n            throw SQLParserException(\"not support insert into sql\")\n        }\n    }\n\n    // -----------------------------------delta sql-------------------------------------------------\n\n    override fun visitDeleteFromTable(ctx: SparkSqlParser.DeleteFromTableContext): Statement {\n        currentOptType = StatementType.DELETE\n        val tableId = parseTableName(ctx.identifierReference())\n        super.visitWhereClause(ctx.whereClause())\n\n        return DeleteTable(tableId, inputTables)\n    }\n\n    override fun visitUpdateTable(ctx: SparkSqlParser.UpdateTableContext): Statement {\n        currentOptType = StatementType.UPDATE\n        val tableId = parseTableName(ctx.identifierReference())\n        if (ctx.whereClause() != null) {\n            super.visitWhereClause(ctx.whereClause())\n        }\n\n        return UpdateTable(tableId, inputTables)\n    }\n\n    override fun visitMergeIntoTable(ctx: SparkSqlParser.MergeIntoTableContext): Statement {\n        currentOptType = StatementType.MERGE\n\n        val targetTable = parseTableName(ctx.target)\n        val mergeTable = MergeTable(targetTable = targetTable)\n\n        if (ctx.source != null) {\n            val tableId = parseTableName(ctx.source)\n            inputTables.add(tableId)\n        } else if (ctx.sourceQuery != null && ctx.sourceQuery is QueryContext) {\n            val query = ctx.sourceQuery as QueryContext\n            super.visitQuery(query)\n        }\n        mergeTable.inputTables = inputTables\n        return mergeTable\n    }\n\n    override fun visitManageResource(ctx: SparkSqlParser.ManageResourceContext): Statement {\n        val resouceType = StringUtils.lowerCase(ctx.identifier().text)\n        val rawArg = StringUtils.substring(command, ctx.identifier().stop.stopIndex + 1, ctx.stop.stopIndex + 1)\n\n        val files = arrayListOf<String>()\n        if (StringUtils.isNotBlank(rawArg)) {\n            val pattern = Pattern.compile(\"(\\\".*?[^\\\\\\\\]\\\"|'.*?[^\\\\\\\\]'|[^ \\\\n\\\\r\\\\t\\\"']+)\")\n            val matcher = pattern.matcher(rawArg)\n            while (matcher.find()) {\n                val match = matcher.group()\n                files.add(CommonUtils.cleanQuote(match))\n            }\n        }\n\n        return if (ctx.ADD() != null) {\n            AddResourceStatement(files, resouceType)\n        } else {\n            ListResourceStatement(files, resouceType)\n        }\n    }\n\n    // -----------------------------------private\n    // method-------------------------------------------------\n\n    override fun visitFunctionCall(ctx: SparkSqlParser.FunctionCallContext): Statement? {\n        val functionId = parseFunctionName(ctx.functionName())\n        if (functionId != null) {\n            val args = ctx.functionArgument().map { CommonUtils.cleanQuote(it.text) }.toList()\n            functionId.functionArguments = args\n            functionNames.add(functionId)\n        }\n\n        return super.visitFunctionCall(ctx)\n    }\n\n    override fun visitFunctionTable(ctx: SparkSqlParser.FunctionTableContext): Statement? {\n        val functionId = parseFunctionName(ctx.functionName())\n        if (functionId != null) {\n            val args = ctx.functionTableArgument().map { CommonUtils.cleanQuote(it.text) }.toList()\n            functionId.functionArguments = args\n            functionId.funcType = \"TVF\"\n            functionNames.add(functionId)\n        }\n\n        return super.visitFunctionTable(ctx)\n    }\n\n    private fun parseFunctionName(ctx: SparkSqlParser.FunctionNameContext): FunctionId? {\n        if (\n            StatementType.SELECT == currentOptType ||\n                StatementType.CREATE_VIEW == currentOptType ||\n                StatementType.INSERT == currentOptType ||\n                StatementType.CREATE_TABLE_AS_SELECT == currentOptType ||\n                StatementType.MERGE == currentOptType ||\n                StatementType.EXPORT_TABLE == currentOptType ||\n                StatementType.DATATUNNEL == currentOptType\n        ) {\n\n            val names = ctx.qualifiedName().identifier()\n            if (names.size == 3) {\n                val catalog = StringUtils.lowerCase(names.get(0).text)\n                val schema = StringUtils.lowerCase(names.get(1).text)\n                val funcName = StringUtils.lowerCase(names.get(2).text)\n                return FunctionId(catalog, schema, funcName)\n            } else if (names.size == 2) {\n                val schema = StringUtils.lowerCase(names.get(0).text)\n                val funcName = StringUtils.lowerCase(names.get(1).text)\n                return FunctionId(schema, funcName)\n            } else if (names.size == 1) {\n                val funcName = StringUtils.lowerCase(names.get(0).text)\n                return FunctionId(funcName)\n            }\n        }\n        return null\n    }\n\n    override fun visitCtes(ctx: SparkSqlParser.CtesContext): Statement? {\n        inCte = true\n        ctx.namedQuery().forEach {\n            cteTempTables.add(TableId(it.name.text))\n            this.visitQuery(it.query())\n        }\n        inCte = false\n        return null\n    }\n\n    override fun visitMultipartIdentifier(ctx: SparkSqlParser.MultipartIdentifierContext): Statement? {\n        val tableId = parseTableName(ctx)\n        if (\n            currentOptType == StatementType.CREATE_TABLE_AS_SELECT ||\n                currentOptType == StatementType.SELECT ||\n                currentOptType == StatementType.CREATE_VIEW ||\n                currentOptType == StatementType.INSERT ||\n                currentOptType == StatementType.MERGE ||\n                currentOptType == StatementType.EXPORT_TABLE ||\n                currentOptType == StatementType.DATATUNNEL ||\n                currentOptType == StatementType.UPDATE ||\n                currentOptType == StatementType.DELETE ||\n                currentAlterActionType == ALTER_VIEW_QUERY\n        ) {\n\n            // 别名和表名一样的场景\n            if (inCte && cteTempTables.last() == tableId) {\n                cteTempTables.remove(tableId)\n            }\n\n            if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {\n                inputTables.add(tableId)\n            }\n        }\n        return null\n    }\n\n    override fun visitRowConstructor(ctx: SparkSqlParser.RowConstructorContext): Statement? {\n        val row =\n            ctx.children\n                .filter { it is SparkSqlParser.NamedExpressionContext }\n                .map {\n                    var text = it.text\n                    text = CommonUtils.cleanQuote(text)\n                    text\n                }\n                .toList()\n\n        rows.add(row)\n        return null\n    }\n\n    override fun visitParenthesizedExpression(ctx: SparkSqlParser.ParenthesizedExpressionContext): Statement? {\n        val row =\n            ctx.children\n                .filter { it is SparkSqlParser.ExpressionContext }\n                .map {\n                    var text = it.text\n                    text = CommonUtils.cleanQuote(text)\n                    text\n                }\n                .toList()\n\n        rows.add(row)\n        return null\n    }\n\n    override fun visitFromClause(ctx: SparkSqlParser.FromClauseContext): Statement? {\n        multiInsertToken = \"from\"\n        return super.visitFromClause(ctx)\n    }\n\n    override fun visitMultiInsertQueryBody(ctx: SparkSqlParser.MultiInsertQueryBodyContext): Statement? {\n        multiInsertToken = \"insert\"\n        val obj = ctx.insertInto()\n        if (obj is SparkSqlParser.InsertOverwriteTableContext) {\n            val multipartIdentifier = obj.identifierReference()\n            val tableId = parseTableName(multipartIdentifier)\n            outputTables.add(tableId)\n        } else if (obj is SparkSqlParser.InsertIntoTableContext) {\n            val multipartIdentifier = obj.identifierReference()\n            val tableId = parseTableName(multipartIdentifier)\n            outputTables.add(tableId)\n        }\n        return null\n    }\n\n    override fun visitQueryOrganization(ctx: SparkSqlParser.QueryOrganizationContext): Statement? {\n        limit = ctx.limit?.text?.toInt()\n        offset = ctx.offset?.text?.toInt()\n        return super.visitQueryOrganization(ctx)\n    }\n\n    override fun visitTypeConstructor(ctx: SparkSqlParser.TypeConstructorContext): Statement? {\n        val valueType = ctx.literalType().getText().uppercase()\n        if (\n            !(\"DATE\".equals(valueType) ||\n                \"TIME\".equals(valueType) ||\n                \"TIMESTAMP\".equals(valueType) ||\n                \"INTERVAL\".equals(valueType) ||\n                \"X\".equals(valueType))\n        ) {\n            throw SQLParserException(\"Literals of type \" + valueType + \" are currently not supported.\")\n        }\n\n        return super.visitTypeConstructor(ctx)\n    }\n\n    private fun parseColDefinition(colDef: List<ColDefinitionOptionContext>): Triple<Boolean, String?, String?> {\n        var nullable: Boolean = false\n        var comment: String? = null\n        var defaultExpr: String? = null\n\n        if (colDef.size > 0) {\n            colDef.forEach { col ->\n                if (col.NULL() != null) {\n                    nullable = true\n                }\n\n                if (col.commentSpec() != null) {\n                    comment = CommonUtils.cleanQuote(col.commentSpec().stringLit().text)\n                }\n\n                if (col.defaultExpression() != null) {\n                    defaultExpr =\n                        StringUtils.substring(\n                            command,\n                            col.defaultExpression().start.startIndex,\n                            col.defaultExpression().stop.stopIndex + 1\n                        )\n\n                    if (defaultExpr != null) {\n                        defaultExpr = CommonUtils.cleanQuote(defaultExpr!!)\n                    }\n                }\n            }\n        }\n\n        return Triple(nullable, defaultExpr, comment)\n    }\n\n    private fun parseAlterColumnAction(context: AlterColumnActionContext): AlterColumnAction {\n        val action = AlterColumnAction(ALTER_COLUMN)\n        if (context.dataType() != null) {\n            action.dataType = source(context.dataType())\n        }\n\n        if (context.commentSpec() != null) {\n            action.comment = CommonUtils.cleanQuote(context.commentSpec().stringLit().text)\n        }\n\n        if (context.colPosition() != null) {\n            if (context.colPosition().FIRST() != null) {\n                action.position = \"first\"\n            } else if (context.colPosition().AFTER() != null) {\n                action.position = \"after\"\n                action.afterCol = context.colPosition().afterCol.text\n            }\n        }\n\n        if (context.setOrDrop != null) {\n            if (StringUtils.containsAnyIgnoreCase(context.setOrDrop.text, \"drop\")) {\n                action.setOrDrop = \"DROP\"\n            } else {\n                action.setOrDrop = \"SET\"\n            }\n\n            if (context.NOT() != null) {\n                action.nullable = false\n            }\n        }\n\n        if (context.defaultExpression() != null) {\n            val expr = context.defaultExpression().expression()\n            action.defaultExpression = CommonUtils.cleanQuote(source(expr))\n        }\n\n        if (context.dropDefault != null) {\n            action.dropDefault = true\n        }\n\n        return action\n    }\n\n    /** 表列支持数据类型 */\n    private fun checkColumnDataType(dataType: String): Boolean {\n        if (StringUtils.startsWithIgnoreCase(dataType, \"decimal\")) {\n            return true\n        }\n\n        return when (dataType.lowercase()) {\n            \"string\",\n            \"int\",\n            \"bigint\",\n            \"double\",\n            \"date\",\n            \"timestamp\",\n            \"boolean\" -> true\n            else -> throw IllegalStateException(\"不支持数据类型：\" + dataType)\n        }\n    }\n\n    /** 分区支持数据类型 */\n    private fun checkPartitionDataType(dataType: String): Boolean {\n        return when (dataType.lowercase()) {\n            \"string\",\n            \"int\",\n            \"bigint\",\n            \"varchar\",\n            \"date\",\n            \"char\" -> true\n            else -> throw IllegalStateException(\"不支持数据类型：\" + dataType)\n        }\n    }\n\n    private fun parseOptions(ctx: PropertyListContext?): HashMap<String, String> {\n        val properties = HashMap<String, String>()\n        if (ctx != null) {\n            ctx.property().forEach { item ->\n                val property = item as SparkSqlParser.PropertyContext\n                val key = CommonUtils.cleanQuote(property.key.text)\n                val value = CommonUtils.cleanQuote(property.value.text)\n                properties.put(key, value)\n            }\n        }\n\n        return properties\n    }\n\n    private fun parsePartitionSpec(ctx: PartitionSpecContext?): LinkedHashMap<String, String> {\n        val partitions: LinkedHashMap<String, String> = LinkedHashMap()\n        if (ctx != null) {\n            ctx.partitionVal().forEach {\n                if (it.childCount == 1) {\n                    partitions.put(it.identifier().text, \"__dynamic__\")\n                } else {\n                    var value = it.getChild(2).text\n                    value = CommonUtils.cleanQuote(value)\n                    partitions.put(it.identifier().text, value)\n                }\n            }\n        }\n        return partitions\n    }\n\n    private fun parseHints(hints: List<HintContext>): LinkedHashMap<String, LinkedList<String>> {\n        val partitions: LinkedHashMap<String, LinkedList<String>> = LinkedHashMap()\n        hints.forEach {\n            it.hintStatements.forEach {\n                if (it.parameters == null || it.parameters.size == 0) {\n                    partitions.put(it.hintName.text, Lists.newLinkedList())\n                } else {\n                    val parameters = Lists.newLinkedList<String>()\n                    it.parameters.forEach { parameters.add(source(it)) }\n                    partitions.put(it.hintName.text, parameters)\n                }\n            }\n        }\n        return partitions\n    }\n\n    private fun parseColumRefs(columns: SparkSqlParser.IdentifierCommentListContext?): List<ColumnRel>? {\n        var columnNameList: List<ColumnRel>? = null\n        if (columns != null) {\n            columnNameList =\n                columns.identifierComment().map {\n                    val name = CommonUtils.cleanQuote(it.identifier().text)\n                    val commentText: String? =\n                        if (it.commentSpec() != null) CommonUtils.cleanQuote(it.commentSpec().stringLit().text)\n                        else null\n                    ColumnRel(name, comment = commentText)\n                }\n        }\n\n        return columnNameList\n    }\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/SparkSqlHelper.kt",
    "content": "package io.github.melin.superior.parser.spark\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils.KEYWORD_REGEX\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.StatementType.*\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlLexer\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParser\nimport io.github.melin.superior.parser.spark.antlr4.SparkSqlParserBaseVisitor\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/1/10. */\nobject SparkSqlHelper {\n\n    @JvmStatic\n    fun checkSupportedSQL(statementType: StatementType): Boolean {\n        return when (statementType) {\n            CREATE_DATABASE,\n            CREATE_SCHEMA,\n            CREATE_TABLE,\n            CREATE_TABLE_AS_SELECT,\n            CREATE_TABLE_AS_LIKE,\n            TRUNCATE_TABLE,\n            MERGE,\n            REFRESH_TABLE,\n            EXPORT_TABLE,\n            ANALYZE_TABLE,\n            ALTER_TABLE,\n            REPAIR_TABLE,\n            SELECT,\n            INSERT,\n            CREATE_FILE_VIEW,\n            CREATE_VIEW,\n            CREATE_FUNCTION,\n            CREATE_TEMP_VIEW_USING,\n            DROP_DATABASE,\n            DROP_SCHEMA,\n            DROP_VIEW,\n            DROP_TABLE,\n            DROP_FUNCTION,\n            SHOW,\n            CACHE,\n            UNCACHE,\n            CLEAR_CACHE,\n            DATATUNNEL,\n            CALL,\n            HELP,\n            MERGE_FILE,\n            SYNC_META,\n            SYNC_TABLE,\n            SYNC_DATABASE,\n            DELETE,\n            UPDATE,\n            VACUUM_TABLE,\n            OPTIMIZE_TABLE,\n            DESC_DELTA_DETAIL,\n            DESC_DELTA_HISTORY,\n            DESC_FUNCTION,\n            DESC_CATALOG,\n            DESC_SCHEMA,\n            DESC_TABLE,\n            DESC_QUERY,\n            SET,\n            EXPLAIN -> true\n            else -> false\n        }\n    }\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until SparkSqlLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = SparkSqlLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement {\n        val statements = this.parseMultiStatement(command)\n        if (statements.size != 1) {\n            throw IllegalStateException(\"only parser one sql, sql count: \" + statements.size)\n        } else {\n            return statements.get(0)\n        }\n    }\n\n    @JvmStatic\n    fun parseMultiStatement(command: String): List<Statement> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = SparkSqlAntlr4Visitor(false, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSqlStatements()\n    }\n\n    @JvmStatic\n    fun splitSql(command: String): List<String> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = SparkSqlAntlr4Visitor(true, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSplitSqls()\n    }\n\n    @JvmStatic\n    fun checkSqlSyntax(command: String) {\n        val sqlVisitor = SparkSqlParserBaseVisitor<Statement>()\n        innerParseStatement(command, sqlVisitor)\n    }\n\n    private fun innerParseStatement(command: String, sqlVisitor: SparkSqlParserBaseVisitor<Statement>) {\n        val charStream = UpperCaseCharStream(CharStreams.fromString(command))\n        val lexer = SparkSqlLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = SparkSqlParser(tokenStream)\n        AbstractSqlParser.installCaches(parser)\n        parser.addParseListener(SparkSqlPostProcessor())\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n\n        parser.interpreter.predictionMode = PredictionMode.SLL\n\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visitSqlStatements(parser.sqlStatements())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                sqlVisitor.visitSqlStatements(parser.sqlStatements())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(command)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/SparkStreamSqlAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.spark\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.TableType\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.*\nimport io.github.melin.superior.common.relational.common.SetStatement\nimport io.github.melin.superior.common.relational.create.CreateTable\nimport io.github.melin.superior.common.relational.dml.InsertMode\nimport io.github.melin.superior.common.relational.dml.InsertTable\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport io.github.melin.superior.common.relational.table.ColumnRel\nimport io.github.melin.superior.parser.spark.antlr4.SparkStreamSqlParser\nimport io.github.melin.superior.parser.spark.antlr4.SparkStreamSqlParserBaseVisitor\n\nclass SparkStreamSqlAntlr4Visitor() : SparkStreamSqlParserBaseVisitor<Statement>() {\n\n    private val tableDatas = ArrayList<Statement>()\n\n    override fun visitSqlStatement(ctx: SparkStreamSqlParser.SqlStatementContext?): Statement {\n        val tableData = super.visitSqlStatement(ctx)\n        tableDatas.add(tableData)\n\n        return tableData\n    }\n\n    override fun visitCreateStreamTable(ctx: SparkStreamSqlParser.CreateStreamTableContext): Statement {\n        val tableName = ctx.tableName.table.ID().text\n        val columns =\n            if (ctx.columns != null) {\n                ctx.columns.children\n                    .filter { it is SparkStreamSqlParser.ColTypeContext }\n                    .map { item ->\n                        val column = item as SparkStreamSqlParser.ColTypeContext\n                        val colName = column.ID().text\n                        val dataType = column.dataType().text\n                        val colComment =\n                            if (column.comment != null) CommonUtils.cleanQuote(column.comment.text) else null\n                        val jsonPath =\n                            if (column.jsonPath != null) CommonUtils.cleanQuote(column.jsonPath.text) else null\n                        // val pattern = if (column.pattern != null)\n                        // StringUtil.cleanQuote(column.pattern.text) else null\n\n                        val columnRel = ColumnRel(colName, dataType, colComment, true)\n                        columnRel.jsonPath = jsonPath\n                        columnRel\n                    }\n            } else {\n                emptyList()\n            }\n\n        val properties = HashMap<String, String>()\n        if (ctx.tableProps != null) {\n            ctx.tableProps.children\n                .filter { it is SparkStreamSqlParser.TablePropertyContext }\n                .map { item ->\n                    val property = item as SparkStreamSqlParser.TablePropertyContext\n                    val key = CommonUtils.cleanQuote(property.key.text)\n                    val value = CommonUtils.cleanQuote(property.value.text)\n                    properties.put(key, value)\n                }\n        }\n\n        return CreateTable(TableId(tableName), TableType.SPARK_STREAM, null, columns, false, properties)\n    }\n\n    override fun visitSetStatement(ctx: SparkStreamSqlParser.SetStatementContext): Statement {\n        val key = ctx.setKeyExpr().text\n        var value = CommonUtils.cleanQuote(ctx.valueKeyExpr().text)\n        value = CommonUtils.cleanQuote(value)\n\n        return SetStatement(key, value)\n    }\n\n    override fun visitInsertStatement(ctx: SparkStreamSqlParser.InsertStatementContext): Statement {\n        val schemaName = if (ctx.tableName.db != null) ctx.tableName.db.ID().text else null\n        val tableName = ctx.tableName.table.ID().text\n\n        val tableId = TableId(schemaName, tableName)\n        val queryStmt = QueryStmt()\n        val querySql = source(ctx.select)\n        queryStmt.setSql(querySql)\n        val insertTable = InsertTable(InsertMode.INTO, queryStmt, tableId)\n        return insertTable\n    }\n\n    fun getTableDatas(): ArrayList<Statement> {\n        return tableDatas\n    }\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/SparkStreamSqlHelper.kt",
    "content": "package io.github.melin.superior.parser.spark\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.spark.antlr4.SparkStreamSqlLexer\nimport io.github.melin.superior.parser.spark.antlr4.SparkStreamSqlParser\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\nobject SparkStreamSqlHelper {\n\n    @JvmStatic\n    fun checkSupportedSQL(statementType: StatementType): Boolean {\n        return when (statementType) {\n            StatementType.CREATE_TABLE,\n            StatementType.SET,\n            StatementType.INSERT -> true\n            else -> false\n        }\n    }\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until SparkStreamSqlLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = SparkStreamSqlLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): ArrayList<Statement> {\n        val trimCmd = StringUtils.trim(command)\n\n        val charStream = UpperCaseCharStream(CharStreams.fromString(trimCmd))\n        val lexer = SparkStreamSqlLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = SparkStreamSqlParser(tokenStream)\n        AbstractSparkStreamSqlParser.installCaches(parser)\n        parser.addParseListener(SparkSqlPostProcessor())\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n        parser.interpreter.predictionMode = PredictionMode.LL\n\n        val sqlVisitor = SparkStreamSqlAntlr4Visitor()\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visit(parser.sqlStatements())\n                return sqlVisitor.getTableDatas()\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                sqlVisitor.visit(parser.sqlStatements())\n                return sqlVisitor.getTableDatas()\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(trimCmd)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSparkStreamSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/relational/CallHelp.kt",
    "content": "package io.github.melin.superior.parser.spark.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class CallHelp(val procedureName: String?) : Statement() {\n    override val statementType = StatementType.HELP\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/relational/CreateFileView.kt",
    "content": "package io.github.melin.superior.parser.spark.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class CreateFileView(\n    override val tableId: TableId,\n    val path: String,\n    var properties: Map<String, String>,\n    var fileFormat: String? = null,\n    val compression: String? = null,\n    val sizeLimit: String? = null\n) : AbsTableStatement() {\n    override val statementType = StatementType.CREATE_FILE_VIEW\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/relational/CreateTempViewUsing.kt",
    "content": "package io.github.melin.superior.parser.spark.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class CreateTempViewUsing(\n    override val tableId: TableId,\n    var fileFormat: String,\n    var properties: Map<String, String>,\n) : AbsTableStatement() {\n    override val statementType = StatementType.CREATE_TEMP_VIEW_USING\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DDL\n\n    var replace: Boolean = false\n    var global: Boolean = false\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/relational/DataTunnelExpr.kt",
    "content": "package io.github.melin.superior.parser.spark.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\n\ndata class DataTunnelExpr(\n    val sourceType: String,\n    var sourceOptions: Map<String, Any>,\n    val transformSql: String?,\n    val sinkType: String,\n    var sinkOptions: Map<String, Any>,\n    var properties: Map<String, Any>,\n) : Statement() {\n    override val statementType = StatementType.DATATUNNEL\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DML\n\n    val inputTables: ArrayList<TableId> = arrayListOf()\n    val functionNames: HashSet<FunctionId> = hashSetOf()\n\n    constructor(\n        sourceType: String,\n        sourceOptions: Map<String, Any>,\n        transformSql: String?,\n        sinkType: String,\n        sinkOptions: Map<String, Any>\n    ) : this(sourceType, sourceOptions, transformSql, sinkType, sinkOptions, mapOf())\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/relational/DataTunnelHelp.kt",
    "content": "package io.github.melin.superior.parser.spark.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class DataTunnelHelp(val type: String, val value: String) : Statement() {\n    override val statementType = StatementType.HELP\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DDL\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/relational/DistCpExpr.kt",
    "content": "package io.github.melin.superior.parser.spark.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class DistCpExpr(var options: Map<String, Any>, var properties: Map<String, Any>) : Statement() {\n    override val statementType = StatementType.SPARK_DIST_CP\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n\n    constructor(options: Map<String, Any>) : this(options, mapOf())\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/relational/LoadData.kt",
    "content": "package io.github.melin.superior.parser.spark.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\nimport io.github.melin.superior.common.relational.dml.InsertMode\n\ndata class LoadData(\n    override val tableId: TableId,\n    val inPath: String,\n    val local: Boolean,\n    var partitionVals: LinkedHashMap<String, String>,\n    val mode: InsertMode = InsertMode.INTO\n) : AbsTableStatement() {\n    override val statementType = StatementType.LOAD_DATA\n    override val privilegeType = PrivilegeType.WRITE\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/relational/MergeFileData.kt",
    "content": "package io.github.melin.superior.parser.spark.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class MergeFileData(\n    override val tableId: TableId,\n    var properties: Map<String, String>,\n    var partitionVals: LinkedHashMap<String, String>\n) : AbsTableStatement() {\n    override val statementType = StatementType.MERGE_FILE\n    override val privilegeType = PrivilegeType.WRITE\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/relational/RefreshStatement.kt",
    "content": "package io.github.melin.superior.parser.spark.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.abs.AbsTableStatement\n\ndata class RefreshStatement(override val tableId: TableId) : AbsTableStatement() {\n    override val statementType = StatementType.REFRESH_TABLE\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.TCL\n}\n"
  },
  {
    "path": "superior-spark-parser/src/main/kotlin/io/github/melin/superior/parser/spark/relational/cache.kt",
    "content": "package io.github.melin.superior.parser.spark.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.dml.QueryStmt\n\ndata class CacheTable(val tableId: TableId, var options: Map<String, String>, val queryStmt: QueryStmt?) : Statement() {\n    override val statementType = StatementType.CACHE\n    override val privilegeType = PrivilegeType.READ\n    override val sqlType = SqlType.DML\n\n    constructor(tableId: TableId, options: Map<String, String>) : this(tableId, options, null)\n}\n\ndata class UnCacheTable(val tableId: TableId) : Statement() {\n    override val statementType = StatementType.UNCACHE\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-spark-parser/src/test/kotlin/io/github/melin/superior/parser/spark/DeltaSqlExtensionsTest.kt",
    "content": "package io.github.melin.superior.parser.spark\n\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.relational.common.DescDeltaDetail\nimport io.github.melin.superior.common.relational.common.DescDeltaHistory\nimport io.github.melin.superior.common.relational.delta.OptimizeTable\nimport io.github.melin.superior.common.relational.delta.VacuumTable\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2018/1/10. */\nclass DeltaSqlExtensionsTest {\n\n    @Test\n    fun vacuumTableTest() {\n        val sql =\n            \"\"\"\n            VACUUM eventsTable DRY RUN;\n            VACUUM eventsTable USING INVENTORY inventoryTable\n            VACUUM eventsTable USING INVENTORY (select * from inventoryTable);\n        \"\"\"\n                .trimIndent()\n\n        val statements = SparkSqlHelper.parseMultiStatement(sql)\n        var vacuumTable = statements.first() as VacuumTable\n        Assert.assertEquals(StatementType.VACUUM_TABLE, vacuumTable.statementType)\n        Assert.assertEquals(\"eventsTable\", vacuumTable.tableId.tableName)\n\n        vacuumTable = statements.get(1) as VacuumTable\n        Assert.assertEquals(\"eventsTable\", vacuumTable.tableId.tableName)\n\n        vacuumTable = statements.last() as VacuumTable\n        Assert.assertEquals(\"eventsTable\", vacuumTable.tableId.tableName)\n    }\n\n    @Test\n    fun optimizeTableTest() {\n        val sql =\n            \"\"\"\n            OPTIMIZE delta_table_name WHERE date >= '2017-01-01'\n            OPTIMIZE delta_table_name ZORDER BY (eventType)\n        \"\"\"\n                .trimIndent()\n\n        val statements = SparkSqlHelper.parseMultiStatement(sql)\n        var optimizeTable = statements.first() as OptimizeTable\n        Assert.assertEquals(StatementType.OPTIMIZE_TABLE, optimizeTable.statementType)\n        Assert.assertEquals(\"delta_table_name\", optimizeTable.tableId.tableName)\n\n        optimizeTable = statements.last() as OptimizeTable\n        Assert.assertEquals(\"delta_table_name\", optimizeTable.tableId.tableName)\n    }\n\n    @Test\n    fun descDeltaDetailTest() {\n        val sql =\n            \"\"\"\n            DESCRIBE DETAIL eventsTable\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is DescDeltaDetail) {\n            Assert.assertEquals(StatementType.DESC_DELTA_DETAIL, statement.statementType)\n            Assert.assertEquals(\"eventsTable\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun descDeltaHistoryTest() {\n        val sql =\n            \"\"\"\n            DESCRIBE HISTORY eventsTable\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is DescDeltaHistory) {\n            Assert.assertEquals(StatementType.DESC_DELTA_HISTORY, statement.statementType)\n            Assert.assertEquals(\"eventsTable\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-spark-parser/src/test/kotlin/io/github/melin/superior/parser/spark/IcebergSqlExtensionsTest.kt",
    "content": "package io.github.melin.superior.parser.spark\n\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.relational.alter.*\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2018/1/10. */\nclass IcebergSqlExtensionsTest {\n\n    @Test\n    fun createTagTest() {\n        val sql = \"ALTER TABLE prod.db.sample CREATE TAG `historical-tag`\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"sample\", statement.tableId.tableName)\n            Assert.assertEquals(AlterActionType.CREATE_TAG, statement.firstAction().alterType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropTagTest() {\n        val sql = \"ALTER TABLE prod.db.sample DROP TAG `historical-tag`\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"sample\", statement.tableId.tableName)\n            Assert.assertEquals(AlterActionType.DROP_TAG, statement.firstAction().alterType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setIdentifierTest() {\n        val sql = \"ALTER TABLE prod.db.sample SET IDENTIFIER FIELDS id, data\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"sample\", statement.tableId.tableName)\n            val action = statement.firstAction() as AlterSetIdentifierFieldsAction\n            Assert.assertEquals(2, action.fields.size)\n            Assert.assertEquals(AlterActionType.SET_IDENTIFIER_FIELDS, statement.firstAction().alterType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun writeSpecTest() {\n        val sql = \"ALTER TABLE prod.db.sample WRITE DISTRIBUTED BY PARTITION LOCALLY ORDERED BY category, id\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"sample\", statement.tableId.tableName)\n            Assert.assertEquals(AlterActionType.SET_WRITE_DISTRIBUTION_AND_ORDERING, statement.firstAction().alterType)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-spark-parser/src/test/kotlin/io/github/melin/superior/parser/spark/SparkSqlParserTest.kt",
    "content": "package io.github.melin.superior.parser.spark\n\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.relational.*\nimport io.github.melin.superior.common.relational.alter.*\nimport io.github.melin.superior.common.relational.common.*\nimport io.github.melin.superior.common.relational.create.*\nimport io.github.melin.superior.common.relational.create.CreateView\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.drop.*\nimport io.github.melin.superior.common.relational.io.ExportTable\nimport io.github.melin.superior.common.relational.table.*\nimport io.github.melin.superior.parser.spark.relational.*\nimport java.io.File\nimport org.apache.commons.io.FileUtils\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2018/1/10. */\nclass SparkSqlParserTest {\n\n    @Test\n    fun splitSqlTest() {\n        val sql =\n            \"\"\"\n            CREATE DATABASE IF NOT EXISTS bigdata1;    \n            drop DATABASE IF EXISTS bigdata2\n        \"\"\"\n                .trimIndent()\n\n        val statements = SparkSqlHelper.splitSql(sql)\n\n        Assert.assertEquals(2, statements.size)\n        Assert.assertEquals(\"CREATE DATABASE IF NOT EXISTS bigdata1\", statements.get(0))\n    }\n\n    @Test\n    fun createDatabaseTest() {\n        val sql =\n            \"\"\"\n            CREATE DATABASE IF NOT EXISTS bigdata1;\n            drop DATABASE IF EXISTS bigdata2\n        \"\"\"\n                .trimIndent()\n\n        val statements = SparkSqlHelper.parseMultiStatement(sql)\n\n        val createDatabse = statements.get(0)\n        val dropDatabase = statements.get(1)\n        if (createDatabse is CreateDatabase) {\n            Assert.assertEquals(\"bigdata1\", createDatabse.databaseName)\n            Assert.assertEquals(\"CREATE DATABASE IF NOT EXISTS bigdata1\", createDatabse.getSql())\n        }\n        if (dropDatabase is CreateDatabase) {\n            Assert.assertEquals(\"bigdata2\", dropDatabase.databaseName)\n            Assert.assertEquals(\"drop DATABASE IF EXISTS bigdata2\", dropDatabase.getSql())\n        }\n    }\n\n    @Test\n    fun createDatabaseTest2() {\n        val sql = \"CREATE DATABASE IF NOT EXISTS bigdata location 's3a://hive/s3/'\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateDatabase) {\n            Assert.assertEquals(\"bigdata\", statement.databaseName)\n            val location = statement.location\n            Assert.assertEquals(\"s3a://hive/s3/\", location)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropDatabaseTest() {\n        val sql = \"drop DATABASE IF EXISTS bigdata\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is DropDatabase) {\n            Assert.assertEquals(\"bigdata\", statement.databaseName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest() {\n        val sql =\n            \"\"\"CREATE TABLE if not exists test.users (\n                name         STRING COMMENT 'Employee name',\n                address      int COMMENT 'address',\n                item1      double,\n                item2      DECIMAL(9, 2),\n                item3      TIMESTAMP,\n                item4      BIGINT,\n                item5      BOOLEAN\n            )\n            COMMENT 'hello world'\n            PARTITIONED BY (ds varchar(50) COMMENT 'part sdf')\n            STORED AS ORC\n            TBLPROPERTIES ('dataCenter'='hangzhou')\n            lifecycle 7\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            val schemaName = statement.tableId.schemaName\n            Assert.assertEquals(\"test\", schemaName)\n            Assert.assertEquals(\"hello world\", statement.comment)\n            Assert.assertNull(statement.location)\n            Assert.assertFalse(statement.external)\n            Assert.assertEquals(statement.fileFormat, \"ORC\")\n            Assert.assertFalse(statement.temporary)\n            Assert.assertEquals(7, statement.lifeCycle)\n            Assert.assertEquals(PartitionType.LIST, statement.partitionType)\n\n            Assert.assertEquals(1, statement.partitionColumnNames.size)\n            Assert.assertEquals(\"ds\", statement.partitionColumnNames.get(0))\n            Assert.assertEquals(\"part sdf\", statement.partitionColumnRels?.get(0)?.comment)\n            Assert.assertEquals(PartitionType.LIST, statement.partitionType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest1() {\n        val sql =\n            \"\"\"create table if not exists platformtool.test_users_dt(\n                    name string comment '姓名',\n                    address string comment '地址',\n                    image binary comment 'image'\n                )\n                comment 'user info'\n                PARTITIONED BY (ds string, event_type string)\n                lifecycle 7\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            val schemaName = statement.tableId.schemaName\n            Assert.assertEquals(\"platformtool\", schemaName)\n            Assert.assertEquals(7, statement.lifeCycle)\n            Assert.assertEquals(\"姓名\", statement.columnRels?.get(0)?.comment)\n            Assert.assertEquals(TableType.HIVE, statement.tableType)\n            Assert.assertEquals(2, statement.partitionColumnNames.size)\n            Assert.assertEquals(\"ds\", statement.partitionColumnNames.get(0))\n            Assert.assertEquals(\"event_type\", statement.partitionColumnNames.get(1))\n            Assert.assertEquals(PartitionType.LIST, statement.partitionType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest2() {\n        val sql =\n            \"\"\"\n            CREATE TABLE dc_cluster_compute (\n                id\t    bigint\tcomment\t'id',\n                data_center\tstring\tcomment\t'数据中心',\n                code\tstring\tcomment\t'code',\n                name\tstring\tcomment\t'集群名称'\n            ) \n            comment\t'计算集群'\n            lifecycle 100; \n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(\"dc_cluster_compute\", tableName)\n            Assert.assertEquals(100, statement.lifeCycle)\n            Assert.assertEquals(TableType.HIVE, statement.tableType)\n            Assert.assertEquals(\"数据中心\", statement.columnRels?.get(1)?.comment)\n\n            Assert.assertNull(statement.partitionType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest3() {\n        val sql =\n            \"\"\"\n            CREATE TABLE bigdata.iceberg_test_dt (\n            id bigint,\n            data string)\n            stored as iceberg\n            PARTITIONED BY (ds string)\n            lifecycle 100;\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(\"iceberg_test_dt\", tableName)\n            Assert.assertEquals(100, statement.lifeCycle)\n            Assert.assertEquals(TableType.HIVE, statement.tableType)\n            Assert.assertEquals(1, statement.partitionColumnNames.size)\n            Assert.assertEquals(\"ds\", statement.partitionColumnNames.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest4() {\n        val sql =\n            \"\"\"\n            CREATE TABLE `bigdata`.`export_test_dt` (\n            `message` STRING COMMENT '',\n            `collect_time` TIMESTAMP COMMENT '',\n            `ds` STRING COMMENT '')\n            USING orc\n            LOCATION 's3a://superior2025/iceberg/warehouse/aws_iceberg.db/iceberg_demo_1'\n            PARTITIONED BY (ds)\n            TBLPROPERTIES (\n            'transient_lastDdlTime' = '1627281671')\n            lifeCycle 100\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(\"export_test_dt\", tableName)\n            Assert.assertEquals(100, statement.lifeCycle)\n            Assert.assertEquals(\"orc\", statement.fileFormat)\n            Assert.assertEquals(\"spark\", statement.modelType)\n            Assert.assertEquals(1, statement.partitionColumnNames.size)\n            Assert.assertEquals(\"ds\", statement.partitionColumnNames.get(0))\n            Assert.assertEquals(statement.location, \"s3a://superior2025/iceberg/warehouse/aws_iceberg.db/iceberg_demo_1\")\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest5() {\n        val sql =\n            \"\"\"\n            CREATE TABLE `bigdata`.`export_test_dt` (\n              `message` STRING COMMENT '',\n              `collect_time` TIMESTAMP COMMENT '',\n              `the_date` STRING COMMENT '',\n              `the_nums` STRING COMMENT '')\n            USING orc\n            PARTITIONED BY (the_date, the_nums)\n            TBLPROPERTIES (\n              'transient_lastDdlTime' = '1627288235')\n            lifeCycle 100\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(\"export_test_dt\", tableName)\n            Assert.assertEquals(100, statement.lifeCycle)\n            Assert.assertEquals(\"orc\", statement.fileFormat)\n            Assert.assertEquals(\"spark\", statement.modelType)\n            Assert.assertEquals(2, statement.partitionColumnNames.size)\n            Assert.assertEquals(\"the_date\", statement.partitionColumnNames.get(0))\n            Assert.assertEquals(\"the_nums\", statement.partitionColumnNames.get(1))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest7() {\n        val sql =\n            \"\"\"\n            CREATE TABLE test_demo_test (name string, age int)\n            using orc\n            LIFECYCLE 10;\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTable) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(\"test_demo_test\", tableName)\n            Assert.assertEquals(10, statement.lifeCycle)\n            Assert.assertEquals(\"orc\", statement.fileFormat)\n            Assert.assertEquals(\"spark\", statement.modelType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest9() {\n        val sql =\n            \"\"\"\n            create table dzlog_test_dt (\n                message string,\n                collect_time timestamp\n            ) \n            using parquet\n            partitioned by (ds string) \n            lifeCycle 14;\n            \"\"\"\n\n        try {\n            SparkSqlHelper.parseStatement(sql)\n            Assert.fail()\n        } catch (e: Exception) {\n            Assert.assertTrue(true)\n        }\n    }\n\n    @Test\n    fun createTableTest10() {\n        val sql =\n            \"\"\"\n            CREATE TABLE my_table\n            USING io.github.spark_redshift_community.spark.redshift\n            OPTIONS (\n              dbtable 'my_table',\n              tempdir 's3n://path/for/temp/data',\n              url 'jdbc:redshift://redshifthost:5439/database?user=username&password=pass'\n            );\n        \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n        if (statement is CreateTable) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(\"io.github.spark_redshift_community.spark.redshift\", statement.fileFormat)\n            Assert.assertEquals(\"my_table\", tableName)\n            Assert.assertEquals(3, statement.options?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest11() {\n        val sql =\n            \"\"\"\n            CREATE TABLE my_table\n            USING io.github.spark_redshift_community.spark.redshift\n            OPTIONS (\n              dbtable 'my_table',\n              tempdir 's3n://path/for/temp/data',\n              url 'jdbc:redshift://redshifthost:5439/database?user=username&password=pass'\n            )\n            AS SELECT * FROM tabletosave;\n        \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n        if (statement is CreateTableAsSelect) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(\"io.github.spark_redshift_community.spark.redshift\", statement.fileFormat)\n            Assert.assertEquals(\"my_table\", tableName)\n            Assert.assertEquals(3, statement.options?.size)\n            Assert.assertEquals(\"SELECT * FROM tabletosave\", statement.queryStmt.getSql())\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest12() {\n        val sql =\n            \"\"\"\n            create table user(id Int, info String) clustered by (id) sorted by (id) into  4 buckets; \n        \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n        if (statement is CreateTable) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(\"user\", tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest13() {\n        val sql =\n            \"\"\"\n            CREATE TABLE cyj123.pipeline_normal99 (\n                id int,\n                name string,\n                class string,\n                area_code int,\n                pt string,\n                is_delete int,\n                age int\n            )\n            STORED BY 'org.apache.paimon.hive.PaimonStorageHandler' \n            TBLPROPERTIES (\n                'table_type' = 'PAIMON',\n                'bucket' = '2',\n                'transient_lastDdlTime' = '1717400524'\n            ) \n        \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n        if (statement is CreateTable) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(\"pipeline_normal99\", tableName)\n            Assert.assertEquals(\"org.apache.paimon.hive.PaimonStorageHandler\", statement.storageHandler)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createHudiTableTest5() {\n        val sql =\n            \"\"\"\n            create table test_hudi_table ( id int, name string, price double, ts long, dt string) \n            using hudi\n            tblproperties (\n              type = 'MOR',\n              primaryKey = 'id, name',\n              preCombineField = 'ts'\n             )\n            partitioned by (dt)\n            lifeCycle 300\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n        if (statement is CreateTable) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(\"test_hudi_table\", tableName)\n            Assert.assertEquals(\"id, name\", statement.properties?.get(\"primaryKey\"))\n            Assert.assertEquals(\"MOR\", statement.properties?.get(\"type\"))\n\n            Assert.assertEquals(300, statement.lifeCycle)\n            Assert.assertEquals(\"hudi\", statement.fileFormat)\n            Assert.assertEquals(1, statement.partitionColumnNames.size)\n            Assert.assertEquals(\"dt\", statement.partitionColumnNames.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createHudiTableTest6() {\n        val sql =\n            \"\"\"\n            create table test_hudi_table ( id int, name string, price double, ts long, dt string) \n            using hudi\n            tblproperties (\n              type = 'cow',\n              primaryKey = 'id, name',\n              preCombineField = 'ts'\n             )\n            partitioned by (dt)\n            lifeCycle 300\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n        if (statement is CreateTable) {\n            val name = statement.tableId.tableName\n            Assert.assertEquals(\"test_hudi_table\", name)\n            Assert.assertEquals(\"id, name\", statement.properties?.get(\"primaryKey\"))\n            Assert.assertEquals(\"cow\", statement.properties?.get(\"type\"))\n\n            Assert.assertEquals(300, statement.lifeCycle)\n            Assert.assertEquals(\"hudi\", statement.fileFormat)\n            Assert.assertEquals(1, statement.partitionColumnNames.size)\n            Assert.assertEquals(\"dt\", statement.partitionColumnNames.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createIcebergTable() {\n        val sql =\n            \"\"\"\n            CREATE TABLE IF NOT EXISTS iceberg_melin.test_table_02 (\n                id bigint, data string, ds timestamp) \n            USING iceberg PARTITIONED BY (days(ts))\n            lifeCycle 300\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n        if (statement is CreateTable) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(\"test_table_02\", tableName)\n\n            Assert.assertEquals(300, statement.lifeCycle)\n            Assert.assertEquals(\"iceberg\", statement.fileFormat)\n            Assert.assertEquals(1, statement.partitionColumnNames.size)\n            Assert.assertEquals(\"days(ts)\", statement.partitionColumnNames.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun replaceHudiTableTest() {\n        val sql =\n            \"\"\"\n            create or replace table test_hudi_table ( id int, name string, price double, ts long, dt string) \n            using hudi\n            tblproperties (\n              type = 'mor',\n              primaryKey = 'id, name',\n              preCombineField = 'ts'\n             )\n            partitioned by (dt)\n            lifeCycle 300\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n        if (statement is CreateTable) {\n            val tableName = statement.tableId.tableName\n            Assert.assertTrue(statement.replace)\n            Assert.assertEquals(\"test_hudi_table\", tableName)\n            Assert.assertEquals(\"id, name\", statement.properties?.get(\"primaryKey\"))\n            Assert.assertEquals(\"mor\", statement.properties?.get(\"type\"))\n\n            Assert.assertEquals(300, statement.lifeCycle)\n            Assert.assertEquals(\"hudi\", statement.fileFormat)\n            Assert.assertEquals(1, statement.partitionColumnNames.size)\n            Assert.assertEquals(\"dt\", statement.partitionColumnNames.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun descTableTest0() {\n        val sql = \"desc table users\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.DESC_TABLE, statement.statementType)\n    }\n\n    @Test\n    fun createTableLikeTest() {\n        val sql = \"create table IF NOT EXISTS test.sale_detail_like  like demo.sale_detail\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTableLike) {\n            Assert.assertEquals(TableId(\"demo\", \"sale_detail\"), statement.oldTableId)\n            Assert.assertEquals(TableId(\"test\", \"sale_detail_like\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableSelectTest() {\n        val sql =\n            \"create table \\nIF NOT EXISTS tdl_users_1 STORED AS ORC as select *, bigdata.TEST(name) from bigdata.users a left outer join address b on a.addr_id = b.id\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTableAsSelect) {\n            Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n            Assert.assertEquals(statement.fileFormat, \"ORC\")\n            Assert.assertEquals(\"tdl_users_1\", statement.tableId.tableName)\n            Assert.assertEquals(\n                \"select *, bigdata.TEST(name) from bigdata.users a left outer join address b on a.addr_id = b.id\",\n                statement.queryStmt.getSql()\n            )\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(\"users\", statement.queryStmt.inputTables.get(0).tableName)\n            Assert.assertEquals(\"address\", statement.queryStmt.inputTables.get(1).tableName)\n\n            Assert.assertTrue(statement.ifNotExists)\n\n            Assert.assertEquals(FunctionId(\"bigdata\", \"test\"), statement.queryStmt.functionNames.first())\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableSelectTest1() {\n        val sql =\n            \"\"\"\n               CREATE TABLE t\n               USING ICEBERG\n               PARTITIONED BY (b)\n               AS SELECT 1 as a, \"a\" as b\n               \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTableAsSelect) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n            Assert.assertEquals(\"ICEBERG\", statement.fileFormat)\n            Assert.assertEquals(\"t\", tableName)\n            Assert.assertEquals(\"SELECT 1 as a, \\\"a\\\" as b\", statement.queryStmt.getSql())\n            Assert.assertEquals(\"b\", statement.partitionColumnNames.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableSelectTest2() {\n        val sql =\n            \"create table \\nIF NOT EXISTS tdl_users_1 using parquet as (select * from users a left outer join address b on a.addr_id = b.id)\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTableAsSelect) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n            Assert.assertEquals(\"tdl_users_1\", tableName)\n            Assert.assertEquals(\n                \"select * from users a left outer join address b on a.addr_id = b.id\",\n                statement.queryStmt.getSql()\n            )\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(\"parquet\", statement.fileFormat)\n            Assert.assertEquals(\"address\", statement.queryStmt.inputTables.get(1).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableSelectTest3() {\n        val sql =\n            \"create table \\nIF NOT EXISTS tdl_users_1 using parquet as (select * from users a left outer join address b on a.addr_id = b.id\" +\n                \" left outer join `bigdata`.users c on c.userid_id = a.id)\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTableAsSelect) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n            Assert.assertEquals(\"tdl_users_1\", tableName)\n            // Assert.assertEquals(\"select * from users a left outer join address b on a.addr_id =\n            // b.id\",\n            // statement.querySql)\n            Assert.assertEquals(3, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(\"address\", statement.queryStmt.inputTables.get(1).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableSelectTest4() {\n        val sql =\n            \"create table huaixin_rp.bigdata.test_iceberg_1 using iceberg PARTITIONED BY(ds) as \" +\n                \"SELECT 'xxx' as name, 23 as price, '20211203' as ds\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTableAsSelect) {\n            val tableName = statement.tableId.tableName\n            Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n            Assert.assertEquals(\"test_iceberg_1\", tableName)\n            Assert.assertEquals(\"SELECT 'xxx' as name, 23 as price, '20211203' as ds\", statement.queryStmt.getSql())\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun replaceTableSelectTest() {\n        val sql =\n            \"create or replace table tdl_users_1 STORED AS ORC as select * from bigdata.users a left outer join address b on a.addr_id = b.id\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTableAsSelect) {\n            val tableName = statement.tableId.tableName\n            Assert.assertTrue(statement.replace)\n            Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n            Assert.assertEquals(statement.fileFormat, \"ORC\")\n            Assert.assertEquals(\"tdl_users_1\", tableName)\n            Assert.assertEquals(\n                \"select * from bigdata.users a left outer join address b on a.addr_id = b.id\",\n                statement.queryStmt.getSql()\n            )\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(\"users\", statement.queryStmt.inputTables.get(0).tableName)\n            Assert.assertEquals(\"address\", statement.queryStmt.inputTables.get(1).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropTableTest() {\n        val sql = \"drop table if exists sale_detail_drop2\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)\n        if (statement is DropTable) {\n            val name = statement.tableId?.tableName\n            Assert.assertEquals(\"sale_detail_drop2\", name)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropViewTest() {\n        val sql = \"drop view if exists sale_detail_drop2\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.DROP_VIEW, statement.statementType)\n        if (statement is DropView) {\n            Assert.assertEquals(\"sale_detail_drop2\", statement.tableId?.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun truncateTableTest() {\n        val sql = \"TRUNCATE TABLE test.user partition(ds='20170403')\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is TruncateTable) {\n            val name = statement.tableId.tableName\n            Assert.assertEquals(\"user\", name)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun msckTableTest() {\n        val sql = \"MSCK REPAIR TABLE test.user\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is RepairTable) {\n            val name = statement.tableId.tableName\n            Assert.assertEquals(\"user\", name)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createViewTest0() {\n        val sql =\n            \"\"\"CREATE View view_users\n            comment 'view test'\n            as\n            select * from account\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateView) {\n            Assert.assertEquals(StatementType.CREATE_VIEW, statement.statementType)\n            Assert.assertEquals(\"view_users\", statement.tableId.tableName)\n            Assert.assertEquals(\"view test\", statement.comment)\n            Assert.assertEquals(\"select * from account\", statement.queryStmt.getSql())\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createViewTest1() {\n        val sql =\n            \"\"\"CREATE View if not exists view_users\n            comment 'view test'\n            as\n            select *, bigdata.test(name) from account\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateView) {\n            Assert.assertEquals(StatementType.CREATE_VIEW, statement.statementType)\n            Assert.assertEquals(\"view_users\", statement.tableId.tableName)\n            Assert.assertEquals(\"view test\", statement.comment)\n            Assert.assertEquals(1, statement.queryStmt.functionNames.size)\n            Assert.assertEquals(FunctionId(\"bigdata\", \"test\"), statement.queryStmt.functionNames.first())\n\n            Assert.assertEquals(\"select *, bigdata.test(name) from account\", statement.queryStmt.getSql())\n            Assert.assertEquals(\"account\", statement.queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTemporaryViewTest0() {\n        val sql =\n            \"\"\"\n            CREATE TEMPORARY VIEW jdbcTable\n            USING org.apache.spark.sql.jdbc\n            OPTIONS (\n              url \"jdbc:postgresql:dbserver\",\n              dbtable \"schema.tablename\",\n              user 'username',\n              password 'password'\n            )\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateTempViewUsing) {\n            Assert.assertEquals(StatementType.CREATE_TEMP_VIEW_USING, statement.statementType)\n            Assert.assertEquals(\"jdbcTable\", statement.tableId.tableName)\n            Assert.assertEquals(\"org.apache.spark.sql.jdbc\", statement.fileFormat)\n            Assert.assertEquals(4, statement.properties.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun alterViewTest0() {\n        val sql = \"ALTER VIEW v1 AS SELECT x, UPPER(s) s FROM t2\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"v1\", statement.tableId.tableName)\n            val action = statement.firstAction() as AlterViewAction\n            Assert.assertEquals(AlterActionType.ALTER_VIEW_QUERY, statement.firstAction().alterType)\n            Assert.assertEquals(\"SELECT x, UPPER(s) s FROM t2\", action.queryStmt.getSql())\n            Assert.assertEquals(\"t2\", action.queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun renameTableTest() {\n        val sql = \"alter table test.table_name rename to new_table_name\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            val action = statement.firstAction() as RenameAction\n            Assert.assertEquals(AlterActionType.RENAME, action.alterType)\n            Assert.assertEquals(\"new_table_name\", action.newTableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun touchTableTest() {\n        val sql = \"alter table test.table_name TOUCH\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"table_name\", statement.tableId.tableName)\n            Assert.assertEquals(AlterActionType.TOUCH_TABLE, statement.firstAction().alterType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun touchTablePrtitionTest() {\n        val sql = \"alter table test.table_name TOUCH partition(ds=20210812, type='login')\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"table_name\", statement.tableId.tableName)\n            val action = statement.firstAction() as AlterTouchPartitionAction\n            Assert.assertEquals(AlterActionType.TOUCH_TABLE, action.alterType)\n            Assert.assertEquals(2, action.partitionVals?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun alterTablePropertiesTest() {\n        var sql =\n            \"ALTER TABLE test.sale_detail SET TBLPROPERTIES ('comment' = 'new coments for statement sale_detail', 'lifeCycle' = '7')\"\n\n        var statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"sale_detail\", statement.tableId.tableName)\n            val action = statement.firstAction() as AlterPropsAction\n            Assert.assertEquals(2, action.properties.size)\n        } else {\n            Assert.fail()\n        }\n\n        sql = \"ALTER TABLE aaa.bbb SET SERDEPROPERTIES ('field.delim' = ',')\"\n        statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"bbb\", statement.tableId.tableName)\n            val action = statement.firstAction() as AlterSerDeAction\n            Assert.assertEquals(1, action.properties.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun addColumnsTest() {\n        val sql =\n            \"alter table test.sale_detail add columns (col_name1 string comment 'col_name1', col_name2 string comment 'col_name2')\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"sale_detail\", statement.tableId.tableName)\n            val cols = statement.actions as List<AlterColumnAction>\n            Assert.assertEquals(2, cols.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun addColumnTest() {\n        val sql = \"ALTER TABLE db.sample ADD COLUMN age int FIRST\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"sample\", statement.tableId.tableName)\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(\"first\", action.position)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun renameColumnTest() {\n        val sql = \"ALTER TABLE db.sample RENAME COLUMN data TO payload\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"sample\", statement.tableId.tableName)\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(\"payload\", action.newColumName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun changeColumnTest() {\n        var sql = \"ALTER TABLE db.sample ALTER COLUMN location.lat TYPE double\"\n        var statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"sample\", statement.tableId.tableName)\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(\"double\", action.dataType)\n        } else {\n            Assert.fail()\n        }\n\n        sql = \"ALTER TABLE db.sample ALTER COLUMN id DROP NOT NULL\"\n        statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"sample\", statement.tableId.tableName)\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(\"id\", action.columName)\n        } else {\n            Assert.fail()\n        }\n\n        sql = \"ALTER TABLE db.sample ALTER COLUMN point.z AFTER y\"\n        statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"sample\", statement.tableId.tableName)\n\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(\"after\", action.position)\n            Assert.assertEquals(\"y\", action.afterCol)\n        } else {\n            Assert.fail()\n        }\n\n        sql = \"ALTER TABLE db.sample ALTER COLUMN id COMMENT 'unique id'\"\n        statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"sample\", statement.tableId.tableName)\n\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(\"unique id\", action.comment)\n        } else {\n            Assert.fail()\n        }\n\n        sql = \"ALTER TABLE demo CHANGE COLUMN price Type float COMMENT '价格'\"\n        statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"demo\", statement.tableId.tableName)\n\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(\"float\", action.dataType)\n            Assert.assertEquals(\"价格\", action.comment)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun changeColumnTest1() {\n        val sql = \"ALTER TABLE test_user11_dt ALTER COLUMN ds comment 'ddd'\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"test_user11_dt\", statement.tableId.tableName)\n\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(\"ds\", action.columName)\n            Assert.assertNull(action.newColumName)\n            Assert.assertNull(action.dataType)\n            Assert.assertEquals(\"ddd\", action.comment)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropColumnTest() {\n        val sql = \"ALTER TABLE db.sample DROP COLUMN id\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"sample\", statement.tableId.tableName)\n\n            val action = statement.firstAction() as DropColumnAction\n            Assert.assertEquals(\"id\", action.columNames.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setTableLocationTest() {\n        val sql = \"alter table demo partition(ds='20180317') set location '/user/hive'\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n            Assert.assertEquals(\"demo\", statement.tableId.tableName)\n            val action = statement.firstAction() as AlterPropsAction\n            Assert.assertEquals(\"/user/hive\", action.location)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateColumnTest() {\n        val sql = \"ALTER TABLE sale_detail CHANGE COLUMN old_col_name new_col_name string comment 'sdsd'\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"sale_detail\", statement.tableId.tableName)\n\n            val action = statement.firstAction() as AlterColumnAction\n            Assert.assertEquals(\"new_col_name\", action.newColumName)\n            Assert.assertEquals(\"sdsd\", action.comment)\n        } else {\n            Assert.fail()\n        }\n\n        val sql1 = \"ALTER TABLE test_users_dt CHANGE age2 age3 int\"\n\n        val statement1 = SparkSqlHelper.parseStatement(sql1)\n        if (statement1 is AlterTable) {\n            Assert.assertEquals(\"test_users_dt\", statement1.tableId.tableName)\n\n            val action = statement1.firstAction() as AlterColumnAction\n            Assert.assertEquals(\"age3\", action.newColumName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropPartitionTest0() {\n        val sql =\n            \"ALTER TABLE page_view DROP IF EXISTS PARTITION (dt='2008-08-08', country='us'), PARTITION (dt='2008-08-09', country='us')\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"page_view\", statement.tableId.tableName)\n            val action = statement.firstAction() as DropPartitionAction\n            Assert.assertTrue(action.ifExists)\n            Assert.assertEquals(AlterActionType.DROP_PARTITION, action.alterType)\n            // Assert.assertEquals(2, action.partitions.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropPartitionTest1() {\n        val sql =\n            \"ALTER TABLE page_view DROP PARTITION (dt='2008-08-08', country='us'), PARTITION (dt='2008-08-09', country='us')\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"page_view\", statement.tableId.tableName)\n            val action = statement.firstAction() as DropPartitionAction\n            Assert.assertFalse(action.ifExists)\n            Assert.assertEquals(AlterActionType.DROP_PARTITION, action.alterType)\n            // Assert.assertEquals(2, action.partitions.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropPartitionTest2() {\n        val sql = \"ALTER TABLE page_view DROP PARTITION (dt<'2008-08-08')\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"page_view\", statement.tableId.tableName)\n            val action = statement.firstAction() as DropPartitionAction\n            Assert.assertFalse(action.ifExists)\n            Assert.assertEquals(AlterActionType.DROP_PARTITION, action.alterType)\n            // Assert.assertEquals(2, action.partitions.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun addPartitionTest0() {\n        val sql = \"ALTER TABLE page_view ADD PARTITION (partCol = 'value1') \"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"page_view\", statement.tableId.tableName)\n            val action = statement.firstAction() as AddPartitionAction\n            Assert.assertFalse(action.ifNotExists)\n            Assert.assertEquals(AlterActionType.ADD_PARTITION, action.alterType)\n            Assert.assertEquals(1, action.partitions.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun addPartitionTest1() {\n        val sql = \"ALTER TABLE page_view add IF NOT EXISTS PARTITION (dt='2008-08-08', country='us')\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"page_view\", statement.tableId.tableName)\n            val action = statement.firstAction() as AddPartitionAction\n            Assert.assertTrue(action.ifNotExists)\n            Assert.assertEquals(AlterActionType.ADD_PARTITION, action.alterType)\n            Assert.assertEquals(1, action.partitions.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun renamePartitionTest() {\n        val sql = \"ALTER TABLE page_view PARTITION (dt='2008-08-08')  RENAME TO PARTITION (dt='20080808')\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n        if (statement is AlterTable) {\n            Assert.assertEquals(\"page_view\", statement.tableId.tableName)\n            val action = statement.firstAction() as RenamePartitionAction\n            Assert.assertEquals(AlterActionType.RENAME_PARTITION, action.alterType)\n            Assert.assertEquals(1, action.fromPartitionVals.size)\n            Assert.assertEquals(1, action.toPartitionVals.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFuncTest() {\n        val sql =\n            \"CREATE FUNCTION test.train_perceptron AS 'hivemall.classifier.PerceptronUDTF' \" +\n                \"using jar 'hdfs://tdhdfs/user/datacompute/platformtool/resources/132/latest/hivemall-spark.jar'\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateFunction) {\n            Assert.assertEquals(\"test\", statement.functionId.schemaName)\n            Assert.assertEquals(\"train_perceptron\", statement.functionId.functionName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFuncTest1() {\n        val sql =\n            \"CREATE TEMPORARY FUNCTION IF NOT EXISTS stream_json_extract_value \" +\n                \"AS 'com.dataworker.spark.jobserver.driver.udf.GenericUDTFJsonExtractValue'\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CreateFunction) {\n            Assert.assertEquals(\"stream_json_extract_value\", statement.functionId.functionName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropFuncTest() {\n        val sql = \"drop FUNCTION train_perceptron\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is DropFunction) {\n            Assert.assertEquals(\"train_perceptron\", statement.functionId.functionName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest0() {\n        val sql =\n            \"\"\"\n            select * from `demo_rp`.bigdata.users a join address b on a.addr_id=b.id limit 101 OFFSET 10\n            select * from `demo_rp`.bigdata.users1 a join address1 b on a.addr_id=b.id limit 102\n            select transform(name,idcard) USING 'python udf-python.py'  AS (name,id_card,gre) from db_mxy.person\n        \"\"\"\n                .trimIndent()\n\n        val statements = SparkSqlHelper.parseMultiStatement(sql)\n\n        Assert.assertEquals(3, statements.size)\n\n        val query0 = statements.get(0)\n        val query1 = statements.get(1)\n        if (query0 is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, query0.statementType)\n            Assert.assertEquals(2, query0.inputTables.size)\n            Assert.assertEquals(\"users\", query0.inputTables.get(0).tableName)\n            Assert.assertEquals(\"demo_rp.bigdata.users\", query0.inputTables.get(0).getFullTableName())\n            Assert.assertEquals(\"address\", query0.inputTables.get(1).tableName)\n            Assert.assertEquals(101, query0.limit)\n            Assert.assertEquals(10, query0.offset)\n        }\n        if (query1 is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, query1.statementType)\n            Assert.assertEquals(2, query1.inputTables.size)\n            Assert.assertEquals(\"users1\", query1.inputTables.get(0).tableName)\n            Assert.assertEquals(\"demo_rp.bigdata.users1\", query1.inputTables.get(0).getFullTableName())\n            Assert.assertEquals(\"address1\", query1.inputTables.get(1).tableName)\n            Assert.assertEquals(102, query1.limit)\n            Assert.assertNull(query1.offset)\n        }\n    }\n\n    @Test\n    fun queryTest1() {\n        val sql = \"select * from (select * from users where name='melin') a limit 1001\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(\"users\", statement.inputTables.get(0).tableName)\n            Assert.assertEquals(1001, statement.limit)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest2() {\n        val sql =\n            \"select * from users a join (select * from address where type='hangzhou') b on a.addr_id=b.id limit 101\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(2, statement.inputTables.size)\n            Assert.assertEquals(\"users\", statement.inputTables.get(0).tableName)\n            Assert.assertEquals(\"address\", statement.inputTables.get(1).tableName)\n            Assert.assertEquals(101, statement.limit)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest3() {\n        val sql =\n            \"\"\"\n            select bzdys, bzhyyh, bzdy, week, round((bzdy-bzdys)*100/bzdys, 2)\n            from (\n                select lag(bzdy) over (order by week) bzdys, bzhyyh, bzdy, week\n                from (\n                    select count(distinct partner_code) bzhyyh, count(1) bzdy, week from tdl_dt2x_table\n                ) a\n            ) b limit 111\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(\"tdl_dt2x_table\", statement.inputTables.get(0).tableName)\n            Assert.assertEquals(111, statement.limit)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest4() {\n        val sql = \"select 2-1\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest5() {\n        val sql =\n            \"select \\n\" +\n                \"     t.table_name\\n\" +\n                \"     ,concat_ws('.',t.database_name,t.table_name) tab_name\\n\" +\n                \"     ,t.database_name\\n\" +\n                \"     ,t.owner \\n\" +\n                \"     ,count(distinct t2.project_code) prj_cnt\\n\" +\n                \"     ,count(distinct t1.obj_name) app_user_cnt\\n\" +\n                \"     from tidb_datacompute.t_table t \\n\" +\n                \"     left join tidb_datacompute.sec_table_privs t1\\n\" +\n                \"            on t.table_name = t1.table_name\\n\" +\n                \"           and t1.status=1\\n\" +\n                \"           and t1.expire_date >= current_date()\\n\" +\n                \"     left join tidb_datacompute.dc_project_member t2\\n\" +\n                \"             on t1.obj_id = t2.user_id\\n\" +\n                \"     where t.`lifecycle` == 1\" +\n                \"     group by t.table_name,t.owner,t.database_name \"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(3, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest6() {\n        val sql = \"select * from test\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest7() {\n        val sql = \"select true is false\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest8() {\n        val sql = \"select 'test' as name\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertIntoTest0() {\n        val sql =\n            \"insert into TABLE users PARTITION(ds='20170220') values('libinsong', 12, 'test'), ('libinsong', 13, 'test')\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(InsertMode.INTO, statement.mode)\n            Assert.assertEquals(\"users\", statement.tableId.tableName)\n            Assert.assertEquals(2, statement.rows?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertIntoTest1() {\n        val sql = \"insert into bigdata.delta_lsw_test values('lsw'),('lsw1')\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(InsertMode.INTO, statement.mode)\n            Assert.assertEquals(\"delta_lsw_test\", statement.tableId.tableName)\n            Assert.assertEquals(2, statement.rows?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertIntoTest2() {\n        val sql = \"insert into demo SELECT * FROM hudi_table_changes('db.table', 'latest_state', 'earliest')\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(InsertMode.INTO, statement.mode)\n\n            Assert.assertEquals(\"demo\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.queryStmt.functionNames.size)\n            Assert.assertEquals(\"hudi_table_changes\", statement.queryStmt.functionNames.first().functionName)\n            Assert.assertEquals(\"TVF\", statement.queryStmt.functionNames.first().funcType)\n            Assert.assertEquals(3, statement.queryStmt.functionNames.first().functionArguments.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTableCustomColumn() {\n        val sql = \"INSERT INTO test_demo_test (name) VALUES('lisi')\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(InsertMode.INTO, statement.mode)\n            Assert.assertEquals(\"test_demo_test\", statement.tableId?.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertOverwriteTest0() {\n        val sql = \"insert OVERWRITE TABLE users PARTITION(ds='20170220', type='login') values('libinsong')\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(InsertMode.OVERWRITE, statement.mode)\n            Assert.assertEquals(2, statement.partitionVals?.size)\n            Assert.assertEquals(\"users\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertOverwriteTest1() {\n        val sql = \"insert OVERWRITE TABLE users PARTITION(ds) values('libinsong', '20170220')\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(InsertMode.OVERWRITE, statement.mode)\n            Assert.assertEquals(1, statement.partitionVals?.size)\n            Assert.assertEquals(\"users\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertOverwriteQueryTest2() {\n        val sql =\n            \"insert /*+ primarys(t1, t2) */ INTO users PARTITION(ds='20170220', type='login') select * from account a join address b on a.addr_id=b.id\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"users\", statement.tableId.tableName)\n            Assert.assertEquals(InsertMode.INTO, statement.mode)\n            Assert.assertEquals(2, statement.partitionVals?.size)\n\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(\"account\", statement.queryStmt.inputTables.get(0).tableName)\n            Assert.assertEquals(\"address\", statement.queryStmt.inputTables.get(1).tableName)\n\n            Assert.assertEquals(1, statement.hints?.size)\n            Assert.assertEquals(2, statement.hints?.get(\"primarys\")?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertOverwriteQueryTest3() {\n        val sql = \"insert INTO users select *, bigdata.Test(id) from account a join address b on a.addr_id=b.id\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"users\", statement.tableId?.tableName)\n            Assert.assertEquals(InsertMode.INTO, statement.mode)\n            Assert.assertEquals(0, statement.partitionVals?.size)\n            Assert.assertEquals(\n                statement.queryStmt.getSql(),\n                \"select *, bigdata.Test(id) from account a join address b on a.addr_id=b.id\"\n            )\n\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(\"account\", statement.queryStmt.inputTables.get(0).tableName)\n            Assert.assertEquals(\"address\", statement.queryStmt.inputTables.get(1).tableName)\n\n            Assert.assertEquals(FunctionId(\"bigdata\", \"test\"), statement.queryStmt.functionNames.first())\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertOverwriteQueryTest4() {\n        val sql =\n            \"insert OVERWRITE TABLE users PARTITION(ds='20170220') select * from account1 union all \" +\n                \"select * from account2\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"users\", statement.tableId?.tableName)\n            Assert.assertEquals(InsertMode.OVERWRITE, statement.mode)\n            Assert.assertEquals(1, statement.partitionVals?.size)\n\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(\"account1\", statement.queryStmt.inputTables.get(0).tableName)\n            Assert.assertEquals(\"account2\", statement.queryStmt.inputTables.get(1).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun mutilInsertTest() {\n        val sql =\n            \"FROM default.sample_07\\n\" +\n                \"\\n\" +\n                \"INSERT OVERWRITE TABLE toodey1 SELECT sample_07.code,sample_07.salary\\n\" +\n                \"\\n\" +\n                \"INSERT OVERWRITE TABLE toodey2 SELECT sample_07.code,sample_07.salary WHERE sample_07.salary >= 50000\\n\" +\n                \"\\n\" +\n                \"INSERT OVERWRITE TABLE toodey3 SELECT sample_07.total_emp,sample_07.salary WHERE sample_07.salary <= 50000\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(3, statement.outputTables.size)\n            Assert.assertEquals(\"sample_07\", statement.queryStmt.inputTables.get(0).tableName)\n            Assert.assertEquals(\"toodey3\", statement.outputTables.get(2).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun useTest() {\n        val sql = \"use bigdata\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.USE, statement.statementType)\n\n        if (statement is UseDatabase) {\n            Assert.assertEquals(\"bigdata\", statement.databaseName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setTest() {\n        val sql =\n            \"\"\"\n            set spark.executor.memory = 30g\n            set spark.sql.enabled=true;\n            set spark.sql.test=\"ddsd\";\n            set spark.sql.test2;\n            reset spark.sql.test;\n        \"\"\"\n                .trimIndent()\n\n        val statements = SparkSqlHelper.parseMultiStatement(sql)\n        Assert.assertEquals(5, statements.size)\n    }\n\n    @Test\n    fun mergeTest() {\n        val sql = \"merge table test OPTIONS (mergefile=2)\"\n        SparkSqlHelper.parseStatement(sql)\n    }\n\n    @Test\n    fun substrFile() {\n        val sql = \"SELECT substring('Spark SQL' from 5)\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.SELECT, statement.statementType)\n    }\n\n    @Test\n    fun druidSql() {\n        val sql = \"SELECT * from druid.`select * from test`\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.SELECT, statement.statementType)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(\"druid\", statement.inputTables.get(0).schemaName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun druidSql1() {\n        val sql = \"SELECT * from tdl_xdsd_sd\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.SELECT, statement.statementType)\n        if (statement is QueryStmt) {\n            Assert.assertNull(statement.inputTables.get(0).schemaName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest() {\n        val sql =\n            \"\"\"\n            DELETE FROM films\n            WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest0() {\n        val sql =\n            \"\"\"\n            UPDATE employees SET sales_count = sales_count + 1 WHERE id =\n            (SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId?.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest1() {\n        val sql = \"update user set name='xxx'\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"user\", statement.tableId?.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deltaMergeTest() {\n        val sql =\n            \"\"\"\n            MERGE INTO logs\n            USING updates\n            ON logs.uniqueId = updates.uniqueId\n            WHEN NOT MATCHED\n              THEN INSERT *\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is MergeTable) {\n            Assert.assertEquals(StatementType.MERGE, statement.statementType)\n            Assert.assertEquals(\"logs\", statement.targetTable.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deltaMergeTest0() {\n        val sql =\n            \"\"\"\n            MERGE INTO logs\n            USING updates\n            ON logs.uniqueId = updates.uniqueId AND logs.date > current_date() - INTERVAL 7 DAYS\n            WHEN NOT MATCHED AND updates.date > current_date() - INTERVAL 7 DAYS\n              THEN INSERT *\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is MergeTable) {\n            Assert.assertEquals(StatementType.MERGE, statement.statementType)\n            Assert.assertEquals(\"logs\", statement.targetTable.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deltaMergeTest1() {\n        val sql =\n            \"\"\"\n            MERGE INTO customers\n            USING (\n              SELECT updates.customerId as mergeKey, updates.*\n              FROM updates\n              UNION ALL\n              SELECT NULL as mergeKey, updates.*\n              FROM updates JOIN customers\n              ON updates.customerid = customers.customerid \n              WHERE customers.current = true AND updates.address <> customers.address\n            ) staged_updates\n            ON customers.customerId = mergeKey\n            WHEN MATCHED AND customers.current = true AND customers.address <> staged_updates.address THEN  \n              UPDATE SET current = false, endDate = staged_updates.effectiveDate\n            WHEN NOT MATCHED THEN \n              INSERT(customerid, address, current, effectivedate, enddate) \n              VALUES(staged_updates.customerId, staged_updates.address, true, staged_updates.effectiveDate, null)\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is MergeTable) {\n            Assert.assertEquals(StatementType.MERGE, statement.statementType)\n            Assert.assertEquals(\"customers\", statement.targetTable.tableName)\n            Assert.assertEquals(2, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deltaMergeTest2() {\n        val sql =\n            \"\"\"\n            MERGE INTO target t\n            USING (\n              SELECT key, latest.newValue as newValue, latest.deleted as deleted FROM (    \n                SELECT key, max(struct(time, newValue, deleted)) as latest FROM changes GROUP BY key\n              )\n            ) s\n            ON s.key = t.key\n            WHEN MATCHED AND s.deleted = true THEN DELETE\n            WHEN MATCHED THEN UPDATE SET key = s.key, value = s.newValue\n            WHEN NOT MATCHED AND s.deleted = false THEN INSERT (key, value) VALUES (key, newValue)\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is MergeTable) {\n            Assert.assertEquals(StatementType.MERGE, statement.statementType)\n            Assert.assertEquals(\"target\", statement.targetTable.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deltaMergeTest3() {\n        val sql =\n            \"\"\"\n            MERGE INTO\n               bigdata.merge_test a1\n            USING\n               bigdata.merge_test1 a2\n            ON\n               a1.name = a2.name\n            WHEN MATCHED THEN UPDATE SET a1.age = a2.age\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is MergeTable) {\n            Assert.assertEquals(StatementType.MERGE, statement.statementType)\n            Assert.assertEquals(\"merge_test\", statement.targetTable.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun cetSelectTest0() {\n        val sql =\n            \"\"\"\n            with q1 as ( select key from q2 where key = '5'),\n            q2 as ( select key from test where key = '5')\n            select * from (select key from q1) a\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(2, statement.inputTables.size)\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun cetInsertTest0() {\n        val sql =\n            \"\"\"\n            with\n            a as (select * from src where key is not null),\n            b as (select  * from src2 where value>0),\n            c as (select * from src3 where value>0),\n            d as (select a.key,b.value from a join b on a.key=b.key),\n            e as (select a.key,c.value from a left outer join c on a.key=c.key and c.key is not null)\n            insert overwrite table srcp partition (p='abc')\n            select * from d union all select * from e\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(3, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun exportTest0() {\n        val sql =\n            \"\"\"\n           with \n                a as (select * from test),\n                druid_result as (select * from a)\n           export table druid_result TO 'druid_result.csv'\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is ExportTable) {\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(StatementType.EXPORT_TABLE, statement.statementType)\n            Assert.assertEquals(\"druid_result\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createExternalTableTest1() {\n        val sql =\n            \"\"\"CREATE EXTERNAL TABLE s3Db.test_zc_s3(\n                        name String COMMENT 'name',\n                        cnt INT COMMENT 'cnt'\n                    ) COMMENT '原始数据表'\n                    LOCATION 's3a://hive/test/'\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is CreateTable) {\n            val schemaName = statement.tableId.schemaName\n            Assert.assertEquals(statement.location, \"s3a://hive/test/\")\n            Assert.assertEquals(\"s3Db\", schemaName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTbl() {\n        val sql =\n            \"\"\"create table bigdata.test_orc9_dt (\n                        name string comment '',\n                        name2 String comment ''\n                    )\n                    TBLPROPERTIES ('compression'='ZSTD', 'fileFormat'='orc', 'encryption'='0', \"orc.encrypt\"=\"hz_admin_key:name2\", \"orc.mask\"='nullify:name')\n                    STORED AS orc\n                    comment 'orc测试'\n                    lifecycle 7\n            \"\"\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is CreateTable) {\n            val prop = statement.properties\n            Assert.assertEquals(\"ZSTD\", prop?.get(\"compression\"))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun countCondTest() {\n        val sql = \"select count(type='mac' or null) From test_table where a=2\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(\"test_table\", statement.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    // @Test\n    fun queryLakeTableMetaTest0() {\n        val sql = \"select * from dc.user.history limit 101\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(\"user\", statement.inputTables.get(0).tableName)\n            // Assert.assertEquals(\"history\", statement.inputTables.get(0).metaAction)\n            Assert.assertEquals(101, statement.limit)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    // @Test\n    fun queryLakeTableMetaTest1() {\n        val sql =\n            \"\"\"\n            select h.made_current_at, s.operation, h.snapshot_id, h.is_current_ancestor, s.summary['spark.app.id']\n            from db.table.history h\n            join db.table.snapshots s on h.snapshot_id = s.snapshot_id\n            order by made_current_at\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(2, statement.inputTables.size)\n            Assert.assertEquals(\"table\", statement.inputTables.get(0).tableName)\n            // Assert.assertEquals(\"history\", statement.inputTables.get(0).metaAction)\n\n            Assert.assertEquals(\"table\", statement.inputTables.get(1).tableName)\n            // Assert.assertEquals(\"snapshots\", statement.inputTables.get(1).metaAction)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dtunnelTest0() {\n        val sql =\n            \"datatunnel source('sftp') options(host='x.x.x.x') sink('hive') options(table='demo', columns=['id', 'name'])\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is DataTunnelExpr) {\n            Assert.assertEquals(StatementType.DATATUNNEL, statement.statementType)\n            Assert.assertEquals(\"sftp\", statement.sourceType)\n            Assert.assertEquals(\"x.x.x.x\", statement.sourceOptions.get(\"host\"))\n\n            Assert.assertEquals(\"hive\", statement.sinkType)\n            Assert.assertEquals(\"demo\", statement.sinkOptions.get(\"table\"))\n\n            val list = statement.sinkOptions.get(\"columns\") as List<String>\n            Assert.assertEquals(2, list.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dtunnelTest1() {\n        val sql =\n            \"\"\"\n            datatunnel source('sftp') options(host='x.x.x.x') \n            transform = \"select * from result where type='sql'\"\n            sink('hive') options(table='demo', columns=['id', 'name'])\n        \"\"\"\n                .trimIndent()\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is DataTunnelExpr) {\n            Assert.assertEquals(StatementType.DATATUNNEL, statement.statementType)\n            Assert.assertEquals(\"sftp\", statement.sourceType)\n            Assert.assertEquals(\"x.x.x.x\", statement.sourceOptions.get(\"host\"))\n\n            Assert.assertEquals(\"select * from result where type='sql'\", statement.transformSql)\n\n            Assert.assertEquals(\"hive\", statement.sinkType)\n            Assert.assertEquals(\"demo\", statement.sinkOptions.get(\"table\"))\n\n            val list = statement.sinkOptions.get(\"columns\") as List<String>\n            Assert.assertEquals(2, list.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dtunnelTest2() {\n        val sql = \"datatunnel source('sftp') options(host='x.x.x.x') sink('log')\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is DataTunnelExpr) {\n            Assert.assertEquals(StatementType.DATATUNNEL, statement.statementType)\n            Assert.assertEquals(\"sftp\", statement.sourceType)\n            Assert.assertEquals(\"x.x.x.x\", statement.sourceOptions.get(\"host\"))\n\n            Assert.assertEquals(\"log\", statement.sinkType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dtunnelTest3() {\n        val sql =\n            \"\"\"\n            WITH tmp_demo_test2 AS (SELECT *, test(id) FROM bigdata.test_demo_test2 where name is not null), \n                 tmp_demo_test3 AS (select * from tmp_demo_test2) \n                datatunnel SOURCE('hive') OPTIONS(\n                databaseName='bigdata',\n                tableName='tmp_demo_test2',\n                columns=['*'])\n            SINK('log') OPTIONS(numRows = 10)\n        \"\"\"\n                .trimIndent()\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is DataTunnelExpr) {\n            Assert.assertEquals(StatementType.DATATUNNEL, statement.statementType)\n            Assert.assertEquals(\"hive\", statement.sourceType)\n\n            Assert.assertEquals(\"log\", statement.sinkType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(1, statement.functionNames.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dtunnelTest4() {\n        val sql =\n            \"\"\"\n            DATATUNNEL SOURCE('oracle') OPTIONS(\n                username='flinkuser',\n                password='flinkpw',\n                host='172.18.1.56',\n                port=1521,\n                serviceName='XE',\n                databaseName='FLINKUSER',    tableName='ORDERS', \n                columns=[{'name' : \"pk\", \"type\" : \"id\"},\n                          { \"name\" : \"col_ip\",\"type\" : \"ip\" },\n                          { \"name\" : \"col_double\",\"type\" : \"double\" },\n                          { \"name\" : \"col_long\",\"type\" : \"long\" },\n                          { \"name\" : \"col_keyword\", \"type\" : \"keyword\" },\n                          { \"name\" : \"col_text\", \"type\" : \"text\", \"analyzer\" : \"ik_max_word\"},\n                          { \"name\" : \"col_geo_point\", \"type\" : \"geo_point\" },\n                          { \"name\" : \"col_date\", \"type\" : \"date\", \"format\" : \"yyyy-MM-dd HH:mm:ss\"},\n                          { \"name\" : \"col_nested1\", \"type\" : \"nested\" },\n                          { \"name\" : \"col_object1\", \"type\" : \"object\" },\n                          { \"name\" : \"col_integer_array\", \"type\" : \"integer\", \"array\" : TRUE},\n                          { \"name\" : \"col_geo_shape\", \"type\" : \"geo_shape\", \"tree\" : \"quadtree\", \"precision\" : \"10m\"}\n                        ])\n                SINK('log') OPTIONS(numRows = 10)\n        \"\"\"\n                .trimIndent()\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is DataTunnelExpr) {\n            Assert.assertEquals(StatementType.DATATUNNEL, statement.statementType)\n            Assert.assertEquals(\"oracle\", statement.sourceType)\n\n            Assert.assertEquals(\"log\", statement.sinkType)\n            val list = statement.sourceOptions.get(\"columns\") as List<HashMap<String, String>>\n            Assert.assertEquals(12, list.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dtunnelHelpTest() {\n        val sql = \"datatunnel help source('sftp')\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is DataTunnelHelp) {\n            Assert.assertEquals(StatementType.HELP, statement.statementType)\n\n            Assert.assertEquals(\"source\", statement.type)\n            Assert.assertEquals(\"sftp\", statement.value)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun callTest0() {\n        val sql =\n            \"CALL catalog_name.system.create_savepoint(table => 'test_hudi_table', instant_time => '20220109225319449')\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CallProcedure) {\n            Assert.assertEquals(StatementType.CALL, statement.statementType)\n            Assert.assertEquals(\"catalog_name\", statement.procedureIds.first().catalogName)\n            Assert.assertEquals(\"system\", statement.procedureIds.first().schemaName)\n            Assert.assertEquals(\"create_savepoint\", statement.procedureIds.first().procedureName)\n            Assert.assertEquals(2, statement.properties.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun callTest1() {\n        val sql = \"call stats_file_sizes(table => 'test_hudi_demo')\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CallProcedure) {\n            Assert.assertEquals(StatementType.CALL, statement.statementType)\n            Assert.assertEquals(\"stats_file_sizes\", statement.procedureIds.first().procedureName)\n            Assert.assertEquals(1, statement.properties.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun callTest2() {\n        val sql =\n            \"\"\"\n            CALL system.remove_orphan_files(\n              table => 'bigdata.ods_iceberg_01',\n              older_than => CURRENT_TIMESTAMP - INTERVAL '5' DAYS,\n              dry_run => true\n            )\n        \"\"\"\n                .trimIndent()\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CallProcedure) {\n            Assert.assertEquals(StatementType.CALL, statement.statementType)\n            Assert.assertEquals(\"remove_orphan_files\", statement.procedureIds.first().procedureName)\n            Assert.assertEquals(3, statement.properties.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun callHelpTest1() {\n        val sql = \"CALL help\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CallHelp) {\n            Assert.assertEquals(StatementType.HELP, statement.statementType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun callHelpTest2() {\n        val sql = \"CALL help(cmd => 'show_commits')\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CallHelp) {\n            Assert.assertEquals(StatementType.HELP, statement.statementType)\n            Assert.assertEquals(\"show_commits\", statement.procedureName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun callHelpTest3() {\n        val sql = \"CALL help show_commits\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is CallHelp) {\n            Assert.assertEquals(StatementType.HELP, statement.statementType)\n            Assert.assertEquals(\"show_commits\", statement.procedureName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun syncSchemaTest() {\n        val sql = \"SYNC Database FROM hive_metastore.my_db SET OWNER wangwu\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is SyncDatabaseMetadata) {\n            Assert.assertEquals(StatementType.SYNC_META, statement.statementType)\n            Assert.assertEquals(\"hive_metastore\", statement.catalogName)\n            Assert.assertEquals(\"my_db\", statement.databaseName)\n            Assert.assertEquals(\"wangwu\", statement.owner)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun syncTableMetaTest() {\n        val sql = \"SYNC TABLE FROM hive_metastore.default.my_tbl\"\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is SyncTableMetadata) {\n            Assert.assertEquals(StatementType.SYNC_META, statement.statementType)\n            Assert.assertEquals(\"hive_metastore\", statement.tableId.catalogName)\n            Assert.assertEquals(\"default\", statement.tableId.schemaName)\n            Assert.assertEquals(\"my_tbl\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun typeConstructor() {\n        var sql = \"select date '20220-02-13' as demo\"\n        SparkSqlHelper.parseStatement(sql)\n\n        sql = \"select timestamp '20220-02-13' as demo\"\n        SparkSqlHelper.parseStatement(sql)\n\n        sql = \"select time '20220-02-13' as demo\"\n        SparkSqlHelper.parseStatement(sql)\n    }\n\n    @Test\n    fun createIndexTest() {\n        val sql = \"CREATE INDEX test_index ON demo.orders (column_name)\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(TableId(\"demo\", \"orders\"), statement.tableId)\n            val createIndex = statement.firstAction() as CreateIndex\n            Assert.assertEquals(\"test_index\", createIndex.indexName)\n        }\n    }\n\n    @Test\n    fun dropIndexTest() {\n        val sql = \"DROP INDEX test_index ON demo.orders\"\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)\n\n        if (statement is AlterTable) {\n            Assert.assertEquals(TableId(\"demo\", \"orders\"), statement.tableId)\n            val dropIndex = statement.firstAction() as DropIndex\n            Assert.assertEquals(\"test_index\", dropIndex.indexName)\n        }\n    }\n\n    @Test\n    fun createFileViewTest() {\n        val sql =\n            \"\"\"\n            create view tdl_spark_test using csv File '/user/dataworks/users/qianxiao/demo.csv' Options( delimiter=',',header='true')\n            COMPRESSION gz;\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        Assert.assertEquals(StatementType.CREATE_FILE_VIEW, statement.statementType)\n\n        if (statement is CreateFileView) {\n            Assert.assertEquals(\"tdl_spark_test\", statement.tableId.tableName)\n            Assert.assertEquals(\"/user/dataworks/users/qianxiao/demo.csv\", statement.path)\n            Assert.assertEquals(\"csv\", statement.fileFormat)\n            Assert.assertEquals(\"gz\", statement.compression)\n        }\n    }\n\n    @Test\n    fun tvfTest() {\n        val sql =\n            \"\"\"\n            SELECT * FROM range(6 + cos(3));\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n\n        if (statement is QueryStmt) {\n            Assert.assertEquals(0, statement.inputTables.size)\n        }\n    }\n\n    @Test\n    fun cacheTest() {\n        val sql =\n            \"\"\"\n            cache lazy table fire_service_calls_tbl_cache OPTIONS ('storageLevel' 'DISK_ONLY') as \n            select * from (select * from demo.db.fire_service_calls_tbl) a\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is CacheTable) {\n            Assert.assertEquals(\"fire_service_calls_tbl_cache\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.options.size)\n            Assert.assertEquals(1, statement.queryStmt?.inputTables?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun uncacheTest() {\n        val sql =\n            \"\"\"\n            uncache table fire_service_calls_tbl_cache;\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is UnCacheTable) {\n            Assert.assertEquals(\"fire_service_calls_tbl_cache\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun resourceManagerTest() {\n        val sql =\n            \"\"\"\n            ADD ARCHIVE /tmp/test.tar.gz;\n            ADD ARCHIVE \"/path/to/some.zip\";\n            ADD ARCHIVE '/some/other.tgz';\n            ADD ARCHIVE \"/path with space/abc.tar\";\n            ADD ARCHIVES \"/path with space/def.tgz\" '/path with space/ghi.zip';\n            \n            LIST JAR;\n            LIST JAR /tmp/test.jar /some/random.jar /another/random.jar;\n        \"\"\"\n                .trimIndent()\n\n        val statements = SparkSqlHelper.parseMultiStatement(sql)\n        Assert.assertEquals(7, statements.size)\n        val addResource = statements.get(4) as AddResourceStatement\n        Assert.assertEquals(2, addResource.fileNames.size)\n\n        val listResource = statements.get(6) as ListResourceStatement\n        Assert.assertEquals(3, listResource.fileNames.size)\n    }\n\n    @Test\n    fun insertOverwriteDirTest() {\n        val sql =\n            \"\"\"\n            with test as (\n                select a, b from aaa\n            )\n            insert overwrite directory 'hdfs://xxx' row format delimited fields terminated by '\\t'\n            select a, b from test\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(\"hdfs://xxx\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun loadDataTest() {\n        val sql =\n            \"\"\"\n            load data inpath 'hdfs:///user/xxx.txt' into table aaa.bbb partition(ds='2024-02-27');\n        \"\"\"\n                .trimIndent()\n\n        val statement = SparkSqlHelper.parseStatement(sql)\n        if (statement is LoadData) {\n            Assert.assertEquals(\"hdfs:///user/xxx.txt\", statement.inPath)\n            Assert.assertEquals(\"aaa.bbb\", statement.tableId.getFullTableName())\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun distCpTest() {\n        val sql =\n            \"\"\"\n            SET SPARK.HADOOP.FS.OSS.ENDPOINT = OSS-CN-HANGZHOU.ALIYUNCS.COM;\n            set spark.hadoop.fs.oss.accessKeyId = xxx;\n            set spark.hadoop.fs.oss.accessKeySecret = xxxx;\n            set spark.hadoop.fs.oss.attempts.maximum = 3;\n            set spark.hadoop.fs.oss.connection.timeout = 10000;\n            set spark.hadoop.fs.oss.connection.establish.timeout = 10000;\n            set spark.hadoop.fs.oss.impl = org.apache.hadoop.fs.aliyun.oss.AliyunOSSFileSystem;\n            set spark.hadoop.fs.sftp.host = \"172.24.5.213\"\n            set spark.hadoop.fs.sftp.host.port = 22\n            set spark.hadoop.fs.sftp.user.172.24.5.213 = root\n            set \"spark.hadoop.fs.sftp.password.172.24.5.213.root\" = 123caoqwe\n            DISTCP OPTIONS (\n              srcPaths = ['oss://melin1204/users'],\n              destPath = \"hdfs://cdh1:8020/temp\",\n              overwrite = true\n            )\n        \"\"\"\n                .trimIndent()\n\n        val statements = SparkSqlHelper.parseMultiStatement(sql)\n        Assert.assertEquals(12, statements.size)\n    }\n\n    @Test\n    fun querySqlTest0() {\n        val sql1 = FileUtils.readFileToString(File(\"./src/test/resources/demo.sql\"), \"UTF-8\")\n        val statement = SparkSqlHelper.parseStatement(sql1)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(10, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(TableId(\"DWB\", \"DWB_FOREX_TRADE_A_D\"), statement.outputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-spark-parser/src/test/kotlin/io/github/melin/superior/parser/spark/SparkStreamSqlParserTest.kt",
    "content": "package io.github.melin.superior.parser.spark\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.common.SetStatement\nimport io.github.melin.superior.common.relational.create.CreateTable\nimport io.github.melin.superior.common.relational.dml.InsertTable\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2018/3/15. */\nclass SparkStreamSqlParserTest {\n\n    @Test\n    fun createTableTest() {\n        val sql =\n            \"CREATE Stream TABLE student_scores (\\n\" +\n                \"  student_number string comment '学号', \\n\" +\n                \"  student_name string comment '姓名', \\n\" +\n                \"  subject string comment '学科',\\n\" +\n                \"  score '/data/score' INT comment '成绩' \\n\" +\n                \")\\n\" +\n                \"WITH (\\n\" +\n                \"  type = \\\"dis\\\",\\n\" +\n                \"  format = \\\"json\\\",\\n\" +\n                \"  kafka.group.id = \\\"cn-north-1\\\"\\n\" +\n                \")\"\n\n        val statement = SparkStreamSqlHelper.parseStatement(sql).get(0)\n\n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"student_scores\", statement.tableId.tableName)\n            Assert.assertEquals(\"cn-north-1\", statement.properties?.get(\"kafka.group.id\"))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest4() {\n        val sql =\n            \"\"\"\n            CREATE Stream TABLE orders (\n                userid string,\n                money bigint\n            )\n            WITH (\n                type = 'kafka',\n                topic = 'flink-topic-input',\n                encode = 'json',\n                kafka.bootstrap.servers = 'localhost:9092',\n                kafka.group.id = 'flink-group'\n            );\n            \n            insert into stat_orders SELECT userid, SUM(money) as total_money FROM orders\n            GROUP BY TUMBLE(proctime, INTERVAL '10' SECOND), userid;\n            \n            set spark.test = 'hello world';\n            set spark.test = setsd,sd,resr;\n            set spark.test = hello world;\n            set spark.test = hello-world;\n            set spark.test = hello $\\{usename} test;\n            #set spark.test = hello comment;\n            set spark.test = hello 'test' world;\n            set spark.test = hello \"test\" world;\n            set spark.test = hdfs://user/hive;\n            set spark.test = 12,12;\n            set spark.test = 3.45;\n            set spark.test = ibdex.json;\n            set spark.test = dw.eset_sdfe_sd;\n            set spark.test = demo.test;\n            set spark.test = dsd(id)%=2;\n            \"\"\"\n\n        val statementDatas = SparkStreamSqlHelper.parseStatement(sql)\n        Assert.assertEquals(16, statementDatas.size)\n        val statement = statementDatas.get(0)\n        if (statement is CreateTable) {\n            Assert.assertEquals(\"orders\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest5() {\n        val sql =\n            \"CREATE Stream TABLE tdl_hudi_stream_json_dt\\n\" +\n                \"    WITH (\\n\" +\n                \"    type = 'hudi',\\n\" +\n                \"    databaseName = \\\"bigdata\\\",\\n\" +\n                \"    tableName = \\\"hudi_stream_json_dt\\\"\" +\n                \"    )\"\n\n        val statement = SparkStreamSqlHelper.parseStatement(sql).get(0)\n\n        if (statement is CreateTable) {\n            Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"tdl_hudi_stream_json_dt\", statement.tableId.tableName)\n            Assert.assertEquals(\"hudi\", statement.properties?.get(\"type\"))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setConfigTest() {\n        val sql = \"set spark.test = false\"\n\n        val statement = SparkStreamSqlHelper.parseStatement(sql).get(0)\n\n        if (statement is SetStatement) {\n            Assert.assertEquals(StatementType.SET, statement.statementType)\n            Assert.assertEquals(\"spark.test\", statement.key)\n            Assert.assertEquals(\"false\", statement.value)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setConfigTest1() {\n        val sql = \"set spark.test = 'hello world'\"\n\n        val statement = SparkStreamSqlHelper.parseStatement(sql).get(0)\n\n        if (statement is SetStatement) {\n            Assert.assertEquals(StatementType.SET, statement.statementType)\n            Assert.assertEquals(\"spark.test\", statement.key)\n            Assert.assertEquals(\"hello world\", statement.value)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setConfigTest2() {\n        val sql = \"set spark.test = 12 \"\n\n        val statement = SparkStreamSqlHelper.parseStatement(sql).get(0)\n\n        if (statement is SetStatement) {\n            Assert.assertEquals(StatementType.SET, statement.statementType)\n            Assert.assertEquals(\"spark.test\", statement.key)\n            Assert.assertEquals(\"12\", statement.value)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun setConfigTest3() {\n        val sql = \"set spark.test = 'demo' \"\n\n        val statement = SparkStreamSqlHelper.parseStatement(sql).get(0)\n\n        if (statement is SetStatement) {\n            Assert.assertEquals(StatementType.SET, statement.statementType)\n            Assert.assertEquals(\"spark.test\", statement.key)\n            Assert.assertEquals(\"demo\", statement.value)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertSqlTest() {\n        val sql = \"insert into bigdata.test_result1 select * from users\"\n\n        val statement = SparkStreamSqlHelper.parseStatement(sql).get(0)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"test_result1\", statement.tableId?.tableName)\n            Assert.assertEquals(\"select * from users\", statement.queryStmt.getSql())\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertUDTFSqlTest() {\n        val sql =\n            \"insert into stat_orders_kafka\\n\" +\n                \"SELECT \\n\" +\n                \"    TUMBLE_START(proctime, INTERVAL '10' SECOND),\\n\" +\n                \"    TUMBLE_END(proctime, INTERVAL '10' SECOND),\\n\" +\n                \"    userid, \\n\" +\n                \"    SUM(money) as total_money \\n\" +\n                \"FROM (select userid, money, proctime from orders LEFT JOIN LATERAL TABLE(demoFunc(a)) as T(newuserid) ON TRUE) a\\n\" +\n                \"GROUP BY TUMBLE(proctime, INTERVAL '10' SECOND), userid;\"\n\n        val statement = SparkStreamSqlHelper.parseStatement(sql).get(0)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"stat_orders_kafka\", statement.tableId?.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-spark-parser/src/test/resources/demo.sql",
    "content": "WITH TMP_BS_FOREX_ORDER AS (\n    SELECT ORDER_ID,\n           ATTR,\n           SOURCE,\n           DATA_FLAG\n    FROM (\n             SELECT ID AS ORDER_ID, ATTR, SOURCE, 'TBNZ' AS DATA_FLAG\n             FROM ODS.ALPHA_ONLINE_ORDERS A\n             WHERE SEC_TYPE = 'FOREX'\n             UNION ALL\n             SELECT ID AS ORDER_ID, ATTR, SOURCE, 'TBSG' AS DATA_FLAG\n             FROM ODS.SG_ALPHA_ONLINE_ORDERS A\n             WHERE SEC_TYPE = 'FOREX'\n             UNION ALL\n             SELECT ID AS ORDER_ID, ATTR, SOURCE, 'TBAU' AS DATA_FLAG\n             FROM ODS.AU_ALPHA_ONLINE_ORDERS A\n             WHERE SEC_TYPE = 'FOREX'\n             UNION ALL\n             SELECT ID AS ORDER_ID, ATTR, SOURCE, 'TFNZ' AS DATA_FLAG\n             FROM ODS.TFNZ_ALPHA_ONLINE_ORDERS A\n             WHERE SEC_TYPE = 'FOREX'\n         ) A\n    GROUP BY ORDER_ID, ATTR, SOURCE, DATA_FLAG\n)\n, TMP_BS_FOREX_COUPON_ORDER AS (\nSELECT ORDER_ID,\n       DATA_FLAG\nFROM (\n         SELECT ORDER_ID, 'TBNZ' AS DATA_FLAG\n         FROM ODS.ALPHA_ONLINE_COUPON_ORDERS A\n                  INNER JOIN ODS.ALPHA_ONLINE_ORDERS B ON A.ORDER_ID = B.ID\n         WHERE B.SEC_TYPE = 'FOREX'\n\n         UNION ALL\n\n         SELECT ORDER_ID, 'TBSG' AS DATA_FLAG\n         FROM ODS.SG_ALPHA_ONLINE_COUPON_ORDERS A\n                  INNER JOIN ODS.SG_ALPHA_ONLINE_ORDERS B ON A.ORDER_ID = B.ID\n         WHERE B.SEC_TYPE = 'FOREX'\n\n         UNION ALL\n\n         SELECT ORDER_ID, 'TBAU' AS DATA_FLAG\n         FROM ODS.AU_ALPHA_ONLINE_COUPON_ORDERS A\n                  INNER JOIN ODS.AU_ALPHA_ONLINE_ORDERS B ON A.ORDER_ID = B.ID\n         WHERE B.SEC_TYPE = 'FOREX'\n\n         UNION ALL\n\n         SELECT ORDER_ID, 'TFNZ' AS DATA_FLAG\n         FROM ODS.TFNZ_ALPHA_ONLINE_COUPON_ORDERS A\n                  INNER JOIN ODS.TFNZ_ALPHA_ONLINE_ORDERS B ON A.ORDER_ID = B.ID\n         WHERE B.SEC_TYPE = 'FOREX'\n     ) A\nGROUP BY ORDER_ID, DATA_FLAG\n)\n, RESULT AS (\n        SELECT\n            A.PID\n             , A.EXECUTING_BROKER\n             , A.CLEARING_BROKER\n             , A.REF_TYPE AS BEHAVIOR_TYPE\n             , A.TRADE_DATE AS BEHAVIOR_DATE    -- 当地时间\n             , A.TRANSACT_TIME AS BEHAVIOR_TIME -- 北京时间\n             , A.TRADE_ID\n             , CAST (A.ORDER_ID AS STRING) AS ORDER_ID\n             , B.SOURCE AS TRADE_ORDER_SOURCE\n             , A.IS_AUTO_EXCHANGE\n             , CASE WHEN CAST (B.ATTR AS BIGINT) & CAST (POW(2, 18) AS BIGINT)= CAST (POW(2, 18) AS BIGINT) THEN 1 ELSE 0 END AS IS_TRADE_GREY_MARKET\n       , CASE WHEN C.ORDER_ID IS NOT NULL THEN 1 ELSE 0 END AS IS_COUPON_USED\n            , CAST (A.ACCOUNT_ID AS STRING) AS ACCOUNT_ID\n            , CAST (A.STOCK_ID AS STRING) AS STOCK_ID\n            , A.`SYMBOL`\n            , A.SEC_TYPE\n            , A.MARKET\n            , A.`EXCHANGE`\n            , A.SIDE AS ACTION\n            , A.CURRENCY\n            , A.AVG_COST AS AVG_PRICE\n            , A.DECIMAL_QTY AS QTY\n            , A.MULTIPLIER\n            , A.AMOUNT\n            , A.FOREX_INCOME AS COMMISSION\n            , A.FOREX_COST AS EXPENSE\n            , A.FOREX_INCOME-NVL(A.FOREX_COST, 0) AS NET\n            , A.CURRENCY AS COMMISSION_CURRENCY\n            , A.DATA_FLAG\n            , A.CREATED_AT\n            , A.UPDATED_AT\n    FROM DWD.DWD_BS_FOREX_TRADE_DETAIL_A_D A\n        LEFT JOIN TMP_BS_FOREX_ORDER B\n    ON A.ORDER_ID=B.ORDER_ID AND A.DATA_FLAG=B.DATA_FLAG\n        LEFT JOIN TMP_BS_FOREX_COUPON_ORDER C ON A.ORDER_ID= C.ORDER_ID AND A.DATA_FLAG= C.DATA_FLAG\n\n    UNION ALL\n    SELECT\n        PID\n         , 'IB' AS EXECUTING_BROKER\n         , 'IB' AS CLEARING_BROKER\n         , A.BEHAVIOR_TYPE\n         , A.BEHAVIOR_DATE                                                                                                           -- 当地日期\n         , CAST (FROM_UTC_TIMESTAMP(TO_UTC_TIMESTAMP(A.TRADE_TIME, 'AMERICA/NEW_YORK'), 'ASIA/SHANGHAI') AS STRING) AS BEHAVIOR_TIME -- 美东转北京地时间\n         , A.TRADE_ID\n         , A.ORDER_ID\n         , A.TRADE_ORDER_SOURCE\n         , 0 AS IS_AUTO_EXCHANGE\n         , NULL AS IS_TRADE_GREY_MARKET\n         , NULL AS IS_COUPON_USED\n         , A.ACCOUNT AS ACCOUNT_ID\n         , NULL AS STOCK_ID\n         , A.`SYMBOL`\n         , A.SEC_TYPE\n         , A.MARKET\n         , A.`EXCHANGE`\n         , A.ACTION\n         , A.CURRENCY\n         , A.AVG_PRICE\n         , A.QTY\n         , A.MULTIPLIER\n         , A.AMOUNT\n         , A.COMMISSION\n         , A.EXPENSE\n         , A.NET\n         , A.COMMISSION_CURRENCY\n         , CASE WHEN LICENSE='TBNZ' THEN 'IB' WHEN LICENSE='US_IB' THEN 'US_IB' END AS DATA_FLAG\n         , CAST (FROM_UTC_TIMESTAMP(TO_UTC_TIMESTAMP(A.TRADE_TIME, 'AMERICA/NEW_YORK'), 'ASIA/SHANGHAI') AS STRING) AS CREATED_AT\n         , CAST (FROM_UTC_TIMESTAMP(TO_UTC_TIMESTAMP(A.TRADE_TIME, 'AMERICA/NEW_YORK'), 'ASIA/SHANGHAI') AS STRING) AS UPDATED_AT\n    FROM DWD.DWD_IB_TRADE_DETAIL_A_D A\n    WHERE A.SEC_TYPE='CASH'\n)\nINSERT OVERWRITE TABLE DWB.DWB_FOREX_TRADE_A_D\nSELECT * FROM RESULT"
  },
  {
    "path": "superior-spark-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-sqlserver-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-sqlserver-parser</artifactId>\n    <name>superior-sqlserver-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "superior-sqlserver-parser/src/main/antlr4/io/github/melin/superior/parser/sqlserver/antlr4/SqlServerLexer.g4",
    "content": "/*\nT-SQL (Transact-SQL, MSSQL) grammar.\nThe MIT License (MIT).\nCopyright (c) 2017, Mark Adams (madams51703@gmail.com)\nCopyright (c) 2015-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies.\nCopyright (c) 2016, Scott Ure (scott@redstormsoftware.com).\nCopyright (c) 2016, Rui Zhang (ruizhang.ccs@gmail.com).\nCopyright (c) 2016, Marcus Henriksson (kuseman80@gmail.com).\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n*/\n\nlexer grammar SqlServerLexer;\n\n// Basic keywords (from https://msdn.microsoft.com/en-us/library/ms189822.aspx)\n\n\n//Keywords that can exist in ID etc\n//More keywords that can also be used as IDs\nABORT:                                 'ABORT';\nABORT_AFTER_WAIT:                      'ABORT_AFTER_WAIT';\nABSENT:                                'ABSENT';\nABSOLUTE:                              'ABSOLUTE';\nACCELERATED_DATABASE_RECOVERY:         'ACCELERATED_DATABASE_RECOVERY';\nACCENT_SENSITIVITY:                    'ACCENT_SENSITIVITY';\nACCESS:                                'ACCESS';\nACTION:                                'ACTION';\nACTIVATION:                            'ACTIVATION';\nACTIVE:                                'ACTIVE';\nADD:                                   'ADD';\nADDRESS:                               'ADDRESS';\nADMINISTER:                            'ADMINISTER';\nAES:                                   'AES';\nAES_128:                               'AES_128';\nAES_192:                               'AES_192';\nAES_256:                               'AES_256';\nAFFINITY:                              'AFFINITY';\nAFTER:                                 'AFTER';\nAGGREGATE:                             'AGGREGATE';\nALGORITHM:                             'ALGORITHM';\nALL:                                   'ALL';\nALLOWED:                               'ALLOWED';\nALLOW_CONNECTIONS:                     'ALLOW_CONNECTIONS';\nALLOW_ENCRYPTED_VALUE_MODIFICATIONS:   'ALLOW_ENCRYPTED_VALUE_MODIFICATIONS';\nALLOW_MULTIPLE_EVENT_LOSS:             'ALLOW_MULTIPLE_EVENT_LOSS';\nALLOW_PAGE_LOCKS:                      'ALLOW_PAGE_LOCKS';\nALLOW_ROW_LOCKS:                       'ALLOW_ROW_LOCKS';\nALLOW_SINGLE_EVENT_LOSS:               'ALLOW_SINGLE_EVENT_LOSS';\nALLOW_SNAPSHOT_ISOLATION:              'ALLOW_SNAPSHOT_ISOLATION';\nALL_CONSTRAINTS:                       'ALL_CONSTRAINTS';\nALL_ERRORMSGS:                         'ALL_ERRORMSGS';\nALL_INDEXES:                           'ALL_INDEXES';\nALL_LEVELS:                            'ALL_LEVELS';\nALTER:                                 'ALTER';\nALWAYS:                                'ALWAYS';\nAND:                                   'AND';\nANONYMOUS:                             'ANONYMOUS';\nANSI_DEFAULTS:                         'ANSI_DEFAULTS';\nANSI_NULLS:                            'ANSI_NULLS';\nANSI_NULL_DEFAULT:                     'ANSI_NULL_DEFAULT';\nANSI_NULL_DFLT_OFF:                    'ANSI_NULL_DFLT_OFF';\nANSI_NULL_DFLT_ON:                     'ANSI_NULL_DFLT_ON';\nANSI_PADDING:                          'ANSI_PADDING';\nANSI_WARNINGS:                         'ANSI_WARNINGS';\nANY:                                   'ANY';\nAPPEND:                                'APPEND';\nAPPLICATION:                           'APPLICATION';\nAPPLICATION_LOG:                       'APPLICATION_LOG';\nAPPLOCK_MODE:                          'APPLOCK_MODE';\nAPPLOCK_TEST:                          'APPLOCK_TEST';\nAPPLY:                                 'APPLY';\nAPP_NAME:                              'APP_NAME';\nARITHABORT:                            'ARITHABORT';\nARITHIGNORE:                           'ARITHIGNORE';\nAS:                                    'AS';\nASC:                                   'ASC';\nASCII:                                 'ASCII';\nASSEMBLY:                              'ASSEMBLY';\nASSEMBLYPROPERTY:                      'ASSEMBLYPROPERTY';\nASYMMETRIC:                            'ASYMMETRIC';\nASYNCHRONOUS_COMMIT:                   'ASYNCHRONOUS_COMMIT';\nAT_KEYWORD:                            'AT';\nAUDIT:                                 'AUDIT';\nAUDIT_GUID:                            'AUDIT_GUID';\nAUTHENTICATE:                          'AUTHENTICATE';\nAUTHENTICATION:                        'AUTHENTICATION';\nAUTHORIZATION:                         'AUTHORIZATION';\nAUTO:                                  'AUTO';\nAUTOGROW_ALL_FILES:                    'AUTOGROW_ALL_FILES';\nAUTOGROW_SINGLE_FILE:                  'AUTOGROW_SINGLE_FILE';\nAUTOMATED_BACKUP_PREFERENCE:           'AUTOMATED_BACKUP_PREFERENCE';\nAUTOMATIC:                             'AUTOMATIC';\nAUTO_CLEANUP:                          'AUTO_CLEANUP';\nAUTO_CLOSE:                            'AUTO_CLOSE';\nAUTO_CREATE_STATISTICS:                'AUTO_CREATE_STATISTICS';\nAUTO_DROP:                             'AUTO_DROP';\nAUTO_SHRINK:                           'AUTO_SHRINK';\nAUTO_UPDATE_STATISTICS:                'AUTO_UPDATE_STATISTICS';\nAUTO_UPDATE_STATISTICS_ASYNC:          'AUTO_UPDATE_STATISTICS_ASYNC';\nAVAILABILITY:                          'AVAILABILITY';\nAVAILABILITY_MODE:                     'AVAILABILITY_MODE';\nAVG:                                   'AVG';\nBACKSLASH:                             '\\\\';\nBACKUP:                                'BACKUP';\nBACKUP_CLONEDB:                        'BACKUP_CLONEDB';\nBACKUP_PRIORITY:                       'BACKUP_PRIORITY';\nBASE64:                                'BASE64';\nBEFORE:                                'BEFORE';\nBEGIN:                                 'BEGIN';\nBEGIN_DIALOG:                          'BEGIN_DIALOG';\nBETWEEN:                               'BETWEEN';\nBIGINT:                                'BIGINT';\nBINARY_CHECKSUM:                       'BINARY_CHECKSUM';\nBINARY_KEYWORD:                        'BINARY';\nBINDING:                               'BINDING';\nBLOB_STORAGE:                          'BLOB_STORAGE';\nBLOCK:                                 'BLOCK';\nBLOCKERS:                              'BLOCKERS';\nBLOCKING_HIERARCHY:                    'BLOCKING_HIERARCHY';\nBLOCKSIZE:                             'BLOCKSIZE';\nBREAK:                                 'BREAK';\nBROKER:                                'BROKER';\nBROKER_INSTANCE:                       'BROKER_INSTANCE';\nBROWSE:                                'BROWSE';\nBUFFER:                                'BUFFER';\nBUFFERCOUNT:                           'BUFFERCOUNT';\nBULK:                                  'BULK';\nBULK_LOGGED:                           'BULK_LOGGED';\nBY:                                    'BY';\nCACHE:                                 'CACHE';\nCALLED:                                'CALLED';\nCALLER:                                'CALLER';\nCAP_CPU_PERCENT:                       'CAP_CPU_PERCENT';\nCASCADE:                               'CASCADE';\nCASE:                                  'CASE';\nCAST:                                  'CAST';\nCATALOG:                               'CATALOG';\nCATCH:                                 'CATCH';\nCERTENCODED:                           'CERTENCODED';\nCERTIFICATE:                           'CERTIFICATE';\nCERTPRIVATEKEY:                        'CERTPRIVATEKEY';\nCERT_ID:                               'CERT_ID';\nCHANGE:                                'CHANGE';\nCHANGES:                               'CHANGES';\nCHANGETABLE:                           'CHANGETABLE';\nCHANGE_RETENTION:                      'CHANGE_RETENTION';\nCHANGE_TRACKING:                       'CHANGE_TRACKING';\nCHAR:                                  'CHAR';\nCHARINDEX:                             'CHARINDEX';\nCHECK:                                 'CHECK';\nCHECKALLOC:                            'CHECKALLOC';\nCHECKCATALOG:                          'CHECKCATALOG';\nCHECKCONSTRAINTS:                      'CHECKCONSTRAINTS';\nCHECKDB:                               'CHECKDB';\nCHECKFILEGROUP:                        'CHECKFILEGROUP';\nCHECKPOINT:                            'CHECKPOINT';\nCHECKSUM:                              'CHECKSUM';\nCHECKSUM_AGG:                          'CHECKSUM_AGG';\nCHECKTABLE:                            'CHECKTABLE';\nCHECK_EXPIRATION:                      'CHECK_EXPIRATION';\nCHECK_POLICY:                          'CHECK_POLICY';\nCLASSIFIER_FUNCTION:                   'CLASSIFIER_FUNCTION';\nCLEANTABLE:                            'CLEANTABLE';\nCLEANUP:                               'CLEANUP';\nCLONEDATABASE:                         'CLONEDATABASE';\nCLOSE:                                 'CLOSE';\nCLUSTER:                               'CLUSTER';\nCLUSTERED:                             'CLUSTERED';\nCOALESCE:                              'COALESCE';\nCOLLATE:                               'COLLATE';\nCOLLECTION:                            'COLLECTION';\nCOLUMN:                                'COLUMN';\nCOLUMNPROPERTY:                        'COLUMNPROPERTY';\nCOLUMNS:                               'COLUMNS';\nCOLUMNSTORE:                           'COLUMNSTORE';\nCOLUMNSTORE_ARCHIVE:                   'COLUMNSTORE_ARCHIVE';\nCOLUMN_ENCRYPTION_KEY:                 'COLUMN_ENCRYPTION_KEY';\nCOLUMN_MASTER_KEY:                     'COLUMN_MASTER_KEY';\nCOL_LENGTH:                            'COL_LENGTH';\nCOL_NAME:                              'COL_NAME';\nCOMMIT:                                'COMMIT';\nCOMMITTED:                             'COMMITTED';\nCOMPATIBILITY_LEVEL:                   'COMPATIBILITY_LEVEL';\nCOMPRESS:                              'COMPRESS';\nCOMPRESSION:                           'COMPRESSION';\nCOMPRESSION_DELAY:                     'COMPRESSION_DELAY';\nCOMPRESS_ALL_ROW_GROUPS:               'COMPRESS_ALL_ROW_GROUPS';\nCOMPUTE:                               'COMPUTE';\nCONCAT:                                'CONCAT';\nCONCAT_NULL_YIELDS_NULL:               'CONCAT_NULL_YIELDS_NULL';\nCONCAT_WS:                             'CONCAT_WS';\nCONFIGURATION:                         'CONFIGURATION';\nCONNECT:                               'CONNECT';\nCONNECTION:                            'CONNECTION';\nCONNECTIONPROPERTY:                    'CONNECTIONPROPERTY';\nCONSTRAINT:                            'CONSTRAINT';\nCONTAINMENT:                           'CONTAINMENT';\nCONTAINS:                              'CONTAINS';\nCONTAINSTABLE:                         'CONTAINSTABLE';\nCONTENT:                               'CONTENT';\nCONTEXT:                               'CONTEXT';\nCONTEXT_INFO:                          'CONTEXT_INFO';\nCONTINUE:                              'CONTINUE';\nCONTINUE_AFTER_ERROR:                  'CONTINUE_AFTER_ERROR';\nCONTRACT:                              'CONTRACT';\nCONTRACT_NAME:                         'CONTRACT_NAME';\nCONTROL:                               'CONTROL';\nCONVERSATION:                          'CONVERSATION';\nCONVERT:                               'TRY_'? 'CONVERT';\nCOOKIE:                                'COOKIE';\nCOPY_ONLY:                             'COPY_ONLY';\nCOUNT:                                 'COUNT';\nCOUNTER:                               'COUNTER';\nCOUNT_BIG:                             'COUNT_BIG';\nCPU:                                   'CPU';\nCREATE:                                'CREATE';\nCREATE_NEW:                            'CREATE_NEW';\nCREATION_DISPOSITION:                  'CREATION_DISPOSITION';\nCREDENTIAL:                            'CREDENTIAL';\nCROSS:                                 'CROSS';\nCRYPTOGRAPHIC:                         'CRYPTOGRAPHIC';\nCUME_DIST:                             'CUME_DIST';\nCURRENT:                               'CURRENT';\nCURRENT_DATE:                          'CURRENT_DATE';\nCURRENT_REQUEST_ID:                    'CURRENT_REQUEST_ID';\nCURRENT_TIME:                          'CURRENT_TIME';\nCURRENT_TIMESTAMP:                     'CURRENT_TIMESTAMP';\nCURRENT_TRANSACTION_ID:                'CURRENT_TRANSACTION_ID';\nCURRENT_USER:                          'CURRENT_USER';\nCURSOR:                                'CURSOR';\nCURSOR_CLOSE_ON_COMMIT:                'CURSOR_CLOSE_ON_COMMIT';\nCURSOR_DEFAULT:                        'CURSOR_DEFAULT';\nCURSOR_STATUS:                         'CURSOR_STATUS';\nCYCLE:                                 'CYCLE';\nDATA:                                  'DATA';\nDATABASE:                              'DATABASE';\nDATABASEPROPERTYEX:                    'DATABASEPROPERTYEX';\nDATABASE_MIRRORING:                    'DATABASE_MIRRORING';\nDATABASE_PRINCIPAL_ID:                 'DATABASE_PRINCIPAL_ID';\nDATALENGTH:                            'DATALENGTH';\nDATASPACE:                             'DATASPACE';\nDATA_COMPRESSION:                      'DATA_COMPRESSION';\nDATA_PURITY:                           'DATA_PURITY';\nDATA_SOURCE:                           'DATA_SOURCE';\nDATEADD:                               'DATEADD';\nDATEDIFF:                              'DATEDIFF';\nDATENAME:                              'DATENAME';\nDATEPART:                              'DATEPART';\nDATE_CORRELATION_OPTIMIZATION:         'DATE_CORRELATION_OPTIMIZATION';\nDAYS:                                  'DAYS';\nDBCC:                                  'DBCC';\nDBREINDEX:                             'DBREINDEX';\nDB_CHAINING:                           'DB_CHAINING';\nDB_FAILOVER:                           'DB_FAILOVER';\nDB_ID:                                 'DB_ID';\nDB_NAME:                               'DB_NAME';\nDDL:                                   'DDL';\nDEALLOCATE:                            'DEALLOCATE';\nDECLARE:                               'DECLARE';\nDECOMPRESS:                            'DECOMPRESS';\nDECRYPTION:                            'DECRYPTION';\nDEFAULT:                               'DEFAULT';\nDEFAULT_DATABASE:                      'DEFAULT_DATABASE';\nDEFAULT_DOUBLE_QUOTE:                  [\"]'DEFAULT'[\"];\nDEFAULT_FULLTEXT_LANGUAGE:             'DEFAULT_FULLTEXT_LANGUAGE';\nDEFAULT_LANGUAGE:                      'DEFAULT_LANGUAGE';\nDEFAULT_SCHEMA:                        'DEFAULT_SCHEMA';\nDEFINITION:                            'DEFINITION';\nDELAY:                                 'DELAY';\nDELAYED_DURABILITY:                    'DELAYED_DURABILITY';\nDELETE:                                'DELETE';\nDELETED:                               'DELETED';\nDENSE_RANK:                            'DENSE_RANK';\nDENY:                                  'DENY';\nDEPENDENTS:                            'DEPENDENTS';\nDES:                                   'DES';\nDESC:                                  'DESC';\nDESCRIPTION:                           'DESCRIPTION';\nDESX:                                  'DESX';\nDETERMINISTIC:                         'DETERMINISTIC';\nDHCP:                                  'DHCP';\nDIAGNOSTICS:                           'DIAGNOSTICS';\nDIALOG:                                'DIALOG';\nDIFFERENCE:                            'DIFFERENCE';\nDIFFERENTIAL:                          'DIFFERENTIAL';\nDIRECTORY_NAME:                        'DIRECTORY_NAME';\nDISABLE:                               'DISABLE';\nDISABLED:                              'DISABLED';\nDISABLE_BROKER:                        'DISABLE_BROKER';\nDISK:                                  'DISK';\nDISTINCT:                              'DISTINCT';\nDISTRIBUTED:                           'DISTRIBUTED';\nDISTRIBUTION:                          'DISTRIBUTION';\nDOCUMENT:                              'DOCUMENT';\nDOLLAR_PARTITION:                      '$PARTITION';\nDOUBLE:                                'DOUBLE';\nDOUBLE_BACK_SLASH:                     '\\\\\\\\';\nDOUBLE_FORWARD_SLASH:                  '//';\nDROP:                                  'DROP';\nDROPCLEANBUFFERS:                      'DROPCLEANBUFFERS';\nDROP_EXISTING:                         'DROP_EXISTING';\nDTC_SUPPORT:                           'DTC_SUPPORT';\nDUMP:                                  'DUMP';\nDYNAMIC:                               'DYNAMIC';\nELEMENTS:                              'ELEMENTS';\nELSE:                                  'ELSE';\nEMERGENCY:                             'EMERGENCY';\nEMPTY:                                 'EMPTY';\nENABLE:                                'ENABLE';\nENABLED:                               'ENABLED';\nENABLE_BROKER:                         'ENABLE_BROKER';\nENCRYPTED:                             'ENCRYPTED';\nENCRYPTED_VALUE:                       'ENCRYPTED_VALUE';\nENCRYPTION:                            'ENCRYPTION';\nENCRYPTION_TYPE:                       'ENCRYPTION_TYPE';\nEND:                                   'END';\nENDPOINT:                              'ENDPOINT';\nENDPOINT_URL:                          'ENDPOINT_URL';\nERRLVL:                                'ERRLVL';\nERROR:                                 'ERROR';\nERROR_BROKER_CONVERSATIONS:            'ERROR_BROKER_CONVERSATIONS';\nERROR_LINE:                            'ERROR_LINE';\nERROR_MESSAGE:                         'ERROR_MESSAGE';\nERROR_NUMBER:                          'ERROR_NUMBER';\nERROR_PROCEDURE:                       'ERROR_PROCEDURE';\nERROR_SEVERITY:                        'ERROR_SEVERITY';\nERROR_STATE:                           'ERROR_STATE';\nESCAPE:                                'ESCAPE';\nESTIMATEONLY:                          'ESTIMATEONLY';\nEVENT:                                 'EVENT';\nEVENTDATA:                             'EVENTDATA';\nEVENT_RETENTION_MODE:                  'EVENT_RETENTION_MODE';\nEXCEPT:                                'EXCEPT';\nEXCLUSIVE:                             'EXCLUSIVE';\nEXECUTABLE:                            'EXECUTABLE';\nEXECUTABLE_FILE:                       'EXECUTABLE_FILE';\nEXECUTE:                               'EXEC' 'UTE'?;\nEXIST:                                 'EXIST';\nEXISTS:                                'EXISTS';\nEXIST_SQUARE_BRACKET:                  '[EXIST]';\nEXIT:                                  'EXIT';\nEXPAND:                                'EXPAND';\nEXPIREDATE:                            'EXPIREDATE';\nEXPIRY_DATE:                           'EXPIRY_DATE';\nEXPLICIT:                              'EXPLICIT';\nEXTENDED_LOGICAL_CHECKS:               'EXTENDED_LOGICAL_CHECKS';\nEXTENSION:                             'EXTENSION';\nEXTERNAL:                              'EXTERNAL';\nEXTERNAL_ACCESS:                       'EXTERNAL_ACCESS';\nFAILOVER:                              'FAILOVER';\nFAILOVER_MODE:                         'FAILOVER_MODE';\nFAILURE:                               'FAILURE';\nFAILURECONDITIONLEVEL:                 'FAILURECONDITIONLEVEL';\nFAILURE_CONDITION_LEVEL:               'FAILURE_CONDITION_LEVEL';\nFAIL_OPERATION:                        'FAIL_OPERATION';\nFAN_IN:                                'FAN_IN';\nFAST:                                  'FAST';\nFAST_FORWARD:                          'FAST_FORWARD';\nFETCH:                                 'FETCH';\nFILE:                                  'FILE';\nFILEGROUP:                             'FILEGROUP';\nFILEGROUPPROPERTY:                     'FILEGROUPPROPERTY';\nFILEGROUP_ID:                          'FILEGROUP_ID';\nFILEGROUP_NAME:                        'FILEGROUP_NAME';\nFILEGROWTH:                            'FILEGROWTH';\nFILENAME:                              'FILENAME';\nFILEPATH:                              'FILEPATH';\nFILEPROPERTY:                          'FILEPROPERTY';\nFILEPROPERTYEX:                        'FILEPROPERTYEX';\nFILESTREAM:                            'FILESTREAM';\nFILESTREAM_ON:                         'FILESTREAM_ON';\nFILE_ID:                               'FILE_ID';\nFILE_IDEX:                             'FILE_IDEX';\nFILE_NAME:                             'FILE_NAME';\nFILE_SNAPSHOT:                         'FILE_SNAPSHOT';\nFILLFACTOR:                            'FILLFACTOR';\nFILTER:                                'FILTER';\nFIRST:                                 'FIRST';\nFIRST_VALUE:                           'FIRST_VALUE';\nFMTONLY:                               'FMTONLY';\nFOLLOWING:                             'FOLLOWING';\nFOR:                                   'FOR';\nFORCE:                                 'FORCE';\nFORCED:                                'FORCED';\nFORCEPLAN:                             'FORCEPLAN';\nFORCESCAN:                             'FORCESCAN';\nFORCESEEK:                             'FORCESEEK';\nFORCE_FAILOVER_ALLOW_DATA_LOSS:        'FORCE_FAILOVER_ALLOW_DATA_LOSS';\nFORCE_SERVICE_ALLOW_DATA_LOSS:         'FORCE_SERVICE_ALLOW_DATA_LOSS';\nFOREIGN:                               'FOREIGN';\nFORMAT:                                'FORMAT';\nFORMATMESSAGE:                         'FORMATMESSAGE';\nFORWARD_ONLY:                          'FORWARD_ONLY';\nFREE:                                  'FREE';\nFREETEXT:                              'FREETEXT';\nFREETEXTTABLE:                         'FREETEXTTABLE';\nFROM:                                  'FROM';\nFULL:                                  'FULL';\nFULLSCAN:                              'FULLSCAN';\nFULLTEXT:                              'FULLTEXT';\nFULLTEXTCATALOGPROPERTY:               'FULLTEXTCATALOGPROPERTY';\nFULLTEXTSERVICEPROPERTY:               'FULLTEXTSERVICEPROPERTY';\nFUNCTION:                              'FUNCTION';\nGB:                                    'GB';\nGENERATED:                             'GENERATED';\nGET:                                   'GET';\nGETANCESTOR:                           'GETANCESTOR';\nGETANSINULL:                           'GETANSINULL';\nGETDATE:                               'GETDATE';\nGETDESCENDANT:                         'GETDESCENDANT';\nGETLEVEL:                              'GETLEVEL';\nGETREPARENTEDVALUE:                    'GETREPARENTEDVALUE';\nGETROOT:                               'GETROOT';\nGETUTCDATE:                            'GETUTCDATE';\nGET_FILESTREAM_TRANSACTION_CONTEXT:    'GET_FILESTREAM_TRANSACTION_CONTEXT';\nGLOBAL:                                'GLOBAL';\nGO:                                    'GO';\nGOTO:                                  'GOTO';\nGOVERNOR:                              'GOVERNOR';\nGRANT:                                 'GRANT';\nGREATEST:                              'GREATEST';\nGROUP:                                 'GROUP';\nGROUPING:                              'GROUPING';\nGROUPING_ID:                           'GROUPING_ID';\nGROUP_MAX_REQUESTS:                    'GROUP_MAX_REQUESTS';\nHADR:                                  'HADR';\nHASH:                                  'HASH';\nHASHED:                                'HASHED';\nHAS_DBACCESS:                          'HAS_DBACCESS';\nHAS_PERMS_BY_NAME:                     'HAS_PERMS_BY_NAME';\nHAVING:                                'HAVING';\nHEALTHCHECKTIMEOUT:                    'HEALTHCHECKTIMEOUT';\nHEALTH_CHECK_TIMEOUT:                  'HEALTH_CHECK_TIMEOUT';\nHEAP:                                  'HEAP';\nHIDDEN_KEYWORD:                        'HIDDEN';\nHIERARCHYID:                           'HIERARCHYID';\nHIGH:                                  'HIGH';\nHOLDLOCK:                              'HOLDLOCK';\nHONOR_BROKER_PRIORITY:                 'HONOR_BROKER_PRIORITY';\nHOST_ID:                               'HOST_ID';\nHOST_NAME:                             'HOST_NAME';\nHOURS:                                 'HOURS';\nIDENTITY:                              'IDENTITY';\nIDENTITYCOL:                           'IDENTITYCOL';\nIDENTITY_INSERT:                       'IDENTITY_INSERT';\nIDENTITY_VALUE:                        'IDENTITY_VALUE';\nIDENT_CURRENT:                         'IDENT_CURRENT';\nIDENT_INCR:                            'IDENT_INCR';\nIDENT_SEED:                            'IDENT_SEED';\nIF:                                    'IF';\nIGNORE_CONSTRAINTS:                    'IGNORE_CONSTRAINTS';\nIGNORE_DUP_KEY:                        'IGNORE_DUP_KEY';\nIGNORE_NONCLUSTERED_COLUMNSTORE_INDEX: 'IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX';\nIGNORE_REPLICATED_TABLE_CACHE:         'IGNORE_REPLICATED_TABLE_CACHE';\nIGNORE_TRIGGERS:                       'IGNORE_TRIGGERS';\nIIF:                                   'IIF';\nIMMEDIATE:                             'IMMEDIATE';\nIMPERSONATE:                           'IMPERSONATE';\nIMPLICIT_TRANSACTIONS:                 'IMPLICIT_TRANSACTIONS';\nIMPORTANCE:                            'IMPORTANCE';\nIN:                                    'IN';\nINCLUDE:                               'INCLUDE';\nINCLUDE_NULL_VALUES:                   'INCLUDE_NULL_VALUES';\nINCREMENT:                             'INCREMENT';\nINCREMENTAL:                           'INCREMENTAL';\nINDEX:                                 'INDEX';\nINDEXKEY_PROPERTY:                     'INDEXKEY_PROPERTY';\nINDEXPROPERTY:                         'INDEXPROPERTY';\nINDEX_COL:                             'INDEX_COL';\nINFINITE:                              'INFINITE';\nINIT:                                  'INIT';\nINITIATOR:                             'INITIATOR';\nINNER:                                 'INNER';\nINPUT:                                 'INPUT';\nINSENSITIVE:                           'INSENSITIVE';\nINSERT:                                'INSERT';\nINSERTED:                              'INSERTED';\nINSTEAD:                               'INSTEAD';\nINT:                                   'INT';\nINTERSECT:                             'INTERSECT';\nINTO:                                  'INTO';\nIO:                                    'IO';\nIP:                                    'IP';\nIS:                                    'IS';\nISDESCENDANTOF:                        'ISDESCENDANTOF';\nISJSON:                                'ISJSON';\nISNULL:                                'ISNULL';\nISNUMERIC:                             'ISNUMERIC';\nISOLATION:                             'ISOLATION';\nIS_MEMBER:                             'IS_MEMBER';\nIS_ROLEMEMBER:                         'IS_ROLEMEMBER';\nIS_SRVROLEMEMBER:                      'IS_SRVROLEMEMBER';\nJOB:                                   'JOB';\nJOIN:                                  'JOIN';\nJSON:                                  'JSON';\nJSON_ARRAY:                            'JSON_ARRAY';\nJSON_MODIFY:                           'JSON_MODIFY';\nJSON_OBJECT:                           'JSON_OBJECT';\nJSON_PATH_EXISTS:                      'JSON_PATH_EXISTS';\nJSON_QUERY:                            'JSON_QUERY';\nJSON_VALUE:                            'JSON_VALUE';\nKB:                                    'KB';\nKEEP:                                  'KEEP';\nKEEPDEFAULTS:                          'KEEPDEFAULTS';\nKEEPFIXED:                             'KEEPFIXED';\nKEEPIDENTITY:                          'KEEPIDENTITY';\nKERBEROS:                              'KERBEROS';\nKEY:                                   'KEY';\nKEYS:                                  'KEYS';\nKEYSET:                                'KEYSET';\nKEY_PATH:                              'KEY_PATH';\nKEY_SOURCE:                            'KEY_SOURCE';\nKEY_STORE_PROVIDER_NAME:               'KEY_STORE_PROVIDER_NAME';\nKILL:                                  'KILL';\nLAG:                                   'LAG';\nLANGUAGE:                              'LANGUAGE';\nLAST:                                  'LAST';\nLAST_VALUE:                            'LAST_VALUE';\nLEAD:                                  'LEAD';\nLEAST:                                 'LEAST';\nLEFT:                                  'LEFT';\nLEN:                                   'LEN';\nLEVEL:                                 'LEVEL';\nLIBRARY:                               'LIBRARY';\nLIFETIME:                              'LIFETIME';\nLIKE:                                  'LIKE';\nLINENO:                                'LINENO';\nLINKED:                                'LINKED';\nLINUX:                                 'LINUX';\nLIST:                                  'LIST';\nLISTENER:                              'LISTENER';\nLISTENER_IP:                           'LISTENER_IP';\nLISTENER_PORT:                         'LISTENER_PORT';\nLISTENER_URL:                          'LISTENER_URL';\nLOAD:                                  'LOAD';\nLOB_COMPACTION:                        'LOB_COMPACTION';\nLOCAL:                                 'LOCAL';\nLOCAL_SERVICE_NAME:                    'LOCAL_SERVICE_NAME';\nLOCATION:                              'LOCATION';\nLOCK:                                  'LOCK';\nLOCK_ESCALATION:                       'LOCK_ESCALATION';\nLOG:                                   'LOG';\nLOGIN:                                 'LOGIN';\nLOGINPROPERTY:                         'LOGINPROPERTY';\nLOOP:                                  'LOOP';\nLOW:                                   'LOW';\nLOWER:                                 'LOWER';\nLTRIM:                                 'LTRIM';\nMANUAL:                                'MANUAL';\nMARK:                                  'MARK';\nMASK:                                  'MASK';\nMASKED:                                'MASKED';\nMASTER:                                'MASTER';\nMATCHED:                               'MATCHED';\nMATERIALIZED:                          'MATERIALIZED';\nMAX:                                   'MAX';\nMAXDOP:                                'MAXDOP';\nMAXRECURSION:                          'MAXRECURSION';\nMAXSIZE:                               'MAXSIZE';\nMAXTRANSFER:                           'MAXTRANSFER';\nMAXVALUE:                              'MAXVALUE';\nMAX_CPU_PERCENT:                       'MAX_CPU_PERCENT';\nMAX_DISPATCH_LATENCY:                  'MAX_DISPATCH_LATENCY';\nMAX_DOP:                               'MAX_DOP';\nMAX_DURATION:                          'MAX_DURATION';\nMAX_EVENT_SIZE:                        'MAX_EVENT_SIZE';\nMAX_FILES:                             'MAX_FILES';\nMAX_IOPS_PER_VOLUME:                   'MAX_IOPS_PER_VOLUME';\nMAX_MEMORY:                            'MAX_MEMORY';\nMAX_MEMORY_PERCENT:                    'MAX_MEMORY_PERCENT';\nMAX_OUTSTANDING_IO_PER_VOLUME:         'MAX_OUTSTANDING_IO_PER_VOLUME';\nMAX_PROCESSES:                         'MAX_PROCESSES';\nMAX_QUEUE_READERS:                     'MAX_QUEUE_READERS';\nMAX_ROLLOVER_FILES:                    'MAX_ROLLOVER_FILES';\nMAX_SIZE:                              'MAX_SIZE';\nMB:                                    'MB';\nMEDIADESCRIPTION:                      'MEDIADESCRIPTION';\nMEDIANAME:                             'MEDIANAME';\nMEDIUM:                                'MEDIUM';\nMEMBER:                                'MEMBER';\nMEMORY_OPTIMIZED_DATA:                 'MEMORY_OPTIMIZED_DATA';\nMEMORY_PARTITION_MODE:                 'MEMORY_PARTITION_MODE';\nMERGE:                                 'MERGE';\nMESSAGE:                               'MESSAGE';\nMESSAGE_FORWARDING:                    'MESSAGE_FORWARDING';\nMESSAGE_FORWARD_SIZE:                  'MESSAGE_FORWARD_SIZE';\nMIN:                                   'MIN';\nMINUTES:                               'MINUTES';\nMINVALUE:                              'MINVALUE';\nMIN_ACTIVE_ROWVERSION:                 'MIN_ACTIVE_ROWVERSION';\nMIN_CPU_PERCENT:                       'MIN_CPU_PERCENT';\nMIN_IOPS_PER_VOLUME:                   'MIN_IOPS_PER_VOLUME';\nMIN_MEMORY_PERCENT:                    'MIN_MEMORY_PERCENT';\nMIRROR:                                'MIRROR';\nMIRROR_ADDRESS:                        'MIRROR_ADDRESS';\nMIXED_PAGE_ALLOCATION:                 'MIXED_PAGE_ALLOCATION';\nMODE:                                  'MODE';\nMODIFY:                                'MODIFY';\nMODIFY_SQUARE_BRACKET:                 '[MODIFY]';\nMOVE:                                  'MOVE';\nMULTI_USER:                            'MULTI_USER';\nMUST_CHANGE:                           'MUST_CHANGE';\nNAME:                                  'NAME';\nNATIONAL:                              'NATIONAL';\nNCHAR:                                 'NCHAR';\nNEGOTIATE:                             'NEGOTIATE';\nNESTED_TRIGGERS:                       'NESTED_TRIGGERS';\nNEWID:                                 'NEWID';\nNEWNAME:                               'NEWNAME';\nNEWSEQUENTIALID:                       'NEWSEQUENTIALID';\nNEW_ACCOUNT:                           'NEW_ACCOUNT';\nNEW_BROKER:                            'NEW_BROKER';\nNEW_PASSWORD:                          'NEW_PASSWORD';\nNEXT:                                  'NEXT';\nNO:                                    'NO';\nNOCHECK:                               'NOCHECK';\nNOCOUNT:                               'NOCOUNT';\nNODES:                                 'NODES';\nNOEXEC:                                'NOEXEC';\nNOEXPAND:                              'NOEXPAND';\nNOFORMAT:                              'NOFORMAT';\nNOHOLDLOCK:                            'NOHOLDLOCK';\nNOINDEX:                               'NOINDEX';\nNOINIT:                                'NOINIT';\nNOLOCK:                                'NOLOCK';\nNONCLUSTERED:                          'NONCLUSTERED';\nNONE:                                  'NONE';\nNON_TRANSACTED_ACCESS:                 'NON_TRANSACTED_ACCESS';\nNORECOMPUTE:                           'NORECOMPUTE';\nNORECOVERY:                            'NORECOVERY';\nNOREWIND:                              'NOREWIND';\nNOSKIP:                                'NOSKIP';\nNOT:                                   'NOT';\nNOTIFICATION:                          'NOTIFICATION';\nNOTIFICATIONS:                         'NOTIFICATIONS';\nNOUNLOAD:                              'NOUNLOAD';\nNOWAIT:                                'NOWAIT';\nNO_CHECKSUM:                           'NO_CHECKSUM';\nNO_COMPRESSION:                        'NO_COMPRESSION';\nNO_EVENT_LOSS:                         'NO_EVENT_LOSS';\nNO_INFOMSGS:                           'NO_INFOMSGS';\nNO_QUERYSTORE:                         'NO_QUERYSTORE';\nNO_STATISTICS:                         'NO_STATISTICS';\nNO_TRUNCATE:                           'NO_TRUNCATE';\nNO_WAIT:                               'NO_WAIT';\nNTILE:                                 'NTILE';\nNTLM:                                  'NTLM';\nNULLIF:                                'NULLIF';\nNULL_:                                 'NULL';\nNULL_DOUBLE_QUOTE:                     [\"]'NULL'[\"];\nNUMANODE:                              'NUMANODE';\nNUMBER:                                'NUMBER';\nNUMERIC_ROUNDABORT:                    'NUMERIC_ROUNDABORT';\nOBJECT:                                'OBJECT';\nOBJECTPROPERTY:                        'OBJECTPROPERTY';\nOBJECTPROPERTYEX:                      'OBJECTPROPERTYEX';\nOBJECT_DEFINITION:                     'OBJECT_DEFINITION';\nOBJECT_ID:                             'OBJECT_ID';\nOBJECT_NAME:                           'OBJECT_NAME';\nOBJECT_SCHEMA_NAME:                    'OBJECT_SCHEMA_NAME';\nOF:                                    'OF';\nOFF:                                   'OFF';\nOFFLINE:                               'OFFLINE';\nOFFSET:                                'OFFSET';\nOFFSETS:                               'OFFSETS';\nOLD_ACCOUNT:                           'OLD_ACCOUNT';\nOLD_PASSWORD:                          'OLD_PASSWORD';\nON:                                    'ON';\nONLINE:                                'ONLINE';\nONLY:                                  'ONLY';\nON_FAILURE:                            'ON_FAILURE';\nOPEN:                                  'OPEN';\nOPENDATASOURCE:                        'OPENDATASOURCE';\nOPENJSON:                              'OPENJSON';\nOPENQUERY:                             'OPENQUERY';\nOPENROWSET:                            'OPENROWSET';\nOPENXML:                               'OPENXML';\nOPEN_EXISTING:                         'OPEN_EXISTING';\nOPERATIONS:                            'OPERATIONS';\nOPTIMISTIC:                            'OPTIMISTIC';\nOPTIMIZE:                              'OPTIMIZE';\nOPTIMIZE_FOR_SEQUENTIAL_KEY:           'OPTIMIZE_FOR_SEQUENTIAL_KEY';\nOPTION:                                'OPTION';\nOR:                                    'OR';\nORDER:                                 'ORDER';\nORIGINAL_DB_NAME:                      'ORIGINAL_DB_NAME';\nORIGINAL_LOGIN:                        'ORIGINAL_LOGIN';\nOUT:                                   'OUT';\nOUTER:                                 'OUTER';\nOUTPUT:                                'OUTPUT';\nOVER:                                  'OVER';\nOVERRIDE:                              'OVERRIDE';\nOWNER:                                 'OWNER';\nOWNERSHIP:                             'OWNERSHIP';\nPAD_INDEX:                             'PAD_INDEX';\nPAGE:                                  'PAGE';\nPAGECOUNT:                             'PAGECOUNT';\nPAGE_VERIFY:                           'PAGE_VERIFY';\nPAGLOCK:                               'PAGLOCK';\nPARAMETERIZATION:                      'PARAMETERIZATION';\nPARAM_NODE:                            'PARAM_NODE';\nPARSE:                                 'TRY_'? 'PARSE';\nPARSENAME:                             'PARSENAME';\nPARSEONLY:                             'PARSEONLY';\nPARTIAL:                               'PARTIAL';\nPARTITION:                             'PARTITION';\nPARTITIONS:                            'PARTITIONS';\nPARTNER:                               'PARTNER';\nPASSWORD:                              'PASSWORD';\nPATH:                                  'PATH';\nPATINDEX:                              'PATINDEX';\nPAUSE:                                 'PAUSE';\nPDW_SHOWSPACEUSED:                     'PDW_SHOWSPACEUSED';\nPERCENT:                               'PERCENT';\nPERCENTILE_CONT:                       'PERCENTILE_CONT';\nPERCENTILE_DISC:                       'PERCENTILE_DISC';\nPERCENT_RANK:                          'PERCENT_RANK';\nPERMISSIONS:                           'PERMISSIONS';\nPERMISSION_SET:                        'PERMISSION_SET';\nPERSISTED:                             'PERSISTED';\nPERSIST_SAMPLE_PERCENT:                'PERSIST_SAMPLE_PERCENT';\nPER_CPU:                               'PER_CPU';\nPER_DB:                                'PER_DB';\nPER_NODE:                              'PER_NODE';\nPHYSICAL_ONLY:                         'PHYSICAL_ONLY';\nPIVOT:                                 'PIVOT';\nPLAN:                                  'PLAN';\nPLATFORM:                              'PLATFORM';\nPOISON_MESSAGE_HANDLING:               'POISON_MESSAGE_HANDLING';\nPOLICY:                                'POLICY';\nPOOL:                                  'POOL';\nPORT:                                  'PORT';\nPRECEDING:                             'PRECEDING';\nPRECISION:                             'PRECISION';\nPREDICATE:                             'PREDICATE';\nPRIMARY:                               'PRIMARY';\nPRIMARY_ROLE:                          'PRIMARY_ROLE';\nPRINT:                                 'PRINT';\nPRIOR:                                 'PRIOR';\nPRIORITY:                              'PRIORITY';\nPRIORITY_LEVEL:                        'PRIORITY_LEVEL';\nPRIVATE:                               'PRIVATE';\nPRIVATE_KEY:                           'PRIVATE_KEY';\nPRIVILEGES:                            'PRIVILEGES';\nPROC:                                  'PROC';\nPROCCACHE:                             'PROCCACHE';\nPROCEDURE:                             'PROCEDURE';\nPROCEDURE_NAME:                        'PROCEDURE_NAME';\nPROCESS:                               'PROCESS';\nPROFILE:                               'PROFILE';\nPROPERTY:                              'PROPERTY';\nPROVIDER:                              'PROVIDER';\nPROVIDER_KEY_NAME:                     'PROVIDER_KEY_NAME';\nPUBLIC:                                'PUBLIC';\nPWDCOMPARE:                            'PWDCOMPARE';\nPWDENCRYPT:                            'PWDENCRYPT';\nPYTHON:                                'PYTHON';\nQUERY:                                 'QUERY';\nQUERY_SQUARE_BRACKET:                  '[QUERY]';\nQUEUE:                                 'QUEUE';\nQUEUE_DELAY:                           'QUEUE_DELAY';\nQUOTED_IDENTIFIER:                     'QUOTED_IDENTIFIER';\nQUOTENAME:                             'QUOTENAME';\nR:                                     'R';\nRAISERROR:                             'RAISERROR';\nRANDOMIZED:                            'RANDOMIZED';\nRANGE:                                 'RANGE';\nRANK:                                  'RANK';\nRAW:                                   'RAW';\nRC2:                                   'RC2';\nRC4:                                   'RC4';\nRC4_128:                               'RC4_128';\nREAD:                                  'READ';\nREADCOMMITTED:                         'READCOMMITTED';\nREADCOMMITTEDLOCK:                     'READCOMMITTEDLOCK';\nREADONLY:                              'READONLY';\nREADPAST:                              'READPAST';\nREADTEXT:                              'READTEXT';\nREADUNCOMMITTED:                       'READUNCOMMITTED';\nREADWRITE:                             'READWRITE';\nREAD_COMMITTED_SNAPSHOT:               'READ_COMMITTED_SNAPSHOT';\nREAD_ONLY:                             'READ_ONLY';\nREAD_ONLY_ROUTING_LIST:                'READ_ONLY_ROUTING_LIST';\nREAD_WRITE:                            'READ_WRITE';\nREAD_WRITE_FILEGROUPS:                 'READ_WRITE_FILEGROUPS';\nREBUILD:                               'REBUILD';\nRECEIVE:                               'RECEIVE';\nRECOMPILE:                             'RECOMPILE';\nRECONFIGURE:                           'RECONFIGURE';\nRECOVERY:                              'RECOVERY';\nRECURSIVE_TRIGGERS:                    'RECURSIVE_TRIGGERS';\nREFERENCES:                            'REFERENCES';\nREGENERATE:                            'REGENERATE';\nRELATED_CONVERSATION:                  'RELATED_CONVERSATION';\nRELATED_CONVERSATION_GROUP:            'RELATED_CONVERSATION_GROUP';\nRELATIVE:                              'RELATIVE';\nREMOTE:                                'REMOTE';\nREMOTE_PROC_TRANSACTIONS:              'REMOTE_PROC_TRANSACTIONS';\nREMOTE_SERVICE_NAME:                   'REMOTE_SERVICE_NAME';\nREMOVE:                                'REMOVE';\nREORGANIZE:                            'REORGANIZE';\nREPAIR_ALLOW_DATA_LOSS:                'REPAIR_ALLOW_DATA_LOSS';\nREPAIR_FAST:                           'REPAIR_FAST';\nREPAIR_REBUILD:                        'REPAIR_REBUILD';\nREPEATABLE:                            'REPEATABLE';\nREPEATABLEREAD:                        'REPEATABLEREAD';\nREPLACE:                               'REPLACE';\nREPLICA:                               'REPLICA';\nREPLICATE:                             'REPLICATE';\nREPLICATION:                           'REPLICATION';\nREQUEST_MAX_CPU_TIME_SEC:              'REQUEST_MAX_CPU_TIME_SEC';\nREQUEST_MAX_MEMORY_GRANT_PERCENT:      'REQUEST_MAX_MEMORY_GRANT_PERCENT';\nREQUEST_MEMORY_GRANT_TIMEOUT_SEC:      'REQUEST_MEMORY_GRANT_TIMEOUT_SEC';\nREQUIRED:                              'REQUIRED';\nREQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT: 'REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT';\nRESAMPLE:                              'RESAMPLE';\nRESERVE_DISK_SPACE:                    'RESERVE_DISK_SPACE';\nRESET:                                 'RESET';\nRESOURCE:                              'RESOURCE';\nRESOURCES:                             'RESOURCES';\nRESOURCE_MANAGER_LOCATION:             'RESOURCE_MANAGER_LOCATION';\nRESTART:                               'RESTART';\nRESTORE:                               'RESTORE';\nRESTRICT:                              'RESTRICT';\nRESTRICTED_USER:                       'RESTRICTED_USER';\nRESUMABLE:                             'RESUMABLE';\nRESUME:                                'RESUME';\nRETAINDAYS:                            'RETAINDAYS';\nRETENTION:                             'RETENTION';\nRETURN:                                'RETURN';\nRETURNS:                               'RETURNS';\nREVERSE:                               'REVERSE';\nREVERT:                                'REVERT';\nREVOKE:                                'REVOKE';\nREWIND:                                'REWIND';\nRIGHT:                                 'RIGHT';\nROBUST:                                'ROBUST';\nROLE:                                  'ROLE';\nROLLBACK:                              'ROLLBACK';\nROOT:                                  'ROOT';\nROUND_ROBIN:                           'ROUND_ROBIN';\nROUTE:                                 'ROUTE';\nROW:                                   'ROW';\nROWCOUNT:                              'ROWCOUNT';\nROWCOUNT_BIG:                          'ROWCOUNT_BIG';\nROWGUID:                               'ROWGUID';\nROWGUIDCOL:                            'ROWGUIDCOL';\nROWLOCK:                               'ROWLOCK';\nROWS:                                  'ROWS';\nROW_NUMBER:                            'ROW_NUMBER';\nRSA_1024:                              'RSA_1024';\nRSA_2048:                              'RSA_2048';\nRSA_3072:                              'RSA_3072';\nRSA_4096:                              'RSA_4096';\nRSA_512:                               'RSA_512';\nRTRIM:                                 'RTRIM';\nRULE:                                  'RULE';\nSAFE:                                  'SAFE';\nSAFETY:                                'SAFETY';\nSAMPLE:                                'SAMPLE';\nSAVE:                                  'SAVE';\nSCHEDULER:                             'SCHEDULER';\nSCHEMA:                                'SCHEMA';\nSCHEMABINDING:                         'SCHEMABINDING';\nSCHEMA_ID:                             'SCHEMA_ID';\nSCHEMA_NAME:                           'SCHEMA_NAME';\nSCHEME:                                'SCHEME';\nSCOPED:                                'SCOPED';\nSCOPE_IDENTITY:                        'SCOPE_IDENTITY';\nSCRIPT:                                'SCRIPT';\nSCROLL:                                'SCROLL';\nSCROLL_LOCKS:                          'SCROLL_LOCKS';\nSEARCH:                                'SEARCH';\nSECONDARY:                             'SECONDARY';\nSECONDARY_ONLY:                        'SECONDARY_ONLY';\nSECONDARY_ROLE:                        'SECONDARY_ROLE';\nSECONDS:                               'SECONDS';\nSECRET:                                'SECRET';\nSECURABLES:                            'SECURABLES';\nSECURITY:                              'SECURITY';\nSECURITYAUDIT:                         'SECURITYAUDIT';\nSECURITY_LOG:                          'SECURITY_LOG';\nSEEDING_MODE:                          'SEEDING_MODE';\nSELECT:                                'SELECT';\nSELF:                                  'SELF';\nSEMANTICKEYPHRASETABLE:                'SEMANTICKEYPHRASETABLE';\nSEMANTICSIMILARITYDETAILSTABLE:        'SEMANTICSIMILARITYDETAILSTABLE';\nSEMANTICSIMILARITYTABLE:               'SEMANTICSIMILARITYTABLE';\nSEMI_SENSITIVE:                        'SEMI_SENSITIVE';\nSEND:                                  'SEND';\nSENT:                                  'SENT';\nSEQUENCE:                              'SEQUENCE';\nSEQUENCE_NUMBER:                       'SEQUENCE_NUMBER';\nSERIALIZABLE:                          'SERIALIZABLE';\nSERVER:                                'SERVER';\nSERVERPROPERTY:                        'SERVERPROPERTY';\nSERVICE:                               'SERVICE';\nSERVICEBROKER:                         'SERVICEBROKER';\nSERVICE_BROKER:                        'SERVICE_BROKER';\nSERVICE_NAME:                          'SERVICE_NAME';\nSESSION:                               'SESSION';\nSESSIONPROPERTY:                       'SESSIONPROPERTY';\nSESSION_CONTEXT:                       'SESSION_CONTEXT';\nSESSION_TIMEOUT:                       'SESSION_TIMEOUT';\nSESSION_USER:                          'SESSION_USER';\nSET:                                   'SET';\nSETERROR:                              'SETERROR';\nSETS:                                  'SETS';\nSETTINGS:                              'SETTINGS';\nSETUSER:                               'SETUSER';\nSHARE:                                 'SHARE';\nSHARED:                                'SHARED';\nSHOWCONTIG:                            'SHOWCONTIG';\nSHOWPLAN:                              'SHOWPLAN';\nSHOWPLAN_ALL:                          'SHOWPLAN_ALL';\nSHOWPLAN_TEXT:                         'SHOWPLAN_TEXT';\nSHOWPLAN_XML:                          'SHOWPLAN_XML';\nSHRINKLOG:                             'SHRINKLOG';\nSHUTDOWN:                              'SHUTDOWN';\nSID:                                   'SID';\nSIGNATURE:                             'SIGNATURE';\nSIMPLE:                                'SIMPLE';\nSINGLE_USER:                           'SINGLE_USER';\nSIZE:                                  'SIZE';\nSKIP_KEYWORD:                          'SKIP';\nSMALLINT:                              'SMALLINT';\nSNAPSHOT:                              'SNAPSHOT';\nSOFTNUMA:                              'SOFTNUMA';\nSOME:                                  'SOME';\nSORT_IN_TEMPDB:                        'SORT_IN_TEMPDB';\nSOUNDEX:                               'SOUNDEX';\nSOURCE:                                'SOURCE';\nSPACE_KEYWORD:                         'SPACE';\nSPARSE:                                'SPARSE';\nSPATIAL_WINDOW_MAX_CELLS:              'SPATIAL_WINDOW_MAX_CELLS';\nSPECIFICATION:                         'SPECIFICATION';\nSPLIT:                                 'SPLIT';\nSQL:                                   'SQL';\nSQLDUMPERFLAGS:                        'SQLDUMPERFLAGS';\nSQLDUMPERPATH:                         'SQLDUMPERPATH';\nSQLDUMPERTIMEOUT:                      'SQLDUMPERTIMEOUT';\nSQL_VARIANT_PROPERTY:                  'SQL_VARIANT_PROPERTY';\nSTANDBY:                               'STANDBY';\nSTART:                                 'START';\nSTARTED:                               'STARTED';\nSTARTUP_STATE:                         'STARTUP_STATE';\nSTART_DATE:                            'START_DATE';\nSTATE:                                 'STATE';\nSTATIC:                                'STATIC';\nSTATISTICS:                            'STATISTICS';\nSTATISTICS_INCREMENTAL:                'STATISTICS_INCREMENTAL';\nSTATISTICS_NORECOMPUTE:                'STATISTICS_NORECOMPUTE';\nSTATS:                                 'STATS';\nSTATS_DATE:                            'STATS_DATE';\nSTATS_STREAM:                          'STATS_STREAM';\nSTATUS:                                'STATUS';\nSTATUSONLY:                            'STATUSONLY';\nSTDEV:                                 'STDEV';\nSTDEVP:                                'STDEVP';\nSTOP:                                  'STOP';\nSTOPLIST:                              'STOPLIST';\nSTOPPED:                               'STOPPED';\nSTOP_ON_ERROR:                         'STOP_ON_ERROR';\nSTR:                                   'STR';\nSTRING_AGG:                            'STRING_AGG';\nSTRING_ESCAPE:                         'STRING_ESCAPE';\nSTUFF:                                 'STUFF';\nSUBJECT:                               'SUBJECT';\nSUBSCRIBE:                             'SUBSCRIBE';\nSUBSCRIPTION:                          'SUBSCRIPTION';\nSUBSTRING:                             'SUBSTRING';\nSUM:                                   'SUM';\nSUPPORTED:                             'SUPPORTED';\nSUSER_ID:                              'SUSER_ID';\nSUSER_NAME:                            'SUSER_NAME';\nSUSER_SID:                             'SUSER_SID';\nSUSER_SNAME:                           'SUSER_SNAME';\nSUSPEND:                               'SUSPEND';\nSWITCH:                                'SWITCH';\nSYMMETRIC:                             'SYMMETRIC';\nSYNCHRONOUS_COMMIT:                    'SYNCHRONOUS_COMMIT';\nSYNONYM:                               'SYNONYM';\nSYSTEM:                                'SYSTEM';\nSYSTEM_USER:                           'SYSTEM_USER';\nTABLE:                                 'TABLE';\nTABLERESULTS:                          'TABLERESULTS';\nTABLESAMPLE:                           'TABLESAMPLE';\nTABLOCK:                               'TABLOCK';\nTABLOCKX:                              'TABLOCKX';\nTAKE:                                  'TAKE';\nTAPE:                                  'TAPE';\nTARGET:                                'TARGET';\nTARGET_RECOVERY_TIME:                  'TARGET_RECOVERY_TIME';\nTB:                                    'TB';\nTCP:                                   'TCP';\nTEXTIMAGE_ON:                          'TEXTIMAGE_ON';\nTEXTSIZE:                              'TEXTSIZE';\nTHEN:                                  'THEN';\nTHROW:                                 'THROW';\nTIES:                                  'TIES';\nTIME:                                  'TIME';\nTIMEOUT:                               'TIMEOUT';\nTIMER:                                 'TIMER';\nTINYINT:                               'TINYINT';\nTO:                                    'TO';\nTOP:                                   'TOP';\nTORN_PAGE_DETECTION:                   'TORN_PAGE_DETECTION';\nTOSTRING:                              'TOSTRING';\nTRACE:                                 'TRACE';\nTRACKING:                              'TRACKING';\nTRACK_CAUSALITY:                       'TRACK_CAUSALITY';\nTRAN:                                  'TRAN';\nTRANSACTION:                           'TRANSACTION';\nTRANSACTION_ID:                        'TRANSACTION_ID';\nTRANSFER:                              'TRANSFER';\nTRANSFORM_NOISE_WORDS:                 'TRANSFORM_NOISE_WORDS';\nTRANSLATE:                             'TRANSLATE';\nTRIGGER:                               'TRIGGER';\nTRIM:                                  'TRIM';\nTRIPLE_DES:                            'TRIPLE_DES';\nTRIPLE_DES_3KEY:                       'TRIPLE_DES_3KEY';\nTRUNCATE:                              'TRUNCATE';\nTRUSTWORTHY:                           'TRUSTWORTHY';\nTRY:                                   'TRY';\nTRY_CAST:                              'TRY_CAST';\nTSEQUAL:                               'TSEQUAL';\nTSQL:                                  'TSQL';\nTWO_DIGIT_YEAR_CUTOFF:                 'TWO_DIGIT_YEAR_CUTOFF';\nTYPE:                                  'TYPE';\nTYPEPROPERTY:                          'TYPEPROPERTY';\nTYPE_ID:                               'TYPE_ID';\nTYPE_NAME:                             'TYPE_NAME';\nTYPE_WARNING:                          'TYPE_WARNING';\nUNBOUNDED:                             'UNBOUNDED';\nUNCHECKED:                             'UNCHECKED';\nUNCOMMITTED:                           'UNCOMMITTED';\nUNICODE:                               'UNICODE';\nUNION:                                 'UNION';\nUNIQUE:                                'UNIQUE';\nUNKNOWN:                               'UNKNOWN';\nUNLIMITED:                             'UNLIMITED';\nUNLOCK:                                'UNLOCK';\nUNMASK:                                'UNMASK';\nUNPIVOT:                               'UNPIVOT';\nUNSAFE:                                'UNSAFE';\nUOW:                                   'UOW';\nUPDATE:                                'UPDATE';\nUPDATETEXT:                            'UPDATETEXT';\nUPDLOCK:                               'UPDLOCK';\nUPPER:                                 'UPPER';\nURL:                                   'URL';\nUSE:                                   'USE';\nUSED:                                  'USED';\nUSER:                                  'USER';\nUSER_ID:                               'USER_ID';\nUSER_NAME:                             'USER_NAME';\nUSING:                                 'USING';\nVALIDATION:                            'VALIDATION';\nVALID_XML:                             'VALID_XML';\nVALUE:                                 'VALUE';\nVALUES:                                'VALUES';\nVALUE_SQUARE_BRACKET:                  '[VALUE]';\nVAR:                                   'VAR';\nVARBINARY_KEYWORD:                     'VARBINARY';\nVARP:                                  'VARP';\nVARYING:                               'VARYING';\nVERBOSELOGGING:                        'VERBOSELOGGING';\nVERIFY_CLONEDB:                        'VERIFY_CLONEDB';\nVERSION:                               'VERSION';\nVIEW:                                  'VIEW';\nVIEWS:                                 'VIEWS';\nVIEW_METADATA:                         'VIEW_METADATA';\nVISIBILITY:                            'VISIBILITY';\nWAIT:                                  'WAIT';\nWAITFOR:                               'WAITFOR';\nWAIT_AT_LOW_PRIORITY:                  'WAIT_AT_LOW_PRIORITY';\nWELL_FORMED_XML:                       'WELL_FORMED_XML';\nWHEN:                                  'WHEN';\nWHERE:                                 'WHERE';\nWHILE:                                 'WHILE';\nWINDOWS:                               'WINDOWS';\nWITH:                                  'WITH';\nWITHIN:                                'WITHIN';\nWITHOUT:                               'WITHOUT';\nWITHOUT_ARRAY_WRAPPER:                 'WITHOUT_ARRAY_WRAPPER';\nWITNESS:                               'WITNESS';\nWORK:                                  'WORK';\nWORKLOAD:                              'WORKLOAD';\nWRITETEXT:                             'WRITETEXT';\nXACT_ABORT:                            'XACT_ABORT';\nXACT_STATE:                            'XACT_STATE';\nXLOCK:                                 'XLOCK';\nXML:                                   'XML';\nXMLDATA:                               'XMLDATA';\nXMLNAMESPACES:                         'XMLNAMESPACES';\nXMLSCHEMA:                             'XMLSCHEMA';\nXML_COMPRESSION:                       'XML_COMPRESSION';\nXSINIL:                                'XSINIL';\nZONE:                                  'ZONE';\n\nABS:                                   'ABS';\nACOS:                                  'ACOS';\nASIN:                                  'ASIN';\nATAN:                                  'ATAN';\nATN2:                                  'ATN2';\nCEILING:                               'CEILING';\nCOS:                                   'COS';\nCOT:                                   'COT';\nDEGREES:                               'DEGREES';\nEXP:                                   'EXP';\nFLOOR:                                 'FLOOR';\nLOG10:                                 'LOG10';\nPI:                                    'PI';\nPOWER:                                 'POWER';\nRADIANS:                               'RADIANS';\nRAND:                                  'RAND';\nROUND:                                 'ROUND';\nSIGN:                                  'SIGN';\nSIN:                                   'SIN';\nSQRT:                                  'SQRT';\nSQUARE:                                'SQUARE';\nTAN:                                   'TAN';\n\nCURRENT_TIMEZONE:                      'CURRENT_TIMEZONE';\nCURRENT_TIMEZONE_ID:                   'CURRENT_TIMEZONE_ID';\nDATE_BUCKET:                           'DATE_BUCKET';\nDATEDIFF_BIG:                          'DATEDIFF_BIG';\nDATEFROMPARTS:                         'DATEFROMPARTS';\nDATETIME2FROMPARTS:                    'DATETIME2FROMPARTS';\nDATETIMEFROMPARTS:                     'DATETIMEFROMPARTS';\nDATETIMEOFFSETFROMPARTS:               'DATETIMEOFFSETFROMPARTS';\nDATETRUNC:                             'DATETRUNC';\nDAY:                                   'DAY';\nEOMONTH:                               'EOMONTH';\nISDATE:                                'ISDATE';\nMONTH:                                 'MONTH';\nSMALLDATETIMEFROMPARTS:                'SMALLDATETIMEFROMPARTS';\nSWITCHOFFSET:                          'SWITCHOFFSET';\nSYSDATETIME:                           'SYSDATETIME';\nSYSDATETIMEOFFSET:                     'SYSDATETIMEOFFSET';\nSYSUTCDATETIME:                        'SYSUTCDATETIME';\nTIMEFROMPARTS:                         'TIMEFROMPARTS';\nTODATETIMEOFFSET:                      'TODATETIMEOFFSET';\nYEAR:                                  'YEAR';\n\nQUARTER:                               'QUARTER';\nDAYOFYEAR:                             'DAYOFYEAR';\nWEEK:                                  'WEEK';\nHOUR:                                  'HOUR';\nMINUTE:                                'MINUTE';\nSECOND:                                'SECOND';\nMILLISECOND:                           'MILLISECOND';\nMICROSECOND:                           'MICROSECOND';\nNANOSECOND:                            'NANOSECOND';\nTZOFFSET:                              'TZOFFSET';\nISO_WEEK:                              'ISO_WEEK';\nWEEKDAY:                               'WEEKDAY';\n\nYEAR_ABBR:                             'yy' | 'yyyy';\nQUARTER_ABBR:                          'qq' | 'q';\nMONTH_ABBR:                            'mm' | 'm';\nDAYOFYEAR_ABBR:                        'dy' | 'y';\nDAY_ABBR:                              'dd' | 'd';\nWEEK_ABBR:                             'wk' | 'ww';\nHOUR_ABBR:                             'hh';\nMINUTE_ABBR:                           'mi' | 'n';\nSECOND_ABBR:                           'ss' | 's';\nMILLISECOND_ABBR:                      'ms';\nMICROSECOND_ABBR:                      'mcs';\nNANOSECOND_ABBR:                       'ns';\nTZOFFSET_ABBR:                         'tz';\nISO_WEEK_ABBR:                         'isowk' | 'isoww';\nWEEKDAY_ABBR:                          'dw';\n\nSP_EXECUTESQL:                         'SP_EXECUTESQL';\n\n//Build-ins:\nVARCHAR:                               'VARCHAR';\nNVARCHAR:                              'NVARCHAR';\n\n//Combinations that cannot be used as IDs\nDISK_DRIVE:                            [A-Z][:];\nDOLLAR_ACTION:                         '$ACTION';\n\n// Functions starting with double at signs\n// https://learn.microsoft.com/en-us/sql/t-sql/language-elements/variables-transact-sql?view=sql-server-ver16\nCURSOR_ROWS:                           '@@CURSOR_ROWS';\nFETCH_STATUS:                          '@@FETCH_STATUS';\n\nIPV4_ADDR:                             DEC_DIGIT+ '.' DEC_DIGIT+ '.' DEC_DIGIT+ '.' DEC_DIGIT+;\n\nSPACE:              [ \\t\\r\\n]+    -> skip;\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/slash-star-comment-transact-sql\nCOMMENT:            '/*' (COMMENT | .)*? '*/' -> channel(HIDDEN);\nLINE_COMMENT:       '--' ~[\\r\\n]* -> channel(HIDDEN);\n\n// TODO: ID can be not only Latin.\nDOUBLE_QUOTE_ID:    '\"' ~'\"'+ '\"';\nDOUBLE_QUOTE_BLANK: '\"\"';\nSINGLE_QUOTE:       '\\'';\nSQUARE_BRACKET_ID:  '[' (~']' | ']' ']')* ']';\nLOCAL_ID:           '@' ([A-Z_$@#0-9] | FullWidthLetter)*;\nTEMP_ID:            '#' ([A-Z_$@#0-9] | FullWidthLetter)*;\nDECIMAL:             DEC_DIGIT+;\nID:                  ( [A-Z_#] | FullWidthLetter) ( [A-Z_#$@0-9] | FullWidthLetter )*;\nSTRING : 'N'? '\\'' (~'\\'' | '\\'\\'')* '\\'';\nBINARY:              '0' 'X' HEX_DIGIT*;\nFLOAT:               DEC_DOT_DEC;\nREAL:                (DECIMAL | DEC_DOT_DEC) ('E' [+-]? DEC_DIGIT+);\n\nEQUAL:               '=';\n\nGREATER:             '>';\nLESS:                '<';\nEXCLAMATION:         '!';\n\nPLUS_ASSIGN:         '+=';\nMINUS_ASSIGN:        '-=';\nMULT_ASSIGN:         '*=';\nDIV_ASSIGN:          '/=';\nMOD_ASSIGN:          '%=';\nAND_ASSIGN:          '&=';\nXOR_ASSIGN:          '^=';\nOR_ASSIGN:           '|=';\n\nDOUBLE_BAR:          '||';\nDOT:                 '.';\nUNDERLINE:           '_';\nAT:                  '@';\nSHARP:               '#';\nDOLLAR:              '$';\nLR_BRACKET:          '(';\nRR_BRACKET:          ')';\nCOMMA:               ',';\nSEMI:                ';';\nCOLON:               ':';\nDOUBLE_COLON:        '::';\nSTAR:                '*';\nDIVIDE:              '/';\nMODULE:              '%';\nPLUS:                '+';\nMINUS:               '-';\nBIT_NOT:             '~';\nBIT_OR:              '|';\nBIT_AND:             '&';\nBIT_XOR:             '^';\n\nPLACEHOLDER:         '?';\n\nfragment LETTER:       [A-Z_];\nfragment DEC_DOT_DEC:  (DEC_DIGIT+ '.' DEC_DIGIT+ |  DEC_DIGIT+ '.' | '.' DEC_DIGIT+);\nfragment HEX_DIGIT:    [0-9A-F];\nfragment DEC_DIGIT:    [0-9];\n\n\nfragment FullWidthLetter\n    : '\\u00c0'..'\\u00d6'\n    | '\\u00d8'..'\\u00f6'\n    | '\\u00f8'..'\\u00ff'\n    | '\\u0100'..'\\u1fff'\n    | '\\u2c00'..'\\u2fff'\n    | '\\u3040'..'\\u318f'\n    | '\\u3300'..'\\u337f'\n    | '\\u3400'..'\\u3fff'\n    | '\\u4e00'..'\\u9fff'\n    | '\\ua000'..'\\ud7ff'\n    | '\\uf900'..'\\ufaff'\n    | '\\uff00'..'\\ufff0'\n    // | '\\u10000'..'\\u1F9FF'  //not support four bytes chars\n    // | '\\u20000'..'\\u2FA1F'\n    ;"
  },
  {
    "path": "superior-sqlserver-parser/src/main/antlr4/io/github/melin/superior/parser/sqlserver/antlr4/SqlServerParser.g4",
    "content": "/*\nT-SQL (Transact-SQL, MSSQL) grammar.\nThe MIT License (MIT).\nCopyright (c) 2017, Mark Adams (madams51703@gmail.com)\nCopyright (c) 2015-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies.\nCopyright (c) 2016, Scott Ure (scott@redstormsoftware.com).\nCopyright (c) 2016, Rui Zhang (ruizhang.ccs@gmail.com).\nCopyright (c) 2016, Marcus Henriksson (kuseman80@gmail.com).\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n*/\n\nparser grammar SqlServerParser;\n\noptions { tokenVocab=SqlServerLexer; }\n\ntsql_file\n    : batch* EOF\n    | execute_body_batch go_statement* EOF\n    ;\n\nbatch\n    : go_statement\n    | execute_body_batch? (go_statement | sql_clauses+) go_statement*\n    | batch_level_statement go_statement*\n    ;\n\nbatch_level_statement\n    : create_or_alter_function\n    | create_or_alter_procedure\n    | create_or_alter_trigger\n    | create_view\n    ;\nsql_clauses\n    : dml_clause SEMI?\n    | cfl_statement SEMI?\n    | another_statement SEMI?\n    | ddl_clause SEMI?\n    | dbcc_clause SEMI?\n    | backup_statement SEMI?\n    | SEMI\n    ;\n\n// Data Manipulation Language: https://msdn.microsoft.com/en-us/library/ff848766(v=sql.120).aspx\ndml_clause\n    : merge_statement\n    | delete_statement\n    | insert_statement\n    | select_statement_standalone\n    | update_statement\n    ;\n\n// Data Definition Language: https://msdn.microsoft.com/en-us/library/ff848799.aspx)\nddl_clause\n    : alter_application_role\n    | alter_assembly\n    | alter_asymmetric_key\n    | alter_authorization\n    | alter_authorization_for_azure_dw\n    | alter_authorization_for_parallel_dw\n    | alter_authorization_for_sql_database\n    | alter_availability_group\n    | alter_certificate\n    | alter_column_encryption_key\n    | alter_credential\n    | alter_cryptographic_provider\n    | alter_database\n    | alter_database_audit_specification\n    | alter_db_role\n    | alter_endpoint\n    | alter_external_data_source\n    | alter_external_library\n    | alter_external_resource_pool\n    | alter_fulltext_catalog\n    | alter_fulltext_stoplist\n    | alter_index\n    | alter_login_azure_sql\n    | alter_login_azure_sql_dw_and_pdw\n    | alter_login_sql_server\n    | alter_master_key_azure_sql\n    | alter_master_key_sql_server\n    | alter_message_type\n    | alter_partition_function\n    | alter_partition_scheme\n    | alter_remote_service_binding\n    | alter_resource_governor\n    | alter_schema_azure_sql_dw_and_pdw\n    | alter_schema_sql\n    | alter_sequence\n    | alter_server_audit\n    | alter_server_audit_specification\n    | alter_server_configuration\n    | alter_server_role\n    | alter_server_role_pdw\n    | alter_service\n    | alter_service_master_key\n    | alter_symmetric_key\n    | alter_table\n    | alter_user\n    | alter_user_azure_sql\n    | alter_workload_group\n    | alter_xml_schema_collection\n    | create_application_role\n    | create_assembly\n    | create_asymmetric_key\n    | create_column_encryption_key\n    | create_column_master_key\n    | create_columnstore_index\n    | create_credential\n    | create_cryptographic_provider\n    | create_database\n    | create_database_audit_specification\n    | create_db_role\n    | create_endpoint\n    | create_event_notification\n    | create_external_library\n    | create_external_resource_pool\n    | create_fulltext_catalog\n    | create_fulltext_stoplist\n    | create_index\n    | create_login_azure_sql\n    | create_login_pdw\n    | create_login_sql_server\n    | create_master_key_azure_sql\n    | create_master_key_sql_server\n    | create_nonclustered_columnstore_index\n    | create_or_alter_broker_priority\n    | create_or_alter_event_session\n    | create_partition_function\n    | create_partition_scheme\n    | create_remote_service_binding\n    | create_resource_pool\n    | create_route\n    | create_rule\n    | create_schema\n    | create_schema_azure_sql_dw_and_pdw\n    | create_search_property_list\n    | create_security_policy\n    | create_sequence\n    | create_server_audit\n    | create_server_audit_specification\n    | create_server_role\n    | create_service\n    | create_statistics\n    | create_synonym\n    | create_table\n    | create_type\n    | create_user\n    | create_user_azure_sql_dw\n    | create_workload_group\n    | create_xml_index\n    | create_xml_schema_collection\n    | disable_trigger\n    | drop_aggregate\n    | drop_application_role\n    | drop_assembly\n    | drop_asymmetric_key\n    | drop_availability_group\n    | drop_broker_priority\n    | drop_certificate\n    | drop_column_encryption_key\n    | drop_column_master_key\n    | drop_contract\n    | drop_credential\n    | drop_cryptograhic_provider\n    | drop_database\n    | drop_database_audit_specification\n    | drop_database_encryption_key\n    | drop_database_scoped_credential\n    | drop_db_role\n    | drop_default\n    | drop_endpoint\n    | drop_event_notifications\n    | drop_event_session\n    | drop_external_data_source\n    | drop_external_file_format\n    | drop_external_library\n    | drop_external_resource_pool\n    | drop_external_table\n    | drop_fulltext_catalog\n    | drop_fulltext_index\n    | drop_fulltext_stoplist\n    | drop_function\n    | drop_index\n    | drop_login\n    | drop_master_key\n    | drop_message_type\n    | drop_partition_function\n    | drop_partition_scheme\n    | drop_procedure\n    | drop_queue\n    | drop_remote_service_binding\n    | drop_resource_pool\n    | drop_route\n    | drop_rule\n    | drop_schema\n    | drop_search_property_list\n    | drop_security_policy\n    | drop_sequence\n    | drop_server_audit\n    | drop_server_audit_specification\n    | drop_server_role\n    | drop_service\n    | drop_signature\n    | drop_statistics\n    | drop_statistics_name_azure_dw_and_pdw\n    | drop_symmetric_key\n    | drop_synonym\n    | drop_table\n    | drop_trigger\n    | drop_type\n    | drop_user\n    | drop_view\n    | drop_workload_group\n    | drop_xml_schema_collection\n    | enable_trigger\n    | lock_table\n    | truncate_table\n    | update_statistics\n    ;\n\nbackup_statement\n    : backup_database\n    | backup_log\n    | backup_certificate\n    | backup_master_key\n    | backup_service_master_key\n    ;\n\n// Control-of-Flow Language: https://docs.microsoft.com/en-us/sql/t-sql/language-elements/control-of-flow\ncfl_statement\n    : block_statement\n    | break_statement\n    | continue_statement\n    | goto_statement\n    | if_statement\n    | print_statement\n    | raiseerror_statement\n    | return_statement\n    | throw_statement\n    | try_catch_statement\n    | waitfor_statement\n    | while_statement\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/begin-end-transact-sql\nblock_statement\n    : BEGIN ';'? sql_clauses* END ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/break-transact-sql\nbreak_statement\n    : BREAK ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/continue-transact-sql\ncontinue_statement\n    : CONTINUE ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/goto-transact-sql\ngoto_statement\n    : GOTO id_ ';'?\n    | id_ ':' ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/return-transact-sql\nreturn_statement\n    : RETURN expression? ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/if-else-transact-sql\nif_statement\n    : IF search_condition sql_clauses (ELSE sql_clauses)? ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/throw-transact-sql\nthrow_statement\n    : THROW (throw_error_number ',' throw_message ',' throw_state)? ';'?\n    ;\n\nthrow_error_number\n    : DECIMAL | LOCAL_ID\n    ;\n\nthrow_message\n    : STRING | LOCAL_ID\n    ;\n\nthrow_state\n    : DECIMAL | LOCAL_ID\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql\ntry_catch_statement\n    : BEGIN TRY ';'? try_clauses=sql_clauses+ END TRY ';'? BEGIN CATCH ';'? catch_clauses=sql_clauses* END CATCH ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/waitfor-transact-sql\nwaitfor_statement\n    : WAITFOR receive_statement? ','? ((DELAY | TIME | TIMEOUT) time)?  expression? ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/while-transact-sql\nwhile_statement\n    : WHILE search_condition (sql_clauses | BREAK ';'? | CONTINUE ';'?)\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/print-transact-sql\nprint_statement\n    : PRINT (expression | DOUBLE_QUOTE_ID) (',' LOCAL_ID)* ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql\nraiseerror_statement\n    : RAISERROR '(' msg=(DECIMAL | STRING | LOCAL_ID) ',' severity=constant_LOCAL_ID ','\n    state=constant_LOCAL_ID (',' (constant_LOCAL_ID | NULL_))* ')' (WITH (LOG | SETERROR | NOWAIT))? ';'?\n    | RAISERROR DECIMAL formatstring=(STRING | LOCAL_ID | DOUBLE_QUOTE_ID) (',' argument=(DECIMAL | STRING | LOCAL_ID))*\n    ;\n\nempty_statement\n    : ';'\n    ;\n\nanother_statement\n    : alter_queue\n    | checkpoint_statement\n    | conversation_statement\n    | create_contract\n    | create_queue\n    | cursor_statement\n    | declare_statement\n    | execute_statement\n    | kill_statement\n    | message_statement\n    | reconfigure_statement\n    | security_statement\n    | set_statement\n    | setuser_statement\n    | shutdown_statement\n    | transaction_statement\n    | use_statement\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-application-role-transact-sql\nalter_application_role\n    : ALTER APPLICATION ROLE appliction_role=id_ WITH  (COMMA? NAME EQUAL new_application_role_name=id_)? (COMMA? PASSWORD EQUAL application_role_password=STRING)? (COMMA? DEFAULT_SCHEMA EQUAL app_role_default_schema=id_)?\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-xml-schema-collection-transact-sql?view=sql-server-ver16\nalter_xml_schema_collection\n    : ALTER XML SCHEMA COLLECTION (id_ '.')? id_ ADD STRING\n    ;\n\ncreate_application_role\n    : CREATE APPLICATION ROLE appliction_role=id_ WITH   (COMMA? PASSWORD EQUAL application_role_password=STRING)? (COMMA? DEFAULT_SCHEMA EQUAL app_role_default_schema=id_)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-aggregate-transact-sql\n\ndrop_aggregate\n    : DROP AGGREGATE ( IF EXISTS )? ( schema_name=id_ DOT )? aggregate_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-application-role-transact-sql\ndrop_application_role\n    : DROP APPLICATION ROLE rolename=id_\n    ;\n\nalter_assembly\n    : alter_assembly_start assembly_name=id_ alter_assembly_clause\n    ;\n\nalter_assembly_start\n    :  ALTER ASSEMBLY\n    ;\n\nalter_assembly_clause\n    : alter_assembly_from_clause? alter_assembly_with_clause? alter_assembly_drop_clause? alter_assembly_add_clause?\n    ;\n\nalter_assembly_from_clause\n    : alter_assembly_from_clause_start (client_assembly_specifier | alter_assembly_file_bits )\n    ;\n\nalter_assembly_from_clause_start\n    : FROM\n    ;\n\nalter_assembly_drop_clause\n    : alter_assembly_drop alter_assembly_drop_multiple_files\n    ;\n\nalter_assembly_drop_multiple_files\n    : ALL\n    | multiple_local_files\n    ;\n\nalter_assembly_drop\n    : DROP\n    ;\n\nalter_assembly_add_clause\n    : alter_asssembly_add_clause_start alter_assembly_client_file_clause\n    ;\n\nalter_asssembly_add_clause_start\n    : ADD FILE FROM\n    ;\n\n// need to implement\nalter_assembly_client_file_clause\n    :  alter_assembly_file_name (alter_assembly_as id_)?\n    ;\n\nalter_assembly_file_name\n    : STRING\n    ;\n\n//need to implement\nalter_assembly_file_bits\n    : alter_assembly_as id_\n    ;\n\nalter_assembly_as\n    : AS\n    ;\n\nalter_assembly_with_clause\n    : alter_assembly_with assembly_option\n    ;\n\nalter_assembly_with\n    : WITH\n    ;\n\nclient_assembly_specifier\n    : network_file_share\n    | local_file\n    | STRING\n    ;\n\nassembly_option\n    : PERMISSION_SET EQUAL (SAFE|EXTERNAL_ACCESS|UNSAFE)\n    | VISIBILITY EQUAL on_off\n    | UNCHECKED DATA\n    | assembly_option COMMA\n    ;\n\nnetwork_file_share\n    : network_file_start network_computer file_path\n    ;\n\nnetwork_computer\n    : computer_name=id_\n    ;\n\nnetwork_file_start\n    : DOUBLE_BACK_SLASH\n    ;\n\nfile_path\n    : file_directory_path_separator file_path\n    | id_\n    ;\n\nfile_directory_path_separator\n    : '\\\\'\n    ;\n\nlocal_file\n    : local_drive file_path\n    ;\n\nlocal_drive\n    :\n    DISK_DRIVE\n    ;\nmultiple_local_files\n    :\n    multiple_local_file_start local_file SINGLE_QUOTE COMMA\n    | local_file\n    ;\n\nmultiple_local_file_start\n    : SINGLE_QUOTE\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-assembly-transact-sql\ncreate_assembly\n    : CREATE ASSEMBLY assembly_name=id_ (AUTHORIZATION owner_name=id_)?\n       FROM (COMMA? (STRING|BINARY) )+\n       (WITH PERMISSION_SET EQUAL (SAFE|EXTERNAL_ACCESS|UNSAFE) )?\n\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-assembly-transact-sql\ndrop_assembly\n    : DROP ASSEMBLY ( IF EXISTS )? (COMMA? assembly_name=id_)+\n       ( WITH NO DEPENDENTS )?\n    ;\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-asymmetric-key-transact-sql\n\nalter_asymmetric_key\n    : alter_asymmetric_key_start Asym_Key_Name=id_ (asymmetric_key_option | REMOVE PRIVATE KEY )\n    ;\n\nalter_asymmetric_key_start\n    : ALTER ASYMMETRIC KEY\n    ;\n\nasymmetric_key_option\n    : asymmetric_key_option_start asymmetric_key_password_change_option ( COMMA asymmetric_key_password_change_option)? RR_BRACKET\n    ;\n\nasymmetric_key_option_start\n    : WITH PRIVATE KEY LR_BRACKET\n    ;\n\nasymmetric_key_password_change_option\n    : DECRYPTION BY PASSWORD EQUAL STRING\n    | ENCRYPTION BY PASSWORD EQUAL STRING\n    ;\n\n\n//https://docs.microsoft.com/en-us/sql/t-sql/statements/create-asymmetric-key-transact-sql\n\ncreate_asymmetric_key\n    : CREATE ASYMMETRIC KEY Asym_Key_Nam=id_\n       (AUTHORIZATION database_principal_name=id_)?\n       ( FROM (FILE EQUAL STRING |EXECUTABLE_FILE EQUAL STRING|ASSEMBLY Assembly_Name=id_ | PROVIDER Provider_Name=id_) )?\n       (WITH (ALGORITHM EQUAL ( RSA_4096 | RSA_3072 | RSA_2048 | RSA_1024 | RSA_512)  |PROVIDER_KEY_NAME EQUAL provider_key_name=STRING | CREATION_DISPOSITION EQUAL (CREATE_NEW|OPEN_EXISTING)  )   )?\n       (ENCRYPTION BY PASSWORD EQUAL asymmetric_key_password=STRING )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-asymmetric-key-transact-sql\ndrop_asymmetric_key\n    : DROP ASYMMETRIC KEY key_name=id_ ( REMOVE PROVIDER KEY )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-authorization-transact-sql\n\nalter_authorization\n    : alter_authorization_start (class_type colon_colon)? entity=entity_name entity_to authorization_grantee\n    ;\n\nauthorization_grantee\n    : principal_name=id_\n    | SCHEMA OWNER\n    ;\n\nentity_to\n    : TO\n    ;\n\ncolon_colon\n    : DOUBLE_COLON\n    ;\n\nalter_authorization_start\n    : ALTER AUTHORIZATION ON\n    ;\n\nalter_authorization_for_sql_database\n    : alter_authorization_start (class_type_for_sql_database colon_colon)? entity=entity_name entity_to authorization_grantee\n    ;\n\nalter_authorization_for_azure_dw\n    : alter_authorization_start (class_type_for_azure_dw colon_colon)? entity=entity_name_for_azure_dw entity_to authorization_grantee\n    ;\n\nalter_authorization_for_parallel_dw\n    : alter_authorization_start (class_type_for_parallel_dw colon_colon)? entity=entity_name_for_parallel_dw entity_to authorization_grantee\n    ;\n\n\nclass_type\n    : OBJECT\n    | ASSEMBLY\n    | ASYMMETRIC KEY\n    | AVAILABILITY GROUP\n    | CERTIFICATE\n    | CONTRACT\n    | TYPE\n    | DATABASE\n    | ENDPOINT\n    | FULLTEXT CATALOG\n    | FULLTEXT STOPLIST\n    | MESSAGE TYPE\n    | REMOTE SERVICE BINDING\n    | ROLE\n    | ROUTE\n    | SCHEMA\n    | SEARCH PROPERTY LIST\n    | SERVER ROLE\n    | SERVICE\n    | SYMMETRIC KEY\n    | XML SCHEMA COLLECTION\n    ;\n\nclass_type_for_sql_database\n    :  OBJECT\n    | ASSEMBLY\n    | ASYMMETRIC KEY\n    | CERTIFICATE\n    | TYPE\n    | DATABASE\n    | FULLTEXT CATALOG\n    | FULLTEXT STOPLIST\n    | ROLE\n    | SCHEMA\n    | SEARCH PROPERTY LIST\n    | SYMMETRIC KEY\n    | XML SCHEMA COLLECTION\n    ;\n\nclass_type_for_azure_dw\n    : SCHEMA\n    | OBJECT\n    ;\n\nclass_type_for_parallel_dw\n    : DATABASE\n    | SCHEMA\n    | OBJECT\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/grant-transact-sql?view=sql-server-ver15\n// SELECT DISTINCT '| ' + CLASS_DESC\n// FROM sys.dm_audit_actions\n// ORDER BY 1\nclass_type_for_grant\n    : APPLICATION ROLE\n    | ASSEMBLY\n    | ASYMMETRIC KEY\n    | AUDIT\n    | AVAILABILITY GROUP\n    | BROKER PRIORITY\n    | CERTIFICATE\n    | COLUMN ( ENCRYPTION | MASTER ) KEY\n    | CONTRACT\n    | CREDENTIAL\n    | CRYPTOGRAPHIC PROVIDER\n    | DATABASE ( AUDIT SPECIFICATION\n               | ENCRYPTION KEY\n               | EVENT SESSION\n               | SCOPED ( CONFIGURATION\n                        | CREDENTIAL\n                        | RESOURCE GOVERNOR )\n               )?\n    | ENDPOINT\n    | EVENT SESSION\n    | NOTIFICATION (DATABASE | OBJECT | SERVER)\n    | EXTERNAL ( DATA SOURCE\n               | FILE FORMAT\n               | LIBRARY\n               | RESOURCE POOL\n               | TABLE\n               | CATALOG\n               | STOPLIST\n               )\n    | LOGIN\n    | MASTER KEY\n    | MESSAGE TYPE\n    | OBJECT\n    | PARTITION ( FUNCTION | SCHEME)\n    | REMOTE SERVICE BINDING\n    | RESOURCE GOVERNOR\n    | ROLE\n    | ROUTE\n    | SCHEMA\n    | SEARCH PROPERTY LIST\n    | SERVER ( ( AUDIT SPECIFICATION? ) | ROLE )?\n    | SERVICE\n    | SQL LOGIN\n    | SYMMETRIC KEY\n    | TRIGGER ( DATABASE | SERVER)\n    | TYPE\n    | USER\n    | XML SCHEMA COLLECTION\n    ;\n\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-availability-group-transact-sql\ndrop_availability_group\n    : DROP AVAILABILITY GROUP group_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-availability-group-transact-sql\nalter_availability_group\n    : alter_availability_group_start alter_availability_group_options\n    ;\n\nalter_availability_group_start\n    : ALTER AVAILABILITY GROUP group_name=id_\n    ;\n\nalter_availability_group_options\n    : SET LR_BRACKET ( ( AUTOMATED_BACKUP_PREFERENCE EQUAL ( PRIMARY | SECONDARY_ONLY| SECONDARY | NONE )  | FAILURE_CONDITION_LEVEL  EQUAL DECIMAL   | HEALTH_CHECK_TIMEOUT EQUAL milliseconds=DECIMAL  | DB_FAILOVER  EQUAL ( ON | OFF )   | REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT EQUAL DECIMAL ) RR_BRACKET  )\n    | ADD DATABASE database_name=id_\n    | REMOVE DATABASE database_name=id_\n    | ADD REPLICA ON server_instance=STRING (WITH LR_BRACKET ( (ENDPOINT_URL EQUAL STRING)?   (COMMA? AVAILABILITY_MODE EQUAL (SYNCHRONOUS_COMMIT| ASYNCHRONOUS_COMMIT))?    (COMMA? FAILOVER_MODE EQUAL (AUTOMATIC|MANUAL) )?  (COMMA?   SEEDING_MODE EQUAL (AUTOMATIC|MANUAL) )?  (COMMA?  BACKUP_PRIORITY EQUAL DECIMAL)?  ( COMMA? PRIMARY_ROLE  LR_BRACKET ALLOW_CONNECTIONS EQUAL ( READ_WRITE | ALL ) RR_BRACKET)?   ( COMMA? SECONDARY_ROLE  LR_BRACKET ALLOW_CONNECTIONS EQUAL ( READ_ONLY  ) RR_BRACKET )? )\n)    RR_BRACKET\n        |SECONDARY_ROLE LR_BRACKET (ALLOW_CONNECTIONS EQUAL (NO|READ_ONLY|ALL) | READ_ONLY_ROUTING_LIST EQUAL ( LR_BRACKET ( ( STRING) ) RR_BRACKET ) )\n        |PRIMARY_ROLE LR_BRACKET (ALLOW_CONNECTIONS EQUAL (NO|READ_ONLY|ALL) | READ_ONLY_ROUTING_LIST EQUAL ( LR_BRACKET ( (COMMA? STRING)*|NONE ) RR_BRACKET )\n        | SESSION_TIMEOUT EQUAL session_timeout=DECIMAL\n)\n    | MODIFY REPLICA ON server_instance=STRING (WITH LR_BRACKET (ENDPOINT_URL EQUAL STRING|  AVAILABILITY_MODE EQUAL (SYNCHRONOUS_COMMIT| ASYNCHRONOUS_COMMIT)  | FAILOVER_MODE EQUAL (AUTOMATIC|MANUAL) |   SEEDING_MODE EQUAL (AUTOMATIC|MANUAL)  |  BACKUP_PRIORITY EQUAL DECIMAL  )\n        |SECONDARY_ROLE LR_BRACKET (ALLOW_CONNECTIONS EQUAL (NO|READ_ONLY|ALL) | READ_ONLY_ROUTING_LIST EQUAL ( LR_BRACKET ( ( STRING) ) RR_BRACKET ) )\n        |PRIMARY_ROLE LR_BRACKET (ALLOW_CONNECTIONS EQUAL (NO|READ_ONLY|ALL) | READ_ONLY_ROUTING_LIST EQUAL ( LR_BRACKET ( (COMMA? STRING)*|NONE ) RR_BRACKET )\n         | SESSION_TIMEOUT EQUAL session_timeout=DECIMAL\n)   ) RR_BRACKET\n    | REMOVE REPLICA ON STRING\n    | JOIN\n    | JOIN AVAILABILITY GROUP ON (COMMA? ag_name=STRING WITH LR_BRACKET ( LISTENER_URL EQUAL STRING COMMA AVAILABILITY_MODE EQUAL (SYNCHRONOUS_COMMIT|ASYNCHRONOUS_COMMIT) COMMA FAILOVER_MODE EQUAL MANUAL COMMA SEEDING_MODE EQUAL (AUTOMATIC|MANUAL) RR_BRACKET ) )+\n     | MODIFY AVAILABILITY GROUP ON (COMMA? ag_name_modified=STRING WITH LR_BRACKET (LISTENER_URL EQUAL STRING  (COMMA? AVAILABILITY_MODE EQUAL (SYNCHRONOUS_COMMIT|ASYNCHRONOUS_COMMIT) )? (COMMA? FAILOVER_MODE EQUAL MANUAL )? (COMMA? SEEDING_MODE EQUAL (AUTOMATIC|MANUAL))? RR_BRACKET ) )+\n    |GRANT CREATE ANY DATABASE\n    | DENY CREATE ANY DATABASE\n    | FAILOVER\n    | FORCE_FAILOVER_ALLOW_DATA_LOSS\n    | ADD LISTENER listener_name=STRING  LR_BRACKET ( WITH DHCP (ON LR_BRACKET ip_v4_failover ip_v4_failover RR_BRACKET ) | WITH IP LR_BRACKET (    (COMMA? LR_BRACKET ( ip_v4_failover COMMA  ip_v4_failover | ip_v6_failover ) RR_BRACKET)+ RR_BRACKET  (COMMA PORT EQUAL DECIMAL)? ) ) RR_BRACKET\n    | MODIFY LISTENER (ADD IP LR_BRACKET (ip_v4_failover ip_v4_failover | ip_v6_failover) RR_BRACKET | PORT EQUAL DECIMAL )\n    |RESTART LISTENER STRING\n    |REMOVE LISTENER STRING\n    |OFFLINE\n    | WITH LR_BRACKET DTC_SUPPORT EQUAL PER_DB RR_BRACKET\n    ;\n\nip_v4_failover\n    : STRING\n    ;\n\nip_v6_failover\n    : STRING\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-broker-priority-transact-sql\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-broker-priority-transact-sql\ncreate_or_alter_broker_priority\n    : (CREATE | ALTER) BROKER PRIORITY ConversationPriorityName=id_ FOR CONVERSATION\n      SET LR_BRACKET\n     ( CONTRACT_NAME EQUAL ( ( id_) | ANY )  COMMA?  )?\n     ( LOCAL_SERVICE_NAME EQUAL (DOUBLE_FORWARD_SLASH? id_ | ANY ) COMMA? )?\n     ( REMOTE_SERVICE_NAME  EQUAL (RemoteServiceName=STRING | ANY ) COMMA? )?\n     ( PRIORITY_LEVEL EQUAL ( PriorityValue=DECIMAL | DEFAULT ) ) ?\n     RR_BRACKET\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-broker-priority-transact-sql\ndrop_broker_priority\n    : DROP BROKER PRIORITY ConversationPriorityName=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-certificate-transact-sql\nalter_certificate\n    : ALTER CERTIFICATE certificate_name=id_ (REMOVE PRIVATE_KEY | WITH PRIVATE KEY LR_BRACKET ( FILE EQUAL STRING COMMA? | DECRYPTION BY PASSWORD EQUAL STRING COMMA?| ENCRYPTION BY PASSWORD EQUAL STRING  COMMA?)+ RR_BRACKET | WITH ACTIVE FOR BEGIN_DIALOG EQUAL ( ON | OFF ) )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-column-encryption-key-transact-sql\nalter_column_encryption_key\n    : ALTER COLUMN ENCRYPTION KEY column_encryption_key=id_ (ADD | DROP) VALUE LR_BRACKET COLUMN_MASTER_KEY EQUAL column_master_key_name=id_ ( COMMA ALGORITHM EQUAL algorithm_name=STRING  COMMA ENCRYPTED_VALUE EQUAL BINARY)? RR_BRACKET\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-column-encryption-key-transact-sql\ncreate_column_encryption_key\n    :   CREATE COLUMN ENCRYPTION KEY column_encryption_key=id_\n         WITH VALUES\n           (LR_BRACKET COMMA? COLUMN_MASTER_KEY EQUAL column_master_key_name=id_ COMMA\n           ALGORITHM EQUAL algorithm_name=STRING  COMMA\n           ENCRYPTED_VALUE EQUAL encrypted_value=BINARY RR_BRACKET COMMA?)+\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-certificate-transact-sql\ndrop_certificate\n    : DROP CERTIFICATE certificate_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-column-encryption-key-transact-sql\ndrop_column_encryption_key\n    : DROP COLUMN ENCRYPTION KEY key_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-column-master-key-transact-sql\ndrop_column_master_key\n    : DROP COLUMN MASTER KEY key_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-contract-transact-sql\ndrop_contract\n    : DROP CONTRACT dropped_contract_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-credential-transact-sql\ndrop_credential\n    : DROP CREDENTIAL credential_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-cryptographic-provider-transact-sql\ndrop_cryptograhic_provider\n    : DROP CRYPTOGRAPHIC PROVIDER provider_name=id_\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-database-transact-sql\ndrop_database\n    : DROP DATABASE ( IF EXISTS )? (COMMA? database_name_or_database_snapshot_name=id_)+\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-database-audit-specification-transact-sql\ndrop_database_audit_specification\n    : DROP DATABASE AUDIT SPECIFICATION audit_specification_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-database-encryption-key-transact-sql?view=sql-server-ver15\ndrop_database_encryption_key\n    : DROP DATABASE ENCRYPTION KEY\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-database-scoped-credential-transact-sql\ndrop_database_scoped_credential\n   : DROP DATABASE SCOPED CREDENTIAL credential_name=id_\n   ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-default-transact-sql\ndrop_default\n    : DROP DEFAULT ( IF EXISTS )? (COMMA? (schema_name=id_ DOT)? default_name=id_)\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-endpoint-transact-sql\ndrop_endpoint\n    : DROP ENDPOINT endPointName=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-external-data-source-transact-sql\ndrop_external_data_source\n    : DROP EXTERNAL DATA SOURCE external_data_source_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-external-file-format-transact-sql\ndrop_external_file_format\n    : DROP EXTERNAL FILE FORMAT external_file_format_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-external-library-transact-sql\ndrop_external_library\n    : DROP EXTERNAL LIBRARY library_name=id_\n( AUTHORIZATION owner_name=id_ )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-external-resource-pool-transact-sql\ndrop_external_resource_pool\n    : DROP EXTERNAL RESOURCE POOL pool_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-external-table-transact-sql\ndrop_external_table\n    : DROP EXTERNAL TABLE (database_name=id_ DOT)? (schema_name=id_ DOT)? table=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-event-notification-transact-sql\ndrop_event_notifications\n    : DROP EVENT NOTIFICATION (COMMA? notification_name=id_)+\n        ON (SERVER|DATABASE|QUEUE queue_name=id_)\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-event-session-transact-sql\ndrop_event_session\n    : DROP EVENT SESSION event_session_name=id_\n        ON SERVER\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-fulltext-catalog-transact-sql\ndrop_fulltext_catalog\n    : DROP FULLTEXT CATALOG catalog_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-fulltext-index-transact-sql\ndrop_fulltext_index\n    : DROP FULLTEXT INDEX ON (schema=id_ DOT)? table=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-fulltext-stoplist-transact-sql\ndrop_fulltext_stoplist\n    : DROP FULLTEXT STOPLIST stoplist_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-login-transact-sql\ndrop_login\n    : DROP LOGIN login_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-master-key-transact-sql\ndrop_master_key\n    : DROP MASTER KEY\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-message-type-transact-sql\ndrop_message_type\n    : DROP MESSAGE TYPE message_type_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-partition-function-transact-sql\ndrop_partition_function\n    : DROP PARTITION FUNCTION partition_function_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-partition-scheme-transact-sql\ndrop_partition_scheme\n    : DROP PARTITION SCHEME partition_scheme_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-queue-transact-sql\ndrop_queue\n    : DROP QUEUE (database_name=id_ DOT)? (schema_name=id_ DOT)? queue_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-remote-service-binding-transact-sql\ndrop_remote_service_binding\n    : DROP REMOTE SERVICE BINDING binding_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-resource-pool-transact-sql\ndrop_resource_pool\n    : DROP RESOURCE POOL pool_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-role-transact-sql\ndrop_db_role\n    : DROP ROLE ( IF EXISTS )? role_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-route-transact-sql\ndrop_route\n    : DROP ROUTE route_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-rule-transact-sql\ndrop_rule\n    : DROP RULE ( IF EXISTS )? (COMMA? (schema_name=id_ DOT)? rule_name=id_)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-schema-transact-sql\ndrop_schema\n    :  DROP SCHEMA ( IF EXISTS )? schema_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-search-property-list-transact-sql\ndrop_search_property_list\n    : DROP SEARCH PROPERTY LIST property_list_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-security-policy-transact-sql\ndrop_security_policy\n    : DROP SECURITY POLICY ( IF EXISTS )? (schema_name=id_ DOT )? security_policy_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-sequence-transact-sql\ndrop_sequence\n    : DROP SEQUENCE ( IF EXISTS )? ( COMMA? (database_name=id_ DOT)? (schema_name=id_ DOT)?          sequence_name=id_ )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-server-audit-transact-sql\ndrop_server_audit\n    : DROP SERVER AUDIT audit_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-server-audit-specification-transact-sql\ndrop_server_audit_specification\n    : DROP SERVER AUDIT SPECIFICATION audit_specification_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-server-role-transact-sql\ndrop_server_role\n    : DROP SERVER ROLE role_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-service-transact-sql\ndrop_service\n    : DROP SERVICE dropped_service_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-signature-transact-sql\ndrop_signature\n    : DROP ( COUNTER )? SIGNATURE FROM (schema_name=id_ DOT)? module_name=id_\n        BY (COMMA?  CERTIFICATE cert_name=id_\n           | COMMA? ASYMMETRIC KEY Asym_key_name=id_\n           )+\n    ;\n\n\ndrop_statistics_name_azure_dw_and_pdw\n    :  DROP STATISTICS  (schema_name=id_ DOT)? object_name=id_ DOT statistics_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-symmetric-key-transact-sql\ndrop_symmetric_key\n    : DROP SYMMETRIC KEY symmetric_key_name=id_ (REMOVE PROVIDER KEY)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-synonym-transact-sql\ndrop_synonym\n    : DROP SYNONYM ( IF EXISTS )? ( schema=id_ DOT )? synonym_name=id_\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-user-transact-sql\ndrop_user\n    : DROP USER ( IF EXISTS )? user_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-workload-group-transact-sql\ndrop_workload_group\n    : DROP WORKLOAD GROUP group_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-xml-schema-collection-transact-sql\ndrop_xml_schema_collection\n    : DROP XML SCHEMA COLLECTION ( relational_schema=id_ DOT )?  sql_identifier=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/disable-trigger-transact-sql\ndisable_trigger\n    : DISABLE TRIGGER ( ( COMMA? (schema_name=id_ DOT)? trigger_name=id_ )+ | ALL)         ON ((schema_id=id_ DOT)? object_name=id_|DATABASE|ALL SERVER)\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/enable-trigger-transact-sql\nenable_trigger\n    : ENABLE TRIGGER ( ( COMMA? (schema_name=id_ DOT)? trigger_name=id_ )+ | ALL)         ON ( (schema_id=id_ DOT)? object_name=id_|DATABASE|ALL SERVER)\n    ;\n\nlock_table\n    : LOCK TABLE table_name IN (SHARE | EXCLUSIVE) MODE (WAIT seconds=DECIMAL | NOWAIT)? ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql\ntruncate_table\n    : TRUNCATE TABLE table_name\n          ( WITH LR_BRACKET\n              PARTITIONS LR_BRACKET\n                                (COMMA? (DECIMAL|DECIMAL TO DECIMAL) )+\n                         RR_BRACKET\n\n                 RR_BRACKET\n          )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-column-master-key-transact-sql\ncreate_column_master_key\n    : CREATE COLUMN MASTER KEY key_name=id_\n         WITH LR_BRACKET\n            KEY_STORE_PROVIDER_NAME EQUAL  key_store_provider_name=STRING COMMA\n            KEY_PATH EQUAL key_path=STRING\n           RR_BRACKET\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-credential-transact-sql\nalter_credential\n    : ALTER CREDENTIAL credential_name=id_\n        WITH IDENTITY EQUAL identity_name=STRING\n         ( COMMA SECRET EQUAL secret=STRING )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-credential-transact-sql\ncreate_credential\n    : CREATE CREDENTIAL credential_name=id_\n        WITH IDENTITY EQUAL identity_name=STRING\n         ( COMMA SECRET EQUAL secret=STRING )?\n         (  FOR CRYPTOGRAPHIC PROVIDER cryptographic_provider_name=id_ )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-cryptographic-provider-transact-sql\nalter_cryptographic_provider\n    : ALTER CRYPTOGRAPHIC PROVIDER provider_name=id_ (FROM FILE EQUAL crypto_provider_ddl_file=STRING)? (ENABLE | DISABLE)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-cryptographic-provider-transact-sql\ncreate_cryptographic_provider\n    : CREATE CRYPTOGRAPHIC PROVIDER provider_name=id_\n      FROM FILE EQUAL path_of_DLL=STRING\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/statements/create-endpoint-transact-sql?view=sql-server-ver16\ncreate_endpoint\n    : CREATE ENDPOINT endpointname=id_ (AUTHORIZATION login=id_)?\n            (STATE EQUAL state=(STARTED | STOPPED | DISABLED))?\n                AS TCP LR_BRACKET endpoint_listener_clause RR_BRACKET\n                ( FOR TSQL LR_BRACKET RR_BRACKET\n                | FOR SERVICE_BROKER LR_BRACKET\n                    endpoint_authentication_clause\n                    (COMMA? endpoint_encryption_alogorithm_clause)?\n                    (COMMA? MESSAGE_FORWARDING EQUAL (ENABLED | DISABLED))?\n                    (COMMA? MESSAGE_FORWARD_SIZE EQUAL DECIMAL)?\n                    RR_BRACKET\n                | FOR DATABASE_MIRRORING LR_BRACKET\n                    endpoint_authentication_clause\n                    (COMMA? endpoint_encryption_alogorithm_clause)?\n                    COMMA? ROLE EQUAL (WITNESS | PARTNER | ALL)\n                    RR_BRACKET\n                )\n    ;\n\nendpoint_encryption_alogorithm_clause\n    : ENCRYPTION EQUAL (DISABLED | SUPPORTED | REQUIRED) (ALGORITHM (AES RC4? | RC4 AES?))?\n    ;\n\nendpoint_authentication_clause\n    : AUTHENTICATION EQUAL\n        ( WINDOWS (NTLM | KERBEROS | NEGOTIATE)? (CERTIFICATE cert_name=id_)?\n        | CERTIFICATE cert_name=id_ WINDOWS? (NTLM | KERBEROS | NEGOTIATE)?\n        )\n    ;\n\nendpoint_listener_clause\n    : LISTENER_PORT EQUAL port=DECIMAL\n        (COMMA LISTENER_IP EQUAL (ALL | '(' (ipv4=IPV4_ADDR | ipv6=STRING) ')'))?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-event-notification-transact-sql\ncreate_event_notification\n    : CREATE EVENT NOTIFICATION event_notification_name=id_\n      ON (SERVER|DATABASE|QUEUE queue_name=id_)\n        (WITH FAN_IN)?\n        FOR (COMMA? event_type_or_group=id_)+\n          TO SERVICE  broker_service=STRING  COMMA\n             broker_service_specifier_or_current_database=STRING\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-event-session-transact-sql\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-event-session-transact-sql\n// todo: not implemented\ncreate_or_alter_event_session\n    : (CREATE | ALTER) EVENT SESSION event_session_name=id_ ON SERVER\n       (COMMA? ADD EVENT ( (event_module_guid=id_ DOT)? event_package_name=id_ DOT event_name=id_)\n        (LR_BRACKET\n          (SET ( COMMA? event_customizable_attributue=id_ EQUAL (DECIMAL|STRING) )* )?\n          ( ACTION LR_BRACKET (COMMA? (event_module_guid=id_ DOT)? event_package_name=id_ DOT action_name=id_)+  RR_BRACKET)+\n          (WHERE event_session_predicate_expression)?\n         RR_BRACKET )*\n      )*\n      (COMMA? DROP EVENT (event_module_guid=id_ DOT)? event_package_name=id_ DOT event_name=id_ )*\n\n      ( (ADD TARGET (event_module_guid=id_ DOT)? event_package_name=id_ DOT target_name=id_ ) ( LR_BRACKET SET (COMMA? target_parameter_name=id_ EQUAL (LR_BRACKET? DECIMAL RR_BRACKET? |STRING) )+ RR_BRACKET )* )*\n       (DROP TARGET (event_module_guid=id_ DOT)? event_package_name=id_ DOT target_name=id_ )*\n\n\n     (WITH\n           LR_BRACKET\n           (COMMA? MAX_MEMORY EQUAL max_memory=DECIMAL (KB|MB) )?\n           (COMMA? EVENT_RETENTION_MODE EQUAL (ALLOW_SINGLE_EVENT_LOSS | ALLOW_MULTIPLE_EVENT_LOSS | NO_EVENT_LOSS ) )?\n           (COMMA? MAX_DISPATCH_LATENCY EQUAL (max_dispatch_latency_seconds=DECIMAL SECONDS | INFINITE) )?\n           (COMMA?  MAX_EVENT_SIZE EQUAL max_event_size=DECIMAL (KB|MB) )?\n           (COMMA? MEMORY_PARTITION_MODE EQUAL (NONE | PER_NODE | PER_CPU) )?\n           (COMMA? TRACK_CAUSALITY EQUAL (ON|OFF) )?\n           (COMMA? STARTUP_STATE EQUAL (ON|OFF) )?\n           RR_BRACKET\n     )?\n     (STATE EQUAL (START|STOP) )?\n\n    ;\n\nevent_session_predicate_expression\n    : ( COMMA? (AND|OR)? NOT? ( event_session_predicate_factor | LR_BRACKET event_session_predicate_expression RR_BRACKET) )+\n    ;\n\nevent_session_predicate_factor\n    : event_session_predicate_leaf\n    | LR_BRACKET event_session_predicate_expression RR_BRACKET\n    ;\n\nevent_session_predicate_leaf\n    : (event_field_name=id_ | (event_field_name=id_ |( (event_module_guid=id_ DOT)?  event_package_name=id_ DOT predicate_source_name=id_ ) ) (EQUAL |(LESS GREATER) | (EXCLAMATION EQUAL) | GREATER  | (GREATER EQUAL)| LESS | LESS EQUAL) (DECIMAL | STRING) )\n    | (event_module_guid=id_ DOT)?  event_package_name=id_ DOT predicate_compare_name=id_ LR_BRACKET (event_field_name=id_ |( (event_module_guid=id_ DOT)?  event_package_name=id_ DOT predicate_source_name=id_ ) COMMA  (DECIMAL | STRING) ) RR_BRACKET\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-external-data-source-transact-sql\nalter_external_data_source\n    : ALTER EXTERNAL DATA SOURCE data_source_name=id_  SET\n    ( LOCATION EQUAL location=STRING COMMA? |  RESOURCE_MANAGER_LOCATION EQUAL resource_manager_location=STRING COMMA? |  CREDENTIAL EQUAL credential_name=id_ )+\n    | ALTER EXTERNAL DATA SOURCE data_source_name=id_ WITH LR_BRACKET TYPE EQUAL BLOB_STORAGE COMMA LOCATION EQUAL location=STRING (COMMA CREDENTIAL EQUAL credential_name=id_ )? RR_BRACKET\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-external-library-transact-sql\nalter_external_library\n    : ALTER EXTERNAL LIBRARY library_name=id_ (AUTHORIZATION owner_name=id_)?\n       (SET|ADD) ( LR_BRACKET CONTENT EQUAL (client_library=STRING | BINARY | NONE) (COMMA PLATFORM EQUAL (WINDOWS|LINUX)? RR_BRACKET) WITH (COMMA? LANGUAGE EQUAL (R|PYTHON) | DATA_SOURCE EQUAL external_data_source_name=id_ )+ RR_BRACKET )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-external-library-transact-sql\ncreate_external_library\n    : CREATE EXTERNAL LIBRARY library_name=id_ (AUTHORIZATION owner_name=id_)?\n       FROM (COMMA? LR_BRACKET?  (CONTENT EQUAL)? (client_library=STRING | BINARY | NONE) (COMMA PLATFORM EQUAL (WINDOWS|LINUX)? RR_BRACKET)? ) ( WITH (COMMA? LANGUAGE EQUAL (R|PYTHON) | DATA_SOURCE EQUAL external_data_source_name=id_ )+ RR_BRACKET  )?\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-external-resource-pool-transact-sql\nalter_external_resource_pool\n    : ALTER EXTERNAL RESOURCE POOL (pool_name=id_ | DEFAULT_DOUBLE_QUOTE) WITH LR_BRACKET MAX_CPU_PERCENT EQUAL max_cpu_percent=DECIMAL ( COMMA? AFFINITY CPU EQUAL (AUTO|(COMMA? DECIMAL TO DECIMAL |COMMA DECIMAL )+ ) | NUMANODE EQUAL (COMMA? DECIMAL TO DECIMAL| COMMA? DECIMAL )+  ) (COMMA? MAX_MEMORY_PERCENT EQUAL max_memory_percent=DECIMAL)? (COMMA? MAX_PROCESSES EQUAL max_processes=DECIMAL)?  RR_BRACKET\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-external-resource-pool-transact-sql\ncreate_external_resource_pool\n    : CREATE EXTERNAL RESOURCE POOL pool_name=id_  WITH LR_BRACKET MAX_CPU_PERCENT EQUAL max_cpu_percent=DECIMAL ( COMMA? AFFINITY CPU EQUAL (AUTO|(COMMA? DECIMAL TO DECIMAL |COMMA DECIMAL )+ ) | NUMANODE EQUAL (COMMA? DECIMAL TO DECIMAL| COMMA? DECIMAL )+  ) (COMMA? MAX_MEMORY_PERCENT EQUAL max_memory_percent=DECIMAL)? (COMMA? MAX_PROCESSES EQUAL max_processes=DECIMAL)?  RR_BRACKET\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-fulltext-catalog-transact-sql\nalter_fulltext_catalog\n    : ALTER FULLTEXT CATALOG catalog_name=id_ (REBUILD (WITH ACCENT_SENSITIVITY EQUAL (ON|OFF) )? | REORGANIZE | AS DEFAULT )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-fulltext-catalog-transact-sql\ncreate_fulltext_catalog\n    : CREATE FULLTEXT CATALOG catalog_name=id_\n        (ON FILEGROUP filegroup=id_)?\n        (IN PATH rootpath=STRING)?\n        (WITH ACCENT_SENSITIVITY EQUAL (ON|OFF) )?\n        (AS DEFAULT)?\n        (AUTHORIZATION owner_name=id_)?\n    ;\n\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-fulltext-stoplist-transact-sql\nalter_fulltext_stoplist\n    : ALTER FULLTEXT STOPLIST stoplist_name=id_ (ADD stopword=STRING LANGUAGE (STRING|DECIMAL|BINARY) | DROP ( stopword=STRING LANGUAGE (STRING|DECIMAL|BINARY) |ALL (STRING|DECIMAL|BINARY) | ALL ) )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-fulltext-stoplist-transact-sql\ncreate_fulltext_stoplist\n    :   CREATE FULLTEXT STOPLIST stoplist_name=id_\n          (FROM ( (database_name=id_ DOT)? source_stoplist_name=id_ |SYSTEM STOPLIST ) )?\n          (AUTHORIZATION owner_name=id_)?\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-login-transact-sql\nalter_login_sql_server\n    : ALTER LOGIN login_name=id_\n       ( (ENABLE|DISABLE)?  | WITH ( (PASSWORD EQUAL ( password=STRING | password_hash=BINARY HASHED ) ) (MUST_CHANGE|UNLOCK)* )? (OLD_PASSWORD EQUAL old_password=STRING (MUST_CHANGE|UNLOCK)* )? (DEFAULT_DATABASE EQUAL default_database=id_)? (DEFAULT_LANGUAGE EQUAL default_laguage=id_)?  (NAME EQUAL login_name=id_)? (CHECK_POLICY EQUAL (ON|OFF) )? (CHECK_EXPIRATION EQUAL (ON|OFF) )? (CREDENTIAL EQUAL credential_name=id_)? (NO CREDENTIAL)? | (ADD|DROP) CREDENTIAL credential_name=id_ )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-login-transact-sql\ncreate_login_sql_server\n    : CREATE LOGIN login_name=id_\n       ( WITH ( (PASSWORD EQUAL ( password=STRING | password_hash=BINARY HASHED ) ) (MUST_CHANGE|UNLOCK)* )?\n       (COMMA? SID EQUAL sid=BINARY)?\n       (COMMA? DEFAULT_DATABASE EQUAL default_database=id_)?\n       (COMMA? DEFAULT_LANGUAGE EQUAL default_laguage=id_)?\n       (COMMA? CHECK_EXPIRATION EQUAL (ON|OFF) )?\n       (COMMA? CHECK_POLICY EQUAL (ON|OFF) )?\n       (COMMA? CREDENTIAL EQUAL credential_name=id_)?\n      |(FROM\n    (WINDOWS\n          (WITH (COMMA? DEFAULT_DATABASE EQUAL default_database=id_)? (COMMA?  DEFAULT_LANGUAGE EQUAL default_language=STRING)? )\n        | CERTIFICATE certname=id_\n        | ASYMMETRIC KEY asym_key_name=id_\n                )\n        )\n      )\n    ;\n\nalter_login_azure_sql\n    : ALTER LOGIN login_name=id_ ( (ENABLE|DISABLE)? | WITH (PASSWORD EQUAL password=STRING (OLD_PASSWORD EQUAL old_password=STRING)? | NAME EQUAL login_name=id_ ) )\n    ;\n\ncreate_login_azure_sql\n    : CREATE LOGIN login_name=id_\n       WITH PASSWORD EQUAL STRING (SID EQUAL sid=BINARY)?\n    ;\n\nalter_login_azure_sql_dw_and_pdw\n    : ALTER LOGIN login_name=id_ ( (ENABLE|DISABLE)? | WITH (PASSWORD EQUAL password=STRING (OLD_PASSWORD EQUAL old_password=STRING (MUST_CHANGE|UNLOCK)* )? | NAME EQUAL login_name=id_ ) )\n    ;\n\ncreate_login_pdw\n    : CREATE LOGIN loginName=id_\n        (WITH\n          ( PASSWORD EQUAL password=STRING (MUST_CHANGE)?\n              (CHECK_POLICY EQUAL (ON|OFF)? )?\n          )\n        | FROM WINDOWS\n        )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-master-key-transact-sql\nalter_master_key_sql_server\n    : ALTER MASTER KEY ( (FORCE)? REGENERATE WITH ENCRYPTION BY PASSWORD EQUAL password=STRING |(ADD|DROP) ENCRYPTION BY (SERVICE MASTER KEY | PASSWORD EQUAL encryption_password=STRING) )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-master-key-transact-sql\ncreate_master_key_sql_server\n    : CREATE MASTER KEY ENCRYPTION BY PASSWORD EQUAL password=STRING\n    ;\n\nalter_master_key_azure_sql\n    : ALTER MASTER KEY ( (FORCE)? REGENERATE WITH ENCRYPTION BY PASSWORD EQUAL password=STRING |ADD ENCRYPTION BY (SERVICE MASTER KEY | PASSWORD EQUAL encryption_password=STRING) | DROP ENCRYPTION BY  PASSWORD EQUAL encryption_password=STRING )\n    ;\n\ncreate_master_key_azure_sql\n    : CREATE MASTER KEY (ENCRYPTION BY PASSWORD EQUAL password=STRING)?\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-message-type-transact-sql\nalter_message_type\n    : ALTER MESSAGE TYPE message_type_name=id_ VALIDATION EQUAL (NONE | EMPTY | WELL_FORMED_XML | VALID_XML WITH SCHEMA COLLECTION schema_collection_name=id_)\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-partition-function-transact-sql\nalter_partition_function\n    : ALTER PARTITION FUNCTION partition_function_name=id_ LR_BRACKET RR_BRACKET        (SPLIT|MERGE) RANGE LR_BRACKET DECIMAL RR_BRACKET\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-partition-scheme-transact-sql\nalter_partition_scheme\n    : ALTER PARTITION SCHEME partition_scheme_name=id_ NEXT USED (file_group_name=id_)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-remote-service-binding-transact-sql\nalter_remote_service_binding\n    : ALTER REMOTE SERVICE BINDING binding_name=id_\n        WITH (USER EQUAL user_name=id_)?\n             (COMMA ANONYMOUS EQUAL (ON|OFF) )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-remote-service-binding-transact-sql\ncreate_remote_service_binding\n    : CREATE REMOTE SERVICE BINDING binding_name=id_\n         (AUTHORIZATION owner_name=id_)?\n         TO SERVICE remote_service_name=STRING\n         WITH (USER EQUAL user_name=id_)?\n              (COMMA ANONYMOUS EQUAL (ON|OFF) )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-resource-pool-transact-sql\ncreate_resource_pool\n    : CREATE RESOURCE POOL pool_name=id_\n        (WITH\n            LR_BRACKET\n               (COMMA? MIN_CPU_PERCENT EQUAL DECIMAL)?\n               (COMMA? MAX_CPU_PERCENT EQUAL DECIMAL)?\n               (COMMA? CAP_CPU_PERCENT EQUAL DECIMAL)?\n               (COMMA? AFFINITY SCHEDULER EQUAL\n                                  (AUTO\n                                   | LR_BRACKET (COMMA? (DECIMAL|DECIMAL TO DECIMAL) )+ RR_BRACKET\n                                   | NUMANODE EQUAL LR_BRACKET (COMMA? (DECIMAL|DECIMAL TO DECIMAL) )+ RR_BRACKET\n                                   )\n               )?\n               (COMMA? MIN_MEMORY_PERCENT EQUAL DECIMAL)?\n               (COMMA? MAX_MEMORY_PERCENT EQUAL DECIMAL)?\n               (COMMA? MIN_IOPS_PER_VOLUME EQUAL DECIMAL)?\n               (COMMA? MAX_IOPS_PER_VOLUME EQUAL DECIMAL)?\n            RR_BRACKET\n         )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-resource-governor-transact-sql\nalter_resource_governor\n    : ALTER RESOURCE GOVERNOR ( (DISABLE | RECONFIGURE) | WITH LR_BRACKET CLASSIFIER_FUNCTION EQUAL ( schema_name=id_ DOT function_name=id_ | NULL_ ) RR_BRACKET | RESET STATISTICS | WITH LR_BRACKET MAX_OUTSTANDING_IO_PER_VOLUME EQUAL max_outstanding_io_per_volume=DECIMAL RR_BRACKET )\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-audit-specification-transact-sql?view=sql-server-ver16\nalter_database_audit_specification\n    : ALTER DATABASE AUDIT SPECIFICATION audit_specification_name=id_\n        (FOR SERVER AUDIT audit_name=id_)?\n        (audit_action_spec_group (',' audit_action_spec_group)*)?\n        (WITH '(' STATE '=' (ON|OFF) ')')?\n    ;\n\naudit_action_spec_group\n    : (ADD|DROP) '(' (audit_action_specification | audit_action_group_name=id_) ')'\n    ;\n\naudit_action_specification\n    : action_specification (',' action_specification)* ON (audit_class_name '::')? audit_securable BY principal_id (',' principal_id)*\n    ;\n\naction_specification\n    : SELECT\n    | INSERT\n    | UPDATE\n    | DELETE\n    | EXECUTE\n    | RECEIVE\n    | REFERENCES\n    ;\n\naudit_class_name\n    : OBJECT\n    | SCHEMA\n    | TABLE\n    ;\n\naudit_securable\n    : ((id_ '.')? id_ '.')? id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-role-transact-sql\nalter_db_role\n    : ALTER ROLE role_name=id_\n        ( (ADD|DROP) MEMBER database_principal=id_\n        | WITH NAME EQUAL new_role_name=id_ )\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/statements/create-database-audit-specification-transact-sql?view=sql-server-ver16\ncreate_database_audit_specification\n    : CREATE DATABASE AUDIT SPECIFICATION audit_specification_name=id_\n         (FOR SERVER AUDIT audit_name=id_)?\n         (audit_action_spec_group (',' audit_action_spec_group)*)?\n         (WITH '(' STATE '=' (ON|OFF) ')')?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-role-transact-sql\ncreate_db_role\n    : CREATE ROLE role_name=id_ (AUTHORIZATION owner_name = id_)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-route-transact-sql\ncreate_route\n    : CREATE ROUTE route_name=id_\n        (AUTHORIZATION owner_name=id_)?\n        WITH\n          (COMMA? SERVICE_NAME EQUAL route_service_name=STRING)?\n          (COMMA? BROKER_INSTANCE EQUAL broker_instance_identifier=STRING)?\n          (COMMA? LIFETIME EQUAL DECIMAL)?\n          COMMA? ADDRESS EQUAL STRING\n          (COMMA MIRROR_ADDRESS EQUAL STRING )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-rule-transact-sql\ncreate_rule\n    : CREATE RULE (schema_name=id_ DOT)? rule_name=id_\n        AS search_condition\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-schema-transact-sql\nalter_schema_sql\n    : ALTER SCHEMA schema_name=id_ TRANSFER ((OBJECT|TYPE|XML SCHEMA COLLECTION) DOUBLE_COLON )? id_ (DOT id_)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-schema-transact-sql\ncreate_schema\n    : CREATE SCHEMA\n    (schema_name=id_\n        |AUTHORIZATION owner_name=id_\n        | schema_name=id_ AUTHORIZATION owner_name=id_\n        )\n        (create_table\n         |create_view\n         | (GRANT|DENY) (SELECT|INSERT|DELETE|UPDATE) ON (SCHEMA DOUBLE_COLON)? object_name=id_ TO owner_name=id_\n         | REVOKE (SELECT|INSERT|DELETE|UPDATE) ON (SCHEMA DOUBLE_COLON)? object_name=id_ FROM owner_name=id_\n        )*\n    ;\n\ncreate_schema_azure_sql_dw_and_pdw\n    :\nCREATE SCHEMA schema_name=id_ (AUTHORIZATION owner_name=id_ )?\n    ;\n\nalter_schema_azure_sql_dw_and_pdw\n    : ALTER SCHEMA schema_name=id_ TRANSFER (OBJECT DOUBLE_COLON )? id_ (DOT ID)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-search-property-list-transact-sql\ncreate_search_property_list\n    : CREATE SEARCH PROPERTY LIST new_list_name=id_\n        (FROM (database_name=id_ DOT)? source_list_name=id_ )?\n        (AUTHORIZATION owner_name=id_)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-security-policy-transact-sql\ncreate_security_policy\n   : CREATE SECURITY POLICY (schema_name=id_ DOT)? security_policy_name=id_\n        (COMMA? ADD (FILTER|BLOCK)? PREDICATE tvf_schema_name=id_ DOT security_predicate_function_name=id_\n            LR_BRACKET (COMMA? column_name_or_arguments=id_)+ RR_BRACKET\n              ON table_schema_name=id_ DOT name=id_\n                (COMMA? AFTER (INSERT|UPDATE)\n                | COMMA? BEFORE (UPDATE|DELETE)\n                )*\n         )+\n            (WITH LR_BRACKET\n                     STATE EQUAL (ON|OFF)\n             (SCHEMABINDING (ON|OFF) )?\n                  RR_BRACKET\n             )?\n             (NOT FOR REPLICATION)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-sequence-transact-sql\nalter_sequence\n    : ALTER SEQUENCE (schema_name=id_ DOT)? sequence_name=id_ ( RESTART (WITH DECIMAL)? )? (INCREMENT BY sequnce_increment=DECIMAL )? ( MINVALUE DECIMAL| NO MINVALUE)? (MAXVALUE DECIMAL| NO MAXVALUE)? (CYCLE|NO CYCLE)? (CACHE DECIMAL | NO CACHE)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-sequence-transact-sql\ncreate_sequence\n    : CREATE SEQUENCE (schema_name=id_ DOT)? sequence_name=id_\n        (AS data_type  )?\n        (START WITH DECIMAL)?\n        (INCREMENT BY MINUS? DECIMAL)?\n        (MINVALUE (MINUS? DECIMAL)? | NO MINVALUE)?\n        (MAXVALUE (MINUS? DECIMAL)? | NO MAXVALUE)?\n        (CYCLE|NO CYCLE)?\n        (CACHE DECIMAL? | NO CACHE)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-server-audit-transact-sql\nalter_server_audit\n    : ALTER SERVER AUDIT audit_name=id_\n        ( ( TO\n              (FILE\n                ( LR_BRACKET\n                   ( COMMA? FILEPATH EQUAL filepath=STRING\n                    | COMMA? MAXSIZE EQUAL ( DECIMAL (MB|GB|TB)\n                    |  UNLIMITED\n                   )\n                   | COMMA? MAX_ROLLOVER_FILES EQUAL max_rollover_files=(DECIMAL|UNLIMITED)\n                   | COMMA? MAX_FILES EQUAL max_files=DECIMAL\n                   | COMMA? RESERVE_DISK_SPACE EQUAL (ON|OFF)  )*\n                 RR_BRACKET )\n                | APPLICATION_LOG\n                | SECURITY_LOG\n            ) )?\n            ( WITH LR_BRACKET\n              (COMMA? QUEUE_DELAY EQUAL queue_delay=DECIMAL\n              | COMMA? ON_FAILURE EQUAL (CONTINUE | SHUTDOWN|FAIL_OPERATION)\n              |COMMA?  STATE EQUAL (ON|OFF) )*\n              RR_BRACKET\n            )?\n            ( WHERE ( COMMA? (NOT?) event_field_name=id_\n                                    (EQUAL\n                                    |(LESS GREATER)\n                                    | (EXCLAMATION EQUAL)\n                                    | GREATER\n                                    | (GREATER EQUAL)\n                                    | LESS\n                                    | LESS EQUAL\n                                    )\n                                      (DECIMAL | STRING)\n                    | COMMA? (AND|OR) NOT? (EQUAL\n                                           |(LESS GREATER)\n                                           | (EXCLAMATION EQUAL)\n                                           | GREATER\n                                           | (GREATER EQUAL)\n                                           | LESS\n                                           | LESS EQUAL)\n                                             (DECIMAL | STRING) ) )?\n        |REMOVE WHERE\n        | MODIFY NAME EQUAL new_audit_name=id_\n       )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-server-audit-transact-sql\ncreate_server_audit\n    : CREATE SERVER AUDIT audit_name=id_\n        ( ( TO\n              (FILE\n                ( LR_BRACKET\n                   ( COMMA? FILEPATH EQUAL filepath=STRING\n                    | COMMA? MAXSIZE EQUAL ( DECIMAL (MB|GB|TB)\n                    |  UNLIMITED\n                   )\n                   | COMMA? MAX_ROLLOVER_FILES EQUAL max_rollover_files=(DECIMAL|UNLIMITED)\n                   | COMMA? MAX_FILES EQUAL max_files=DECIMAL\n                   | COMMA? RESERVE_DISK_SPACE EQUAL (ON|OFF)  )*\n                 RR_BRACKET )\n                | APPLICATION_LOG\n                | SECURITY_LOG\n            ) )?\n            ( WITH LR_BRACKET\n              (COMMA? QUEUE_DELAY EQUAL queue_delay=DECIMAL\n              | COMMA? ON_FAILURE EQUAL (CONTINUE | SHUTDOWN|FAIL_OPERATION)\n              |COMMA?  STATE EQUAL (ON|OFF)\n              |COMMA? AUDIT_GUID EQUAL audit_guid=id_\n            )*\n\n              RR_BRACKET\n            )?\n            ( WHERE ( COMMA? (NOT?) event_field_name=id_\n                                    (EQUAL\n                                    |(LESS GREATER)\n                                    | (EXCLAMATION EQUAL)\n                                    | GREATER\n                                    | (GREATER EQUAL)\n                                    | LESS\n                                    | LESS EQUAL\n                                    )\n                                      (DECIMAL | STRING)\n                    | COMMA? (AND|OR) NOT? (EQUAL\n                                           |(LESS GREATER)\n                                           | (EXCLAMATION EQUAL)\n                                           | GREATER\n                                           | (GREATER EQUAL)\n                                           | LESS\n                                           | LESS EQUAL)\n                                             (DECIMAL | STRING) ) )?\n        |REMOVE WHERE\n        | MODIFY NAME EQUAL new_audit_name=id_\n       )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-server-audit-specification-transact-sql\n\nalter_server_audit_specification\n    : ALTER SERVER AUDIT SPECIFICATION audit_specification_name=id_\n       (FOR SERVER AUDIT audit_name=id_)?\n       ( (ADD|DROP) LR_BRACKET  audit_action_group_name=id_ RR_BRACKET )*\n         (WITH LR_BRACKET STATE EQUAL (ON|OFF) RR_BRACKET )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-server-audit-specification-transact-sql\ncreate_server_audit_specification\n    : CREATE SERVER AUDIT SPECIFICATION audit_specification_name=id_\n       (FOR SERVER AUDIT audit_name=id_)?\n       ( ADD LR_BRACKET  audit_action_group_name=id_ RR_BRACKET )*\n         (WITH LR_BRACKET STATE EQUAL (ON|OFF) RR_BRACKET )?\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-server-configuration-transact-sql\n\nalter_server_configuration\n    : ALTER SERVER CONFIGURATION\n      SET  ( (PROCESS AFFINITY (CPU EQUAL (AUTO | (COMMA? DECIMAL | COMMA? DECIMAL TO DECIMAL)+ ) | NUMANODE EQUAL ( COMMA? DECIMAL |COMMA?  DECIMAL TO DECIMAL)+ ) | DIAGNOSTICS LOG (ON|OFF|PATH EQUAL (STRING | DEFAULT) |MAX_SIZE EQUAL (DECIMAL MB |DEFAULT)|MAX_FILES EQUAL (DECIMAL|DEFAULT) ) | FAILOVER CLUSTER PROPERTY (VERBOSELOGGING EQUAL (STRING|DEFAULT) |SQLDUMPERFLAGS EQUAL (STRING|DEFAULT) | SQLDUMPERPATH EQUAL (STRING|DEFAULT) | SQLDUMPERTIMEOUT (STRING|DEFAULT) | FAILURECONDITIONLEVEL EQUAL (STRING|DEFAULT) | HEALTHCHECKTIMEOUT EQUAL (DECIMAL|DEFAULT) ) | HADR CLUSTER CONTEXT EQUAL (STRING|LOCAL) | BUFFER POOL EXTENSION (ON LR_BRACKET FILENAME EQUAL STRING COMMA SIZE EQUAL DECIMAL (KB|MB|GB)  RR_BRACKET | OFF ) | SET SOFTNUMA (ON|OFF) ) )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-server-role-transact-sql\nalter_server_role\n    : ALTER SERVER ROLE server_role_name=id_\n      ( (ADD|DROP) MEMBER server_principal=id_\n      | WITH NAME EQUAL new_server_role_name=id_\n      )\n    ;\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-server-role-transact-sql\ncreate_server_role\n    : CREATE SERVER ROLE server_role=id_ (AUTHORIZATION server_principal=id_)?\n    ;\n\nalter_server_role_pdw\n    : ALTER SERVER ROLE server_role_name=id_ (ADD|DROP) MEMBER login=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-service-transact-sql\nalter_service\n    : ALTER SERVICE modified_service_name=id_ (ON QUEUE (schema_name=id_ DOT)? queue_name=id_)?  ('(' opt_arg_clause (COMMA opt_arg_clause)* ')')?\n    ;\n\nopt_arg_clause\n    : (ADD|DROP) CONTRACT modified_contract_name=id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-service-transact-sql\ncreate_service\n    : CREATE SERVICE create_service_name=id_\n        (AUTHORIZATION owner_name=id_)?\n        ON QUEUE (schema_name=id_ DOT)? queue_name=id_\n          ( LR_BRACKET (COMMA? (id_|DEFAULT) )+ RR_BRACKET )?\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-service-master-key-transact-sql\n\nalter_service_master_key\n    : ALTER SERVICE MASTER KEY ( FORCE? REGENERATE | (WITH (OLD_ACCOUNT EQUAL acold_account_name=STRING COMMA OLD_PASSWORD EQUAL old_password=STRING | NEW_ACCOUNT EQUAL new_account_name=STRING COMMA NEW_PASSWORD EQUAL new_password=STRING)?  ) )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-symmetric-key-transact-sql\n\nalter_symmetric_key\n    : ALTER SYMMETRIC KEY key_name=id_ ( (ADD|DROP) ENCRYPTION BY (CERTIFICATE certificate_name=id_ | PASSWORD EQUAL password=STRING | SYMMETRIC KEY symmetric_key_name=id_ | ASYMMETRIC KEY Asym_key_name=id_  ) )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-synonym-transact-sql\ncreate_synonym\n    : CREATE SYNONYM (schema_name_1=id_ DOT )? synonym_name=id_\n        FOR ( (server_name=id_ DOT )? (database_name=id_ DOT)? (schema_name_2=id_ DOT)? object_name=id_\n            | (database_or_schema2=id_ DOT)? (schema_id_2_or_object_name=id_ DOT)?\n            )\n    ;\n\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-user-transact-sql\nalter_user\n    : ALTER USER username=id_ WITH (COMMA? NAME EQUAL newusername=id_ | COMMA? DEFAULT_SCHEMA EQUAL ( schema_name=id_ |NULL_ ) | COMMA? LOGIN EQUAL loginame=id_ | COMMA? PASSWORD EQUAL STRING (OLD_PASSWORD EQUAL STRING)+ | COMMA? DEFAULT_LANGUAGE EQUAL (NONE| lcid=DECIMAL| language_name_or_alias=id_) | COMMA? ALLOW_ENCRYPTED_VALUE_MODIFICATIONS EQUAL (ON|OFF) )+\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-user-transact-sql\ncreate_user\n    : CREATE USER user_name=id_\n         (  (FOR|FROM) LOGIN login_name=id_ )?\n         ( WITH (COMMA? DEFAULT_SCHEMA EQUAL schema_name=id_\n                |COMMA? ALLOW_ENCRYPTED_VALUE_MODIFICATIONS EQUAL (ON|OFF)\n                )*\n         )?\n    | CREATE USER   ( windows_principal=id_\n                      (WITH\n                        (COMMA? DEFAULT_SCHEMA EQUAL schema_name=id_\n                        |COMMA? DEFAULT_LANGUAGE EQUAL (NONE\n                                                |DECIMAL\n                                                |language_name_or_alias=id_                                                      )\n                        |COMMA? SID EQUAL BINARY\n                        |COMMA? ALLOW_ENCRYPTED_VALUE_MODIFICATIONS EQUAL (ON|OFF)\n                        )*\n                      )?\n                   | user_name=id_ WITH PASSWORD EQUAL password=STRING\n                            (COMMA? DEFAULT_SCHEMA EQUAL schema_name=id_\n                            |COMMA? DEFAULT_LANGUAGE EQUAL (NONE\n                                                |DECIMAL\n                                                |language_name_or_alias=id_                                                      )\n                            |COMMA? SID EQUAL BINARY\n                           |COMMA? ALLOW_ENCRYPTED_VALUE_MODIFICATIONS EQUAL (ON|OFF)\n                          )*\n                   | Azure_Active_Directory_principal=id_ FROM EXTERNAL PROVIDER\n                   )\n    | CREATE USER user_name=id_\n                 ( WITHOUT LOGIN\n                   (COMMA? DEFAULT_SCHEMA EQUAL schema_name=id_\n                   |COMMA? ALLOW_ENCRYPTED_VALUE_MODIFICATIONS EQUAL (ON|OFF)\n                   )*\n                 | (FOR|FROM) CERTIFICATE cert_name=id_\n                 | (FOR|FROM) ASYMMETRIC KEY asym_key_name=id_\n                 )\n    | CREATE USER user_name=id_\n    ;\n\ncreate_user_azure_sql_dw\n    : CREATE USER user_name=id_\n        ( (FOR|FROM) LOGIN login_name=id_\n        | WITHOUT LOGIN\n        )?\n\n        ( WITH DEFAULT_SCHEMA EQUAL schema_name=id_)?\n    | CREATE USER Azure_Active_Directory_principal=id_\n        FROM EXTERNAL PROVIDER\n        ( WITH DEFAULT_SCHEMA EQUAL schema_name=id_)?\n    ;\n\n\nalter_user_azure_sql\n    : ALTER USER username=id_ WITH (COMMA? NAME EQUAL newusername=id_ | COMMA? DEFAULT_SCHEMA EQUAL  schema_name=id_ | COMMA? LOGIN EQUAL loginame=id_  | COMMA? ALLOW_ENCRYPTED_VALUE_MODIFICATIONS EQUAL (ON|OFF) )+\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-workload-group-transact-sql\n\nalter_workload_group\n    : ALTER WORKLOAD GROUP\n         (workload_group_group_name=id_\n         |DEFAULT_DOUBLE_QUOTE\n         )\n         (WITH LR_BRACKET\n           (IMPORTANCE EQUAL (LOW|MEDIUM|HIGH)\n           | COMMA? REQUEST_MAX_MEMORY_GRANT_PERCENT EQUAL request_max_memory_grant=DECIMAL\n           | COMMA? REQUEST_MAX_CPU_TIME_SEC EQUAL request_max_cpu_time_sec=DECIMAL\n           | REQUEST_MEMORY_GRANT_TIMEOUT_SEC EQUAL request_memory_grant_timeout_sec=DECIMAL\n           | MAX_DOP EQUAL max_dop=DECIMAL\n           | GROUP_MAX_REQUESTS EQUAL group_max_requests=DECIMAL)+\n          RR_BRACKET )?\n     (USING (workload_group_pool_name=id_ | DEFAULT_DOUBLE_QUOTE) )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-workload-group-transact-sql\ncreate_workload_group\n    : CREATE WORKLOAD GROUP workload_group_group_name=id_\n         (WITH LR_BRACKET\n           (IMPORTANCE EQUAL (LOW|MEDIUM|HIGH)\n           | COMMA? REQUEST_MAX_MEMORY_GRANT_PERCENT EQUAL request_max_memory_grant=DECIMAL\n           | COMMA? REQUEST_MAX_CPU_TIME_SEC EQUAL request_max_cpu_time_sec=DECIMAL\n           | REQUEST_MEMORY_GRANT_TIMEOUT_SEC EQUAL request_memory_grant_timeout_sec=DECIMAL\n           | MAX_DOP EQUAL max_dop=DECIMAL\n           | GROUP_MAX_REQUESTS EQUAL group_max_requests=DECIMAL)+\n          RR_BRACKET )?\n     (USING (workload_group_pool_name=id_ | DEFAULT_DOUBLE_QUOTE)?\n            (COMMA? EXTERNAL external_pool_name=id_ | DEFAULT_DOUBLE_QUOTE)?\n      )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-xml-schema-collection-transact-sql\ncreate_xml_schema_collection\n    : CREATE XML SCHEMA COLLECTION (relational_schema=id_ DOT)? sql_identifier=id_ AS  (STRING|id_|LOCAL_ID)\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-partition-function-transact-sql?view=sql-server-ver15\ncreate_partition_function\n    : CREATE PARTITION FUNCTION partition_function_name=id_ '(' input_parameter_type=data_type ')'\n      AS RANGE ( LEFT | RIGHT )?\n      FOR VALUES '(' boundary_values=expression_list_ ')'\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-partition-scheme-transact-sql?view=sql-server-ver15\ncreate_partition_scheme\n    : CREATE PARTITION SCHEME partition_scheme_name=id_\n      AS PARTITION partition_function_name=id_\n      ALL? TO '(' file_group_names+=id_ (',' file_group_names+=id_)* ')'\n    ;\n\ncreate_queue\n    : CREATE QUEUE (full_table_name | queue_name=id_) queue_settings?\n      (ON filegroup=id_ | DEFAULT)?\n    ;\n\n\nqueue_settings\n    : WITH\n       (STATUS EQUAL on_off COMMA?)?\n       (RETENTION EQUAL on_off COMMA?)?\n       (ACTIVATION\n         LR_BRACKET\n           (\n             (\n              (STATUS EQUAL on_off COMMA? )?\n              (PROCEDURE_NAME EQUAL func_proc_name_database_schema COMMA?)?\n              (MAX_QUEUE_READERS EQUAL max_readers=DECIMAL COMMA?)?\n              (EXECUTE AS (SELF | user_name=STRING | OWNER) COMMA?)?\n             )\n             | DROP\n           )\n         RR_BRACKET COMMA?\n       )?\n       (POISON_MESSAGE_HANDLING\n         LR_BRACKET\n           (STATUS EQUAL on_off)\n         RR_BRACKET\n       )?\n    ;\n\nalter_queue\n    : ALTER QUEUE (full_table_name | queue_name=id_)\n      (queue_settings | queue_action)\n    ;\n\nqueue_action\n    : REBUILD ( WITH LR_BRACKET queue_rebuild_options RR_BRACKET)?\n    | REORGANIZE (WITH LOB_COMPACTION EQUAL on_off)?\n    | MOVE TO (id_ | DEFAULT)\n    ;\nqueue_rebuild_options\n    : MAXDOP EQUAL DECIMAL\n    ;\n\ncreate_contract\n    : CREATE CONTRACT contract_name\n      (AUTHORIZATION owner_name=id_)?\n      LR_BRACKET ((message_type_name=id_ | DEFAULT)\n          SENT BY (INITIATOR | TARGET | ANY ) COMMA?)+\n      RR_BRACKET\n    ;\n\nconversation_statement\n    : begin_conversation_timer\n    | begin_conversation_dialog\n    | end_conversation\n    | get_conversation\n    | send_conversation\n    | waitfor_conversation\n    ;\n\nmessage_statement\n    : CREATE MESSAGE TYPE message_type_name=id_\n      (AUTHORIZATION owner_name=id_)?\n      (VALIDATION EQUAL (NONE\n      | EMPTY\n      | WELL_FORMED_XML\n      | VALID_XML WITH SCHEMA COLLECTION schema_collection_name=id_))\n    ;\n\n// DML\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql\n// note that there's a limit on number of when_matches but it has to be done runtime due to different ordering of statements allowed\nmerge_statement\n    : with_expression?\n      MERGE (TOP '(' expression ')' PERCENT?)?\n      INTO? ddl_object with_table_hints? as_table_alias?\n      USING table_sources\n      ON search_condition\n      when_matches+\n      output_clause?\n      option_clause? ';'\n    ;\n\nwhen_matches\n    : (WHEN MATCHED (AND search_condition)?\n          THEN merge_matched)+\n    | (WHEN NOT MATCHED (BY TARGET)? (AND search_condition)?\n          THEN merge_not_matched)\n    | (WHEN NOT MATCHED BY SOURCE (AND search_condition)?\n          THEN merge_matched)+\n    ;\n\nmerge_matched\n    : UPDATE SET update_elem_merge (',' update_elem_merge)*\n    | DELETE\n    ;\n\nmerge_not_matched\n    : INSERT ('(' column_name_list ')')?\n      (table_value_constructor | DEFAULT VALUES)\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms189835.aspx\ndelete_statement\n    : with_expression?\n      DELETE (TOP '(' expression ')' PERCENT? | TOP DECIMAL)?\n      FROM? delete_statement_from\n      with_table_hints?\n      output_clause?\n      (FROM table_sources)?\n      (WHERE (search_condition | CURRENT OF (GLOBAL? cursor_name | cursor_var=LOCAL_ID)))?\n      for_clause? option_clause? ';'?\n    ;\n\ndelete_statement_from\n    : ddl_object\n    | rowset_function_limited\n    | table_var=LOCAL_ID\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms174335.aspx\ninsert_statement\n    : with_expression?\n      INSERT (TOP '(' expression ')' PERCENT?)?\n      INTO? (ddl_object | rowset_function_limited)\n      with_table_hints?\n      ('(' insert_column_name_list ')')?\n      output_clause?\n      insert_statement_value\n      for_clause? option_clause? ';'?\n    ;\n\ninsert_statement_value\n    : table_value_constructor\n    | derived_table\n    | execute_statement\n    | DEFAULT VALUES\n    ;\n\n\nreceive_statement\n    : '('? RECEIVE (ALL | DISTINCT | top_clause | '*')\n      (LOCAL_ID '=' expression ','?)* FROM full_table_name\n      (INTO table_variable=id_ (WHERE where=search_condition))? ')'?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms189499.aspx\nselect_statement_standalone\n    : with_expression? select_statement\n    ;\n\nselect_statement\n    : query_expression select_order_by_clause? for_clause? option_clause? ';'?\n    ;\n\ntime\n    : (LOCAL_ID | constant)\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms177523.aspx\nupdate_statement\n    : with_expression?\n      UPDATE (TOP '(' expression ')' PERCENT?)?\n      (ddl_object | rowset_function_limited)\n      with_table_hints?\n      SET update_elem (',' update_elem)*\n      output_clause?\n      (FROM table_sources)?\n      (WHERE (search_condition | CURRENT OF (GLOBAL? cursor_name | cursor_var=LOCAL_ID)))?\n      for_clause? option_clause? ';'?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms177564.aspx\noutput_clause\n    : OUTPUT output_dml_list_elem (',' output_dml_list_elem)*\n      (INTO (LOCAL_ID | table_name) ('(' column_name_list ')')? )?\n    ;\n\noutput_dml_list_elem\n    : (expression | asterisk) as_column_alias?\n    ;\n\n// DDL\n\n// https://msdn.microsoft.com/en-ie/library/ms176061.aspx\ncreate_database\n    : CREATE DATABASE (database=id_)\n    ( CONTAINMENT '=' ( NONE | PARTIAL ) )?\n    ( ON PRIMARY? database_file_spec ( ',' database_file_spec )* )?\n    ( LOG ON database_file_spec ( ',' database_file_spec )* )?\n    ( COLLATE collation_name = id_ )?\n    ( WITH  create_database_option ( ',' create_database_option )* )?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms188783.aspx\ncreate_index\n    : CREATE UNIQUE? clustered? INDEX id_ ON table_name '(' column_name_list_with_order ')'\n    (INCLUDE '(' column_name_list ')' )?\n    (WHERE where=search_condition)?\n    (create_index_options)?\n    (ON id_)?\n    ';'?\n    ;\n\ncreate_index_options\n    : 'WITH' '(' relational_index_option (',' relational_index_option)* ')'\n    ;\n\nrelational_index_option\n    : rebuild_index_option\n    | DROP_EXISTING '=' on_off\n    | OPTIMIZE_FOR_SEQUENTIAL_KEY '=' on_off\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-index-transact-sql\nalter_index\n    : ALTER INDEX (id_ | ALL) ON table_name (DISABLE | PAUSE | ABORT | RESUME resumable_index_options? | reorganize_partition | set_index_options | rebuild_partition)\n    ;\n\nresumable_index_options\n    : WITH '(' (resumable_index_option (',' resumable_index_option)*) ')'\n    ;\n\nresumable_index_option\n    : MAXDOP '=' max_degree_of_parallelism=DECIMAL\n    | MAX_DURATION '=' max_duration=DECIMAL MINUTES?\n    | low_priority_lock_wait\n    ;\n\nreorganize_partition\n    : REORGANIZE (PARTITION '=' DECIMAL)? reorganize_options?\n    ;\n\nreorganize_options\n    : WITH '(' (reorganize_option (',' reorganize_option)*) ')'\n    ;\n\nreorganize_option\n    : LOB_COMPACTION '=' on_off\n    | COMPRESS_ALL_ROW_GROUPS '=' on_off\n    ;\n\nset_index_options\n    : SET '(' set_index_option (',' set_index_option)* ')'\n    ;\n\nset_index_option\n    : ALLOW_ROW_LOCKS '=' on_off\n    | ALLOW_PAGE_LOCKS '=' on_off\n    | OPTIMIZE_FOR_SEQUENTIAL_KEY '=' on_off\n    | IGNORE_DUP_KEY '=' on_off\n    | STATISTICS_NORECOMPUTE '=' on_off\n    | COMPRESSION_DELAY '=' delay=DECIMAL MINUTES?\n    ;\n\nrebuild_partition\n    : REBUILD (PARTITION '=' ALL)? rebuild_index_options?\n    | REBUILD PARTITION '=' DECIMAL single_partition_rebuild_index_options?\n    ;\n\nrebuild_index_options\n    : WITH '(' rebuild_index_option (',' rebuild_index_option)* ')'\n    ;\n\nrebuild_index_option\n    : PAD_INDEX '=' on_off\n    | FILLFACTOR '=' DECIMAL\n    | SORT_IN_TEMPDB '=' on_off\n    | IGNORE_DUP_KEY '=' on_off\n    | STATISTICS_NORECOMPUTE '=' on_off\n    | STATISTICS_INCREMENTAL '=' on_off\n    | ONLINE '=' (ON ('(' low_priority_lock_wait ')')? | OFF)\n    | RESUMABLE '=' on_off\n    | MAX_DURATION '=' times=DECIMAL MINUTES?\n    | ALLOW_ROW_LOCKS '=' on_off\n    | ALLOW_PAGE_LOCKS '=' on_off\n    | MAXDOP '=' max_degree_of_parallelism=DECIMAL\n    | DATA_COMPRESSION '=' (NONE | ROW | PAGE | COLUMNSTORE | COLUMNSTORE_ARCHIVE)\n        on_partitions?\n    | XML_COMPRESSION '=' on_off\n        on_partitions?\n    ;\n\nsingle_partition_rebuild_index_options\n    : WITH '(' single_partition_rebuild_index_option (',' single_partition_rebuild_index_option)* ')'\n    ;\n\nsingle_partition_rebuild_index_option\n    : SORT_IN_TEMPDB '=' on_off\n    | MAXDOP '=' max_degree_of_parallelism=DECIMAL\n    | RESUMABLE '=' on_off\n    | DATA_COMPRESSION '=' (NONE | ROW | PAGE | COLUMNSTORE | COLUMNSTORE_ARCHIVE)\n        on_partitions?\n    | XML_COMPRESSION '=' on_off\n        on_partitions?\n    | ONLINE '=' (ON ('(' low_priority_lock_wait ')')? | OFF)\n    ;\n\non_partitions\n    : ON PARTITIONS '('\n        partition_number=DECIMAL ( 'TO' to_partition_number=DECIMAL )?\n        ( ',' partition_number=DECIMAL ( 'TO' to_partition_number=DECIMAL )? )*\n    ')'\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-columnstore-index-transact-sql?view=sql-server-ver15\ncreate_columnstore_index\n    : CREATE CLUSTERED COLUMNSTORE INDEX id_ ON table_name\n    create_columnstore_index_options?\n    (ON id_)?\n    ';'?\n    ;\n\ncreate_columnstore_index_options\n    : 'WITH' '(' columnstore_index_option (',' columnstore_index_option)* ')'\n    ;\n\ncolumnstore_index_option\n    :\n      DROP_EXISTING '=' on_off\n    | MAXDOP '=' max_degree_of_parallelism=DECIMAL\n    | ONLINE '=' on_off\n    | COMPRESSION_DELAY '=' delay=DECIMAL MINUTES?\n    | DATA_COMPRESSION '=' (COLUMNSTORE | COLUMNSTORE_ARCHIVE)\n        on_partitions?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-columnstore-index-transact-sql?view=sql-server-ver15\ncreate_nonclustered_columnstore_index\n    : CREATE NONCLUSTERED? COLUMNSTORE INDEX id_ ON table_name '(' column_name_list_with_order ')'\n    (WHERE search_condition)?\n    create_columnstore_index_options?\n    (ON id_)?\n    ';'?\n    ;\n\ncreate_xml_index\n    : CREATE PRIMARY? XML INDEX id_ ON table_name '(' id_ ')'\n    (USING XML INDEX id_ (FOR (VALUE | PATH | PROPERTY)?)?)?\n    xml_index_options?\n    ';'?\n    ;\n\nxml_index_options\n    : 'WITH' '(' xml_index_option (',' xml_index_option)* ')'\n    ;\n\nxml_index_option\n    : PAD_INDEX '=' on_off\n    | FILLFACTOR '=' DECIMAL\n    | SORT_IN_TEMPDB '=' on_off\n    | IGNORE_DUP_KEY '=' on_off\n    | DROP_EXISTING '=' on_off\n    | ONLINE '=' (ON ('(' low_priority_lock_wait ')')? | OFF)\n    | ALLOW_ROW_LOCKS '=' on_off\n    | ALLOW_PAGE_LOCKS '=' on_off\n    | MAXDOP '=' max_degree_of_parallelism=DECIMAL\n    | XML_COMPRESSION '=' on_off\n    ;\n\n\n// https://msdn.microsoft.com/en-us/library/ms187926(v=sql.120).aspx\ncreate_or_alter_procedure\n    : ((CREATE (OR (ALTER | REPLACE))?) | ALTER) proc=(PROC | PROCEDURE) procName=func_proc_name_schema (';' DECIMAL)?\n      ('('? procedure_param (',' procedure_param)* ')'?)?\n      (WITH procedure_option (',' procedure_option)*)?\n      (FOR REPLICATION)? AS (as_external_name | sql_clauses*)\n    ;\n\nas_external_name\n    : EXTERNAL NAME assembly_name = id_ '.' class_name = id_ '.' method_name = id_\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql\ncreate_or_alter_trigger\n    : create_or_alter_dml_trigger\n    | create_or_alter_ddl_trigger\n    ;\n\ncreate_or_alter_dml_trigger\n    : (CREATE (OR (ALTER | REPLACE))? | ALTER) TRIGGER simple_name\n      ON table_name\n      (WITH dml_trigger_option (',' dml_trigger_option)* )?\n      (FOR | AFTER | INSTEAD OF)\n      dml_trigger_operation (',' dml_trigger_operation)*\n      (WITH APPEND)?\n      (NOT FOR REPLICATION)?\n      AS sql_clauses+\n    ;\n\ndml_trigger_option\n    : ENCRYPTION\n    | execute_clause\n    ;\n\ndml_trigger_operation\n    : (INSERT | UPDATE | DELETE)\n    ;\n\ncreate_or_alter_ddl_trigger\n    : (CREATE (OR (ALTER | REPLACE))? | ALTER) TRIGGER simple_name\n      ON (ALL SERVER | DATABASE)\n      (WITH dml_trigger_option (',' dml_trigger_option)* )?\n      (FOR | AFTER) ddl_trigger_operation (',' ddl_trigger_operation)*\n      AS sql_clauses+\n    ;\n\nddl_trigger_operation\n    : simple_id\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms186755.aspx\ncreate_or_alter_function\n    : ((CREATE (OR ALTER)?) | ALTER) FUNCTION funcName=func_proc_name_schema\n        (('(' procedure_param (',' procedure_param)* ')') | '(' ')') //must have (), but can be empty\n        (func_body_returns_select | func_body_returns_table | func_body_returns_scalar) ';'?\n    ;\n\nfunc_body_returns_select\n    : RETURNS TABLE\n        (WITH function_option (',' function_option)*)?\n        AS? (as_external_name | RETURN ('(' select_statement_standalone ')' | select_statement_standalone))\n    ;\n\nfunc_body_returns_table\n    : RETURNS LOCAL_ID table_type_definition\n        (WITH function_option (',' function_option)*)?\n        AS? (as_external_name |\n        BEGIN\n           sql_clauses*\n           RETURN ';'?\n        END ';'?)\n    ;\n\nfunc_body_returns_scalar\n    : RETURNS data_type\n        (WITH function_option (',' function_option)*)?\n        AS? (as_external_name |\n        BEGIN\n           sql_clauses*\n           RETURN ret=expression ';'?\n       END)\n    ;\n\nprocedure_param_default_value\n    : NULL_\n    | DEFAULT\n    | constant\n    | LOCAL_ID\n    ;\n\nprocedure_param\n    : LOCAL_ID AS? (type_schema=id_ '.')? data_type VARYING? ('=' default_val=procedure_param_default_value)? (OUT | OUTPUT | READONLY)?\n    ;\n\nprocedure_option\n    : ENCRYPTION\n    | RECOMPILE\n    | execute_clause\n    ;\n\nfunction_option\n    : ENCRYPTION\n    | SCHEMABINDING\n    | RETURNS NULL_ ON NULL_ INPUT\n    | CALLED ON NULL_ INPUT\n    | execute_clause\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms188038.aspx\ncreate_statistics\n    : CREATE STATISTICS id_ ON table_name '(' column_name_list ')'\n      (WITH (FULLSCAN | SAMPLE DECIMAL (PERCENT | ROWS) | STATS_STREAM)\n            (',' NORECOMPUTE)? (',' INCREMENTAL EQUAL on_off)? )? ';'?\n    ;\n\nupdate_statistics\n    : UPDATE STATISTICS full_table_name\n        ( id_ | '(' id_ ( ',' id_ )* ')' )?\n        update_statistics_options?\n    ;\n\nupdate_statistics_options\n    : WITH update_statistics_option (',' update_statistics_option)*\n    ;\n\nupdate_statistics_option\n    : ( FULLSCAN (','? PERSIST_SAMPLE_PERCENT '=' on_off )? )\n    | ( SAMPLE number=DECIMAL (PERCENT | ROWS)\n        (','? PERSIST_SAMPLE_PERCENT '=' on_off )? )\n    | RESAMPLE on_partitions?\n    | STATS_STREAM '=' stats_stream_=expression\n    | ROWCOUNT '=' DECIMAL\n    | PAGECOUNT '=' DECIMAL\n    | ALL\n    | COLUMNS\n    | INDEX\n    | NORECOMPUTE\n    | INCREMENTAL '=' on_off\n    | MAXDOP '=' max_dregree_of_parallelism=DECIMAL\n    | AUTO_DROP '=' on_off\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms174979.aspx\ncreate_table\n    : CREATE TABLE table_name '(' column_def_table_constraints  (','? table_indices)*  ','? ')' (LOCK simple_id)? table_options* (ON id_ | DEFAULT | on_partition_or_filegroup)? (TEXTIMAGE_ON id_ | DEFAULT)?';'?\n    ;\n\ntable_indices\n    : INDEX id_  UNIQUE? clustered? '(' column_name_list_with_order ')'\n    | INDEX id_ CLUSTERED COLUMNSTORE\n    | INDEX id_ NONCLUSTERED? COLUMNSTORE '(' column_name_list ')'\n    create_table_index_options?\n    (ON id_)?\n    ;\n\ntable_options\n    : WITH ('(' table_option (',' table_option)* ')' | table_option (',' table_option)*)\n    ;\n\ntable_option\n    : (simple_id | keyword) '=' (simple_id | keyword | on_off | DECIMAL)\n    | CLUSTERED COLUMNSTORE INDEX | HEAP\n    | FILLFACTOR '=' DECIMAL\n    | DISTRIBUTION '=' HASH '(' id_ ')' | CLUSTERED INDEX '(' id_ (ASC | DESC)? (',' id_ (ASC | DESC)?)* ')'\n    | DATA_COMPRESSION '=' (NONE | ROW | PAGE)\n        on_partitions?\n    | XML_COMPRESSION '=' on_off\n        on_partitions?\n    ;\n\ncreate_table_index_options\n    : WITH '(' create_table_index_option ( ',' create_table_index_option)* ')'\n    ;\n\ncreate_table_index_option\n    : PAD_INDEX '=' on_off\n    | FILLFACTOR '=' DECIMAL\n    | IGNORE_DUP_KEY '=' on_off\n    | STATISTICS_NORECOMPUTE '=' on_off\n    | STATISTICS_INCREMENTAL '=' on_off\n    | ALLOW_ROW_LOCKS '=' on_off\n    | ALLOW_PAGE_LOCKS '=' on_off\n    | OPTIMIZE_FOR_SEQUENTIAL_KEY '=' on_off\n    | DATA_COMPRESSION '=' (NONE | ROW | PAGE | COLUMNSTORE | COLUMNSTORE_ARCHIVE)\n        on_partitions?\n    | XML_COMPRESSION '=' on_off\n        on_partitions?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms187956.aspx\ncreate_view\n    : (CREATE (OR (ALTER | REPLACE))? | ALTER) VIEW simple_name ('(' column_name_list ')')?\n      (WITH view_attribute (',' view_attribute)*)?\n      AS select_statement_standalone (WITH CHECK OPTION)? ';'?\n    ;\n\nview_attribute\n    : ENCRYPTION | SCHEMABINDING | VIEW_METADATA\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms190273.aspx\nalter_table\n    : ALTER TABLE table_name (SET '(' LOCK_ESCALATION '=' (AUTO | TABLE | DISABLE) ')'\n                             | ADD column_def_table_constraints\n                             | ALTER COLUMN (column_definition | column_modifier)\n                             | DROP COLUMN id_ (',' id_)*\n                             | DROP CONSTRAINT constraint=id_\n                             | WITH (CHECK | NOCHECK) ADD (CONSTRAINT constraint=id_)?\n                                ( FOREIGN KEY '(' fk=column_name_list ')' REFERENCES table_name ('(' pk=column_name_list')')? (on_delete | on_update)*\n                                | CHECK '(' search_condition ')' )\n                             | (NOCHECK | CHECK) CONSTRAINT constraint=id_\n                             | (ENABLE | DISABLE) TRIGGER id_?\n                             | REBUILD table_options\n                             | SWITCH switch_partition)\n                             ';'?\n    ;\n\nswitch_partition\n    : (PARTITION? source_partition_number_expression=expression)?\n      TO target_table=table_name\n      (PARTITION target_partition_number_expression=expression)?\n      (WITH low_priority_lock_wait)?\n    ;\n\nlow_priority_lock_wait\n    : WAIT_AT_LOW_PRIORITY '('\n      MAX_DURATION '=' max_duration=time MINUTES? ','\n      ABORT_AFTER_WAIT '=' abort_after_wait=(NONE | SELF | BLOCKERS) ')'\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms174269.aspx\nalter_database\n    : ALTER DATABASE (database=id_ | CURRENT)\n      (MODIFY NAME '=' new_name=id_\n      | COLLATE collation=id_\n      | SET database_optionspec (WITH termination)?\n      | add_or_modify_files\n      | add_or_modify_filegroups\n      ) ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-file-and-filegroup-options?view=sql-server-ver15\nadd_or_modify_files\n    : ADD FILE filespec (',' filespec)* (TO FILEGROUP filegroup_name=id_)?\n    | ADD LOG FILE filespec (',' filespec)*\n    | REMOVE FILE logical_file_name=id_\n    | MODIFY FILE filespec\n    ;\n\nfilespec\n    : '('      NAME       '=' name=id_or_string\n          (',' NEWNAME    '=' new_name=id_or_string )?\n          (',' FILENAME   '=' file_name=STRING )?\n          (',' SIZE       '=' size=file_size )?\n          (',' MAXSIZE    '=' (max_size=file_size) | UNLIMITED )?\n          (',' FILEGROWTH '=' growth_increment=file_size )?\n          (',' OFFLINE )?\n      ')'\n    ;\n\nadd_or_modify_filegroups\n    : ADD FILEGROUP filegroup_name=id_ (CONTAINS FILESTREAM | CONTAINS MEMORY_OPTIMIZED_DATA)?\n    | REMOVE FILEGROUP filegrou_name=id_\n    | MODIFY FILEGROUP filegrou_name=id_ (\n          filegroup_updatability_option\n        | DEFAULT\n        | NAME '=' new_filegroup_name=id_\n        | AUTOGROW_SINGLE_FILE\n        | AUTOGROW_ALL_FILES\n      )\n    ;\n\nfilegroup_updatability_option\n    : READONLY\n    | READWRITE\n    | READ_ONLY\n    | READ_WRITE\n    ;\n\n// https://msdn.microsoft.com/en-us/library/bb522682.aspx\n// Runtime check.\ndatabase_optionspec\n    : auto_option\n    | change_tracking_option\n    | containment_option\n    | cursor_option\n    | database_mirroring_option\n    | date_correlation_optimization_option\n    | db_encryption_option\n    | db_state_option\n    | db_update_option\n    | db_user_access_option\n    | delayed_durability_option\n    | external_access_option\n    | FILESTREAM database_filestream_option\n    | hadr_options\n    | mixed_page_allocation_option\n    | parameterization_option\n//  | query_store_options\n    | recovery_option\n//  | remote_data_archive_option\n    | service_broker_option\n    | snapshot_option\n    | sql_option\n    | target_recovery_time_option\n    | termination\n    ;\n\nauto_option\n    : AUTO_CLOSE on_off\n    | AUTO_CREATE_STATISTICS  OFF | ON ( INCREMENTAL EQUAL  ON | OFF  )\n    | AUTO_SHRINK  on_off\n    | AUTO_UPDATE_STATISTICS on_off\n    | AUTO_UPDATE_STATISTICS_ASYNC  (ON | OFF )\n    ;\n\nchange_tracking_option\n    : CHANGE_TRACKING  EQUAL ( OFF | ON '(' (change_tracking_option_list (',' change_tracking_option_list)*)* ')' )\n    ;\n\nchange_tracking_option_list\n    : AUTO_CLEANUP EQUAL on_off\n    | CHANGE_RETENTION EQUAL DECIMAL ( DAYS | HOURS | MINUTES )\n    ;\n\ncontainment_option\n    : CONTAINMENT EQUAL ( NONE | PARTIAL )\n    ;\n\ncursor_option\n    : CURSOR_CLOSE_ON_COMMIT on_off\n    | CURSOR_DEFAULT ( LOCAL | GLOBAL )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-endpoint-transact-sql\nalter_endpoint\n    : ALTER ENDPOINT endpointname=id_ (AUTHORIZATION login=id_)?\n       (STATE EQUAL state=(STARTED | STOPPED | DISABLED))?\n               AS TCP LR_BRACKET endpoint_listener_clause RR_BRACKET\n               ( FOR TSQL LR_BRACKET RR_BRACKET\n               | FOR SERVICE_BROKER LR_BRACKET\n                   endpoint_authentication_clause\n                   (COMMA? endpoint_encryption_alogorithm_clause)?\n                   (COMMA? MESSAGE_FORWARDING EQUAL (ENABLED | DISABLED))?\n                   (COMMA? MESSAGE_FORWARD_SIZE EQUAL DECIMAL)?\n                   RR_BRACKET\n               | FOR DATABASE_MIRRORING LR_BRACKET\n                   endpoint_authentication_clause\n                   (COMMA? endpoint_encryption_alogorithm_clause)?\n                   COMMA? ROLE EQUAL (WITNESS | PARTNER | ALL)\n                   RR_BRACKET\n               )\n    ;\n\n/* Will visit later\n*/\ndatabase_mirroring_option\n    : mirroring_set_option\n    ;\n\nmirroring_set_option\n    : mirroring_partner  partner_option\n    | mirroring_witness  witness_option\n    ;\nmirroring_partner\n    : PARTNER\n    ;\n\nmirroring_witness\n    : WITNESS\n    ;\n\nwitness_partner_equal\n    : EQUAL\n    ;\n\n\npartner_option\n    : witness_partner_equal partner_server\n    | FAILOVER\n    | FORCE_SERVICE_ALLOW_DATA_LOSS\n    | OFF\n    | RESUME\n    | SAFETY (FULL | OFF )\n    | SUSPEND\n    | TIMEOUT DECIMAL\n    ;\n\nwitness_option\n    : witness_partner_equal witness_server\n    | OFF\n    ;\n\nwitness_server\n    : partner_server\n    ;\n\npartner_server\n    : partner_server_tcp_prefix host mirroring_host_port_seperator port_number\n    ;\n\nmirroring_host_port_seperator\n    : COLON\n    ;\n\npartner_server_tcp_prefix\n    : TCP COLON DOUBLE_FORWARD_SLASH\n    ;\nport_number\n    : port=DECIMAL\n    ;\n\nhost\n    : id_ DOT host\n    | (id_ DOT |id_)\n    ;\n\ndate_correlation_optimization_option\n    : DATE_CORRELATION_OPTIMIZATION on_off\n    ;\n\ndb_encryption_option\n    : ENCRYPTION on_off\n    ;\ndb_state_option\n    : ( ONLINE | OFFLINE | EMERGENCY )\n    ;\n\ndb_update_option\n    : READ_ONLY | READ_WRITE\n    ;\n\ndb_user_access_option\n    : SINGLE_USER | RESTRICTED_USER | MULTI_USER\n    ;\ndelayed_durability_option\n    : DELAYED_DURABILITY EQUAL ( DISABLED | ALLOWED | FORCED )\n    ;\n\nexternal_access_option\n    : DB_CHAINING on_off\n    | TRUSTWORTHY on_off\n    | DEFAULT_LANGUAGE EQUAL ( id_ | STRING )\n    | DEFAULT_FULLTEXT_LANGUAGE EQUAL ( id_ | STRING )\n    | NESTED_TRIGGERS EQUAL ( OFF | ON )\n    | TRANSFORM_NOISE_WORDS EQUAL ( OFF | ON )\n    | TWO_DIGIT_YEAR_CUTOFF EQUAL DECIMAL\n    ;\n\nhadr_options\n    : HADR\n      ( ( AVAILABILITY GROUP EQUAL availability_group_name=id_ | OFF ) |(SUSPEND|RESUME) )\n    ;\n\nmixed_page_allocation_option\n    : MIXED_PAGE_ALLOCATION ( OFF | ON )\n    ;\n\nparameterization_option\n    : PARAMETERIZATION ( SIMPLE | FORCED )\n    ;\n\nrecovery_option\n    : RECOVERY ( FULL | BULK_LOGGED | SIMPLE )\n    | TORN_PAGE_DETECTION on_off\n    | ACCELERATED_DATABASE_RECOVERY '=' on_off\n    | PAGE_VERIFY ( CHECKSUM | TORN_PAGE_DETECTION | NONE )\n    ;\n\nservice_broker_option:\n    ENABLE_BROKER\n    | DISABLE_BROKER\n    | NEW_BROKER\n    | ERROR_BROKER_CONVERSATIONS\n    | HONOR_BROKER_PRIORITY on_off\n    ;\nsnapshot_option\n    : ALLOW_SNAPSHOT_ISOLATION on_off\n    | READ_COMMITTED_SNAPSHOT (ON | OFF )\n    | MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT = (ON | OFF )\n    ;\n\nsql_option\n    : ANSI_NULL_DEFAULT on_off\n    | ANSI_NULLS on_off\n    | ANSI_PADDING on_off\n    | ANSI_WARNINGS on_off\n    | ARITHABORT on_off\n    | COMPATIBILITY_LEVEL EQUAL DECIMAL\n    | CONCAT_NULL_YIELDS_NULL on_off\n    | NUMERIC_ROUNDABORT on_off\n    | QUOTED_IDENTIFIER on_off\n    | RECURSIVE_TRIGGERS on_off\n    ;\n\ntarget_recovery_time_option\n    : TARGET_RECOVERY_TIME EQUAL DECIMAL ( SECONDS | MINUTES )\n    ;\n\ntermination\n    : ROLLBACK AFTER seconds = DECIMAL\n    | ROLLBACK IMMEDIATE\n    | NO_WAIT\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms176118.aspx\ndrop_index\n    : DROP INDEX (IF EXISTS)?\n    ( drop_relational_or_xml_or_spatial_index (',' drop_relational_or_xml_or_spatial_index)*\n    | drop_backward_compatible_index (',' drop_backward_compatible_index)*\n    )\n    ';'?\n    ;\n\ndrop_relational_or_xml_or_spatial_index\n    : index_name=id_ ON full_table_name\n    ;\n\ndrop_backward_compatible_index\n    : (owner_name=id_ '.')? table_or_view_name=id_ '.' index_name=id_\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms174969.aspx\ndrop_procedure\n    : DROP proc=(PROC | PROCEDURE) (IF EXISTS)? func_proc_name_schema (',' func_proc_name_schema)* ';'?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-trigger-transact-sql\ndrop_trigger\n    : drop_dml_trigger\n    | drop_ddl_trigger\n    ;\n\ndrop_dml_trigger\n    : DROP TRIGGER (IF EXISTS)? simple_name (',' simple_name)* ';'?\n    ;\n\ndrop_ddl_trigger\n    : DROP TRIGGER (IF EXISTS)? simple_name (',' simple_name)*\n    ON (DATABASE | ALL SERVER) ';'?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms190290.aspx\ndrop_function\n    : DROP FUNCTION (IF EXISTS)? func_proc_name_schema (',' func_proc_name_schema)* ';'?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms175075.aspx\ndrop_statistics\n    : DROP STATISTICS (COMMA? (table_name '.')? name=id_)+ ';'\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms173790.aspx\ndrop_table\n    : DROP TABLE (IF EXISTS)? table_name (',' table_name)* ';'?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms173492.aspx\ndrop_view\n    : DROP VIEW (IF EXISTS)? simple_name (',' simple_name)* ';'?\n    ;\n\ncreate_type\n    : CREATE TYPE name = simple_name\n      (FROM data_type null_notnull?)?\n      (AS TABLE LR_BRACKET column_def_table_constraints RR_BRACKET)?\n    ;\n\ndrop_type:\n    DROP TYPE ( IF EXISTS )? name = simple_name\n    ;\n\nrowset_function_limited\n    : openquery\n    | opendatasource\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms188427(v=sql.120).aspx\nopenquery\n    : OPENQUERY '(' linked_server=id_ ',' query=STRING ')'\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms179856.aspx\nopendatasource\n    : OPENDATASOURCE '(' provider=STRING ',' init=STRING ')'\n     '.' (database=id_)? '.' (scheme=id_)? '.' (table=id_)\n    ;\n\n// Other statements.\n\n// https://msdn.microsoft.com/en-us/library/ms188927.aspx\ndeclare_statement\n    : DECLARE LOCAL_ID AS? (data_type | table_type_definition | table_name)\n    | DECLARE loc+=declare_local (',' loc+=declare_local)*\n    | DECLARE LOCAL_ID AS? xml_type_definition\n    | WITH XMLNAMESPACES '(' xml_dec+=xml_declaration (',' xml_dec+=xml_declaration)* ')'\n    ;\n\nxml_declaration\n    : xml_namespace_uri=STRING AS id_\n    | DEFAULT STRING\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms181441(v=sql.120).aspx\ncursor_statement\n    // https://msdn.microsoft.com/en-us/library/ms175035(v=sql.120).aspx\n    : CLOSE GLOBAL? cursor_name ';'?\n    // https://msdn.microsoft.com/en-us/library/ms188782(v=sql.120).aspx\n    | DEALLOCATE GLOBAL? CURSOR? cursor_name ';'?\n    // https://msdn.microsoft.com/en-us/library/ms180169(v=sql.120).aspx\n    | declare_cursor\n    // https://msdn.microsoft.com/en-us/library/ms180152(v=sql.120).aspx\n    | fetch_cursor\n    // https://msdn.microsoft.com/en-us/library/ms190500(v=sql.120).aspx\n    | OPEN GLOBAL? cursor_name ';'?\n    ;\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/backup-transact-sql\nbackup_database\n    : BACKUP DATABASE ( database_name=id_ )\n          (READ_WRITE_FILEGROUPS (COMMA? (FILE|FILEGROUP) EQUAL file_or_filegroup=STRING)* )?\n          (COMMA? (FILE|FILEGROUP) EQUAL file_or_filegroup=STRING)*\n           ( TO ( COMMA? logical_device_name=id_)+\n           | TO ( COMMA? (DISK|TAPE|URL) EQUAL (STRING|id_) )+\n           )\n\n           ( (MIRROR TO ( COMMA? logical_device_name=id_)+ )+\n           | ( MIRROR TO ( COMMA? (DISK|TAPE|URL) EQUAL (STRING|id_) )+ )+\n           )?\n\n             (WITH ( COMMA? DIFFERENTIAL\n                   | COMMA? COPY_ONLY\n                   | COMMA? (COMPRESSION|NO_COMPRESSION)\n                   | COMMA? DESCRIPTION EQUAL (STRING|id_)\n                   | COMMA? NAME EQUAL backup_set_name=id_\n                   | COMMA? CREDENTIAL\n                   | COMMA? FILE_SNAPSHOT\n                   | COMMA? (EXPIREDATE EQUAL (STRING|id_) | RETAINDAYS EQUAL (DECIMAL|id_) )\n                   | COMMA? (NOINIT|INIT)\n                   | COMMA? (NOSKIP|SKIP_KEYWORD)\n                   | COMMA? (NOFORMAT|FORMAT)\n                   | COMMA? MEDIADESCRIPTION EQUAL (STRING|id_)\n                   | COMMA? MEDIANAME EQUAL (medianame=STRING)\n                   | COMMA? BLOCKSIZE EQUAL (DECIMAL|id_)\n                   | COMMA? BUFFERCOUNT EQUAL (DECIMAL|id_)\n                   | COMMA? MAXTRANSFER EQUAL (DECIMAL|id_)\n                   | COMMA? (NO_CHECKSUM|CHECKSUM)\n                   | COMMA? (STOP_ON_ERROR|CONTINUE_AFTER_ERROR)\n                   | COMMA? RESTART\n                   | COMMA? STATS (EQUAL stats_percent=DECIMAL)?\n                   | COMMA? (REWIND|NOREWIND)\n                   | COMMA? (LOAD|NOUNLOAD)\n                   | COMMA? ENCRYPTION LR_BRACKET\n                                         ALGORITHM EQUAL\n                                         (AES_128\n                                         | AES_192\n                                         | AES_256\n                                         | TRIPLE_DES_3KEY\n                                         )\n                                         COMMA\n                                         SERVER CERTIFICATE EQUAL\n                                           (encryptor_name=id_\n                                           | SERVER ASYMMETRIC KEY EQUAL encryptor_name=id_\n                                           )\n                  )*\n              )?\n\n    ;\n\nbackup_log\n    : BACKUP LOG ( database_name=id_ )\n           ( TO ( COMMA? logical_device_name=id_)+\n           | TO ( COMMA? (DISK|TAPE|URL) EQUAL (STRING|id_) )+\n           )\n\n           ( (MIRROR TO ( COMMA? logical_device_name=id_)+ )+\n           | ( MIRROR TO ( COMMA? (DISK|TAPE|URL) EQUAL (STRING|id_) )+ )+\n           )?\n\n             (WITH ( COMMA? DIFFERENTIAL\n                   | COMMA? COPY_ONLY\n                   | COMMA? (COMPRESSION|NO_COMPRESSION)\n                   | COMMA? DESCRIPTION EQUAL (STRING|id_)\n                   | COMMA? NAME EQUAL backup_set_name=id_\n                   | COMMA? CREDENTIAL\n                   | COMMA? FILE_SNAPSHOT\n                   | COMMA? (EXPIREDATE EQUAL (STRING|id_) | RETAINDAYS EQUAL (DECIMAL|id_) )\n                   | COMMA? (NOINIT|INIT)\n                   | COMMA? (NOSKIP|SKIP_KEYWORD)\n                   | COMMA? (NOFORMAT|FORMAT)\n                   | COMMA? MEDIADESCRIPTION EQUAL (STRING|id_)\n                   | COMMA? MEDIANAME EQUAL (medianame=STRING)\n                   | COMMA? BLOCKSIZE EQUAL (DECIMAL|id_)\n                   | COMMA? BUFFERCOUNT EQUAL (DECIMAL|id_)\n                   | COMMA? MAXTRANSFER EQUAL (DECIMAL|id_)\n                   | COMMA? (NO_CHECKSUM|CHECKSUM)\n                   | COMMA? (STOP_ON_ERROR|CONTINUE_AFTER_ERROR)\n                   | COMMA? RESTART\n                   | COMMA? STATS (EQUAL stats_percent=DECIMAL)?\n                   | COMMA? (REWIND|NOREWIND)\n                   | COMMA? (LOAD|NOUNLOAD)\n                   | COMMA? (NORECOVERY| STANDBY EQUAL undo_file_name=STRING)\n                   | COMMA? NO_TRUNCATE\n                   | COMMA? ENCRYPTION LR_BRACKET\n                                         ALGORITHM EQUAL\n                                         (AES_128\n                                         | AES_192\n                                         | AES_256\n                                         | TRIPLE_DES_3KEY\n                                         )\n                                         COMMA\n                                         SERVER CERTIFICATE EQUAL\n                                           (encryptor_name=id_\n                                           | SERVER ASYMMETRIC KEY EQUAL encryptor_name=id_\n                                           )\n                  )*\n              )?\n\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/backup-certificate-transact-sql\nbackup_certificate\n    : BACKUP CERTIFICATE certname=id_ TO FILE EQUAL cert_file=STRING\n       ( WITH PRIVATE KEY\n           LR_BRACKET\n             (COMMA? FILE EQUAL private_key_file=STRING\n             |COMMA? ENCRYPTION BY PASSWORD EQUAL encryption_password=STRING\n             |COMMA? DECRYPTION BY PASSWORD EQUAL decryption_pasword=STRING\n             )+\n           RR_BRACKET\n       )?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/backup-master-key-transact-sql\nbackup_master_key\n    : BACKUP MASTER KEY TO FILE EQUAL master_key_backup_file=STRING\n         ENCRYPTION BY PASSWORD EQUAL encryption_password=STRING\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/statements/backup-service-master-key-transact-sql\nbackup_service_master_key\n    : BACKUP SERVICE MASTER KEY TO FILE EQUAL service_master_key_backup_file=STRING\n         ENCRYPTION BY PASSWORD EQUAL encryption_password=STRING\n    ;\n\nkill_statement\n    : KILL (kill_process | kill_query_notification | kill_stats_job)\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/kill-transact-sql\nkill_process\n    : (session_id=(DECIMAL|STRING) | UOW) (WITH STATUSONLY)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/kill-query-notification-subscription-transact-sql\nkill_query_notification\n    : QUERY NOTIFICATION SUBSCRIPTION (ALL | subscription_id=DECIMAL)\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/kill-stats-job-transact-sql\nkill_stats_job\n    : STATS JOB job_id=DECIMAL\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms188332.aspx\nexecute_statement\n    : EXECUTE execute_body ';'?\n    ;\n\nexecute_body_batch\n    : func_proc_name_server_database_schema (execute_statement_arg (',' execute_statement_arg)*)? ';'?\n    ;\n\n//https://docs.microsoft.com/it-it/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver15\nexecute_body\n    : (return_status=LOCAL_ID '=')? (func_proc_name_server_database_schema | execute_var_string)  execute_statement_arg?\n    | '(' execute_var_string (',' execute_var_string)* ')' (AS (LOGIN | USER) '=' STRING)? (AT_KEYWORD linkedServer=id_)?\n    | AS (\n            (LOGIN | USER) '=' STRING\n            | CALLER\n    )\n    ;\n\nexecute_statement_arg\n    :\n    execute_statement_arg_unnamed (',' execute_statement_arg) *    //Unnamed params can continue unnamed\n    |\n    execute_statement_arg_named (',' execute_statement_arg_named)* //Named can only be continued by unnamed\n    ;\n\nexecute_statement_arg_named\n    : name=LOCAL_ID '=' value=execute_parameter\n    ;\n\nexecute_statement_arg_unnamed\n    : value=execute_parameter\n    ;\n\nexecute_parameter\n    : (constant | LOCAL_ID (OUTPUT | OUT)? | id_ | DEFAULT | NULL_)\n    ;\n\nexecute_var_string\n    : LOCAL_ID (OUTPUT | OUT)? ('+' LOCAL_ID ('+' execute_var_string)?)?\n    | STRING ('+' LOCAL_ID ('+' execute_var_string)?)?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ff848791.aspx\nsecurity_statement\n    // https://msdn.microsoft.com/en-us/library/ms188354.aspx\n    : execute_clause ';'?\n    // https://msdn.microsoft.com/en-us/library/ms187965.aspx\n    | GRANT (ALL PRIVILEGES? | grant_permission ('(' column_name_list ')')?) (ON (class_type_for_grant '::')? on_id=table_name)? TO to_principal+=principal_id (',' to_principal+=principal_id)* (WITH GRANT OPTION)? (AS as_principal=principal_id)? ';'?\n    // https://msdn.microsoft.com/en-us/library/ms178632.aspx\n    | REVERT (WITH COOKIE '=' LOCAL_ID)? ';'?\n    | open_key\n    | close_key\n    | create_key\n    | create_certificate\n    ;\n\nprincipal_id\n    : id_\n    | PUBLIC\n    ;\n\ncreate_certificate\n    : CREATE CERTIFICATE certificate_name=id_ (AUTHORIZATION user_name=id_)?\n      (FROM existing_keys | generate_new_keys)\n      (ACTIVE FOR BEGIN DIALOG '=' on_off)?\n    ;\n\nexisting_keys\n    : ASSEMBLY assembly_name=id_\n    | EXECUTABLE? FILE EQUAL path_to_file=STRING (WITH PRIVATE KEY '(' private_key_options ')')?\n    ;\n\nprivate_key_options\n    : (FILE | BINARY) '=' path=STRING (',' (DECRYPTION | ENCRYPTION) BY PASSWORD '=' password=STRING)?\n    ;\n\ngenerate_new_keys\n    : (ENCRYPTION BY PASSWORD '=' password=STRING)?\n      WITH SUBJECT EQUAL certificate_subject_name=STRING (',' date_options)*\n    ;\n\ndate_options\n    : (START_DATE | EXPIRY_DATE) EQUAL STRING\n    ;\n\nopen_key\n    : OPEN SYMMETRIC KEY key_name=id_ DECRYPTION BY decryption_mechanism\n    | OPEN MASTER KEY DECRYPTION BY PASSWORD '=' password=STRING\n    ;\n\nclose_key\n    : CLOSE SYMMETRIC KEY key_name=id_\n    | CLOSE ALL SYMMETRIC KEYS\n    | CLOSE MASTER KEY\n    ;\n\ncreate_key\n    : CREATE MASTER KEY ENCRYPTION BY PASSWORD '=' password=STRING\n    | CREATE SYMMETRIC KEY key_name=id_\n      (AUTHORIZATION user_name=id_)?\n      (FROM PROVIDER provider_name=id_)?\n      WITH ((key_options | ENCRYPTION BY encryption_mechanism)','?)+\n    ;\n\nkey_options\n    : KEY_SOURCE EQUAL pass_phrase=STRING\n    | ALGORITHM EQUAL algorithm\n    | IDENTITY_VALUE EQUAL identity_phrase=STRING\n    | PROVIDER_KEY_NAME EQUAL key_name_in_provider=STRING\n    | CREATION_DISPOSITION EQUAL (CREATE_NEW | OPEN_EXISTING)\n    ;\n\nalgorithm\n    : DES\n    | TRIPLE_DES\n    | TRIPLE_DES_3KEY\n    | RC2\n    | RC4\n    | RC4_128\n    | DESX\n    | AES_128\n    | AES_192\n    | AES_256\n    ;\n\nencryption_mechanism\n    : CERTIFICATE certificate_name=id_\n    | ASYMMETRIC KEY asym_key_name=id_\n    | SYMMETRIC KEY decrypting_Key_name=id_\n    | PASSWORD '=' STRING\n    ;\n\ndecryption_mechanism\n    : CERTIFICATE certificate_name=id_ (WITH PASSWORD EQUAL STRING)?\n    | ASYMMETRIC KEY asym_key_name=id_ (WITH PASSWORD EQUAL STRING)?\n    | SYMMETRIC KEY decrypting_Key_name=id_\n    | PASSWORD EQUAL STRING\n    ;\n\n// https://docs.microsoft.com/en-us/sql/relational-databases/system-functions/sys-fn-builtin-permissions-transact-sql?view=sql-server-ver15\n// SELECT DISTINCT '| ' + permission_name\n// FROM sys.fn_builtin_permissions (DEFAULT)\n// ORDER BY 1\ngrant_permission\n    : ADMINISTER ( BULK OPERATIONS | DATABASE BULK OPERATIONS)\n    | ALTER ( ANY ( APPLICATION ROLE\n                  | ASSEMBLY\n                  | ASYMMETRIC KEY\n                  | AVAILABILITY GROUP\n                  | CERTIFICATE\n                  | COLUMN ( ENCRYPTION KEY | MASTER KEY )\n                  | CONNECTION\n                  | CONTRACT\n                  | CREDENTIAL\n                  | DATABASE ( AUDIT\n                             | DDL TRIGGER\n                             | EVENT ( NOTIFICATION | SESSION )\n                             | SCOPED CONFIGURATION\n                             )?\n                  | DATASPACE\n                  | ENDPOINT\n                  | EVENT ( NOTIFICATION | SESSION )\n                  | EXTERNAL ( DATA SOURCE | FILE FORMAT | LIBRARY)\n                  | FULLTEXT CATALOG\n                  | LINKED SERVER\n                  | LOGIN\n                  | MASK\n                  | MESSAGE TYPE\n                  | REMOTE SERVICE BINDING\n                  | ROLE\n                  | ROUTE\n                  | SCHEMA\n                  | SECURITY POLICY\n                  | SERVER ( AUDIT | ROLE )\n                  | SERVICE\n                  | SYMMETRIC KEY\n                  | USER\n                  )\n            | RESOURCES\n            | SERVER STATE\n            | SETTINGS\n            | TRACE\n            )?\n    | AUTHENTICATE SERVER?\n    | BACKUP ( DATABASE | LOG )\n    | CHECKPOINT\n    | CONNECT ( ANY DATABASE | REPLICATION | SQL )?\n    | CONTROL SERVER?\n    | CREATE ( AGGREGATE\n             | ANY DATABASE\n             | ASSEMBLY\n             | ASYMMETRIC KEY\n             | AVAILABILITY GROUP\n             | CERTIFICATE\n             | CONTRACT\n             | DATABASE (DDL EVENT NOTIFICATION)?\n             | DDL EVENT NOTIFICATION\n             | DEFAULT\n             | ENDPOINT\n             | EXTERNAL LIBRARY\n             | FULLTEXT CATALOG\n             | FUNCTION\n             | MESSAGE TYPE\n             | PROCEDURE\n             | QUEUE\n             | REMOTE SERVICE BINDING\n             | ROLE\n             | ROUTE\n             | RULE\n             | SCHEMA\n             | SEQUENCE\n             | SERVER ROLE\n             | SERVICE\n             | SYMMETRIC KEY\n             | SYNONYM\n             | TABLE\n             | TRACE EVENT NOTIFICATION\n             | TYPE\n             | VIEW\n             | XML SCHEMA COLLECTION\n             )\n    | DELETE\n    | EXECUTE ( ANY EXTERNAL SCRIPT )?\n    | EXTERNAL ACCESS ASSEMBLY\n    | IMPERSONATE ( ANY LOGIN )?\n    | INSERT\n    | KILL DATABASE CONNECTION\n    | RECEIVE\n    | REFERENCES\n    | SELECT ( ALL USER SECURABLES )?\n    | SEND\n    | SHOWPLAN\n    | SHUTDOWN\n    | SUBSCRIBE QUERY NOTIFICATIONS\n    | TAKE OWNERSHIP\n    | UNMASK\n    | UNSAFE ASSEMBLY\n    | UPDATE\n    | VIEW ( ANY ( DATABASE | DEFINITION | COLUMN ( ENCRYPTION | MASTER ) KEY DEFINITION )\n           | CHANGE TRACKING\n           | DATABASE STATE\n           | DEFINITION\n           | SERVER STATE\n           )\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms190356.aspx\n// https://msdn.microsoft.com/en-us/library/ms189484.aspx\nset_statement\n    : SET LOCAL_ID ('.' member_name=id_)? '=' expression\n    | SET LOCAL_ID assignment_operator expression\n    | SET LOCAL_ID '='\n      CURSOR declare_set_cursor_common (FOR (READ ONLY | UPDATE (OF column_name_list)?))?\n    // https://msdn.microsoft.com/en-us/library/ms189837.aspx\n    | set_special\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms174377.aspx\ntransaction_statement\n    // https://msdn.microsoft.com/en-us/library/ms188386.aspx\n    : BEGIN DISTRIBUTED (TRAN | TRANSACTION) (id_ | LOCAL_ID)?\n    // https://msdn.microsoft.com/en-us/library/ms188929.aspx\n    | BEGIN (TRAN | TRANSACTION) ((id_ | LOCAL_ID) (WITH MARK STRING)?)?\n    // https://msdn.microsoft.com/en-us/library/ms190295.aspx\n    | COMMIT (TRAN | TRANSACTION) ((id_ | LOCAL_ID) (WITH '(' DELAYED_DURABILITY EQUAL (OFF | ON) ')')?)?\n    // https://msdn.microsoft.com/en-us/library/ms178628.aspx\n    | COMMIT WORK?\n    | COMMIT id_\n    | ROLLBACK id_\n    // https://msdn.microsoft.com/en-us/library/ms181299.aspx\n    | ROLLBACK (TRAN | TRANSACTION) (id_ | LOCAL_ID)?\n    // https://msdn.microsoft.com/en-us/library/ms174973.aspx\n    | ROLLBACK WORK?\n    // https://msdn.microsoft.com/en-us/library/ms188378.aspx\n    | SAVE (TRAN | TRANSACTION) (id_ | LOCAL_ID)?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms188037.aspx\ngo_statement\n    : GO (count=DECIMAL)?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms188366.aspx\nuse_statement\n    : USE database=id_\n    ;\n\nsetuser_statement\n    : SETUSER user=STRING?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/reconfigure-transact-sql\nreconfigure_statement\n    : RECONFIGURE (WITH OVERRIDE)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/shutdown-transact-sql\nshutdown_statement\n    : SHUTDOWN (WITH NOWAIT)?\n    ;\n\ncheckpoint_statement\n    : CHECKPOINT (checkPointDuration=DECIMAL)?\n    ;\n\ndbcc_checkalloc_option\n    : ALL_ERRORMSGS\n    | NO_INFOMSGS\n    | TABLOCK\n    | ESTIMATEONLY\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-checkalloc-transact-sql?view=sql-server-ver16\ndbcc_checkalloc\n    : name=CHECKALLOC\n        (\n            '('\n                ( database=id_ | databaseid=STRING | DECIMAL )\n                ( ',' NOINDEX | ',' ( REPAIR_ALLOW_DATA_LOSS | REPAIR_FAST | REPAIR_REBUILD ) )?\n            ')'\n            (\n                WITH dbcc_option=dbcc_checkalloc_option ( ',' dbcc_option=dbcc_checkalloc_option )*\n            )?\n        )?\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-checkcatalog-transact-sql?view=sql-server-ver16\ndbcc_checkcatalog\n    : name=CHECKCATALOG\n        (\n            '('\n                ( database=id_ | databasename=STRING | DECIMAL )\n            ')'\n        )?\n        (\n            WITH dbcc_option=NO_INFOMSGS\n        )?\n    ;\n\ndbcc_checkconstraints_option\n    : ALL_CONSTRAINTS\n    | ALL_ERRORMSGS\n    | NO_INFOMSGS\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-checkconstraints-transact-sql?view=sql-server-ver16\ndbcc_checkconstraints\n    : name=CHECKCONSTRAINTS\n        (\n            '('\n                ( table_or_constraint=id_ | table_or_constraint_name=STRING )\n            ')'\n        )?\n        (\n            WITH dbcc_option=dbcc_checkconstraints_option (',' dbcc_option=dbcc_checkconstraints_option)*\n        )?\n    ;\n\ndbcc_checkdb_table_option\n    : ALL_ERRORMSGS\n    | EXTENDED_LOGICAL_CHECKS\n    | NO_INFOMSGS\n    | TABLOCK\n    | ESTIMATEONLY\n    | PHYSICAL_ONLY\n    | DATA_PURITY\n    | MAXDOP '=' max_dregree_of_parallelism=DECIMAL\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-checkdb-transact-sql?view=sql-server-ver16\ndbcc_checkdb\n    : name=CHECKDB\n        (\n            '('\n                ( database=id_ | databasename=STRING | DECIMAL )\n                (\n                    ',' (\n                            NOINDEX\n                            | REPAIR_ALLOW_DATA_LOSS\n                            | REPAIR_FAST\n                            | REPAIR_REBUILD\n                    )\n                )?\n            ')'\n        )?\n        (\n            WITH dbcc_option=dbcc_checkdb_table_option (',' dbcc_option=dbcc_checkdb_table_option)*\n        )?\n    ;\n\ndbcc_checkfilegroup_option\n    : ALL_ERRORMSGS\n    | NO_INFOMSGS\n    | TABLOCK\n    | ESTIMATEONLY\n    | PHYSICAL_ONLY\n    | MAXDOP '=' max_dregree_of_parallelism=DECIMAL\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-checkfilegroup-transact-sql?view=sql-server-ver16\n// Additional parameters: https://dbtut.com/index.php/2019/01/01/dbcc-checkfilegroup-command-on-sql-server/\ndbcc_checkfilegroup\n    : name=CHECKFILEGROUP\n        (\n            '('\n                ( filegroup_id=DECIMAL | filegroup_name=STRING )\n                (\n                    ',' (\n                            NOINDEX\n                            | REPAIR_ALLOW_DATA_LOSS\n                            | REPAIR_FAST\n                            | REPAIR_REBUILD\n                    )\n                )?\n            ')'\n        )?\n        (\n            WITH dbcc_option=dbcc_checkfilegroup_option (',' dbcc_option=dbcc_checkfilegroup_option)*\n        )?\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-checktable-transact-sql?view=sql-server-ver16\ndbcc_checktable\n    : name=CHECKTABLE\n        '('\n            table_or_view_name=STRING\n            ( ',' (\n                    NOINDEX\n                    | index_id=expression\n                    | REPAIR_ALLOW_DATA_LOSS\n                    | REPAIR_FAST\n                    | REPAIR_REBUILD\n                )\n            )?\n        ')'\n        (\n            WITH dbcc_option=dbcc_checkdb_table_option (',' dbcc_option=dbcc_checkdb_table_option)*\n        )?\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-cleantable-transact-sql?view=sql-server-ver16\ndbcc_cleantable\n    : name=CLEANTABLE\n        '('\n            ( database=id_ | databasename=STRING | DECIMAL )\n            ',' ( table_or_view=id_ | table_or_view_name=STRING )\n            ( ',' batch_size=DECIMAL )?\n        ')'\n        ( WITH dbcc_option=NO_INFOMSGS )?\n    ;\n\ndbcc_clonedatabase_option\n    : NO_STATISTICS\n    | NO_QUERYSTORE\n    | SERVICEBROKER\n    | VERIFY_CLONEDB\n    | BACKUP_CLONEDB\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-clonedatabase-transact-sql?view=sql-server-ver16\ndbcc_clonedatabase\n    : name=CLONEDATABASE\n        '('\n            source_database=id_\n            ',' target_database=id_\n        ')'\n        ( WITH dbcc_option=dbcc_clonedatabase_option (',' dbcc_option=dbcc_clonedatabase_option)* )?\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-pdw-showspaceused-transact-sql?view=aps-pdw-2016-au7\ndbcc_pdw_showspaceused\n    : name=PDW_SHOWSPACEUSED ( '(' tablename=id_ ')' ) ? ( WITH dbcc_option=IGNORE_REPLICATED_TABLE_CACHE )? ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-proccache-transact-sql?view=sql-server-ver16\ndbcc_proccache\n    : name=PROCCACHE ( WITH dbcc_option=NO_INFOMSGS )? ;\n\ndbcc_showcontig_option\n    : ALL_INDEXES\n    | TABLERESULTS\n    | FAST\n    | ALL_LEVELS\n    | NO_INFOMSGS\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-showcontig-transact-sql?view=sql-server-ver16\ndbcc_showcontig\n    : name=SHOWCONTIG\n        (\n            '('\n                table_or_view=expression\n                (\n                    ',' index=expression\n                )?\n            ')'\n        )?\n        ( WITH dbcc_option=dbcc_showcontig_option (',' dbcc_showcontig_option)* )?\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-shrinklog-azure-sql-data-warehouse?view=aps-pdw-2016-au7\ndbcc_shrinklog\n    : name=SHRINKLOG\n        ('(' SIZE '=' ( (DECIMAL ( MB | GB | TB ) ) | DEFAULT ) ')')?\n        ( WITH dbcc_option=NO_INFOMSGS )?\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-dbreindex-transact-sql?view=sql-server-ver16\ndbcc_dbreindex\n    : name=DBREINDEX\n        '('\n            table=id_or_string\n            ( ',' index_name=id_or_string ( ',' fillfactor=expression)? )?\n        ')'\n        (\n            WITH dbcc_option=NO_INFOMSGS\n        )?\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-dllname-free-transact-sql?view=sql-server-ver16\ndbcc_dll_free\n    : dllname=id_\n        '(' name=FREE ')'\n        (\n            WITH dbcc_option=NO_INFOMSGS\n        )?\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-dropcleanbuffers-transact-sql?view=sql-server-ver16\ndbcc_dropcleanbuffers\n    : name=DROPCLEANBUFFERS\n        (\n            '('\n                COMPUTE | ALL\n            ')'\n        )?\n        (\n            WITH dbcc_option=NO_INFOMSGS\n        )?\n    ;\n\ndbcc_clause\n    : DBCC (\n        dbcc_checkalloc\n        | dbcc_checkcatalog\n        | dbcc_checkconstraints\n        | dbcc_checkdb\n        | dbcc_checkfilegroup\n        | dbcc_checktable\n        | dbcc_cleantable\n        | dbcc_clonedatabase\n        | dbcc_dbreindex\n        | dbcc_dll_free\n        | dbcc_dropcleanbuffers\n        | dbcc_pdw_showspaceused\n        | dbcc_proccache\n        | dbcc_showcontig\n        | dbcc_shrinklog\n    )\n    ;\n\nexecute_clause\n    : EXECUTE AS clause=(CALLER | SELF | OWNER | STRING)\n    ;\n\ndeclare_local\n    : LOCAL_ID AS? data_type ('=' expression)?\n    ;\n\ntable_type_definition\n    : TABLE '(' column_def_table_constraints (','? table_type_indices)*  ')'\n    ;\n\ntable_type_indices\n    :  (((PRIMARY KEY | INDEX id_) (CLUSTERED | NONCLUSTERED)?) | UNIQUE) '(' column_name_list_with_order ')'\n    | CHECK '(' search_condition ')'\n    ;\n\nxml_type_definition\n    : XML '(' ( CONTENT | DOCUMENT )? xml_schema_collection ')'\n    ;\n\nxml_schema_collection\n    : ID '.' ID\n    ;\n\ncolumn_def_table_constraints\n    : column_def_table_constraint (','? column_def_table_constraint)*\n    ;\n\ncolumn_def_table_constraint\n    : column_definition\n    | materialized_column_definition\n    | table_constraint\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms187742.aspx\n// There is a documentation error: column definition elements can be given in\n// any order\ncolumn_definition\n    : id_ (data_type | AS expression PERSISTED? )\n      column_definition_element*\n      column_index?\n    ;\n\ncolumn_definition_element\n    : FILESTREAM\n    | COLLATE collation_name=id_\n    | SPARSE\n    | MASKED WITH '(' FUNCTION '=' mask_function=STRING ')'\n    | (CONSTRAINT constraint=id_)? DEFAULT  constant_expr=expression\n    | IDENTITY ('(' seed=DECIMAL ',' increment=DECIMAL ')')?\n    | NOT FOR REPLICATION\n    | GENERATED ALWAYS AS ( ROW | TRANSACTION_ID | SEQUENCE_NUMBER ) ( START | END ) HIDDEN_KEYWORD?\n    // NULL / NOT NULL is a constraint\n    | ROWGUIDCOL\n    | ENCRYPTED WITH\n        '(' COLUMN_ENCRYPTION_KEY '=' key_name=STRING ','\n            ENCRYPTION_TYPE '=' ( DETERMINISTIC | RANDOMIZED ) ','\n            ALGORITHM '=' algo=STRING\n        ')'\n    | column_constraint\n    ;\n\ncolumn_modifier\n    : id_ (ADD | DROP) (\n      ROWGUIDCOL\n      | PERSISTED\n      | NOT FOR REPLICATION\n      | SPARSE\n      | HIDDEN_KEYWORD\n      | MASKED (WITH (FUNCTION EQUAL STRING | LR_BRACKET FUNCTION EQUAL STRING RR_BRACKET))?)\n    ;\n\nmaterialized_column_definition\n    : id_ (COMPUTE | AS) expression (MATERIALIZED | NOT MATERIALIZED)?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms186712.aspx\n// There is a documentation error: NOT NULL is a constraint\n// and therefore can be given a name.\ncolumn_constraint\n    : (CONSTRAINT constraint=id_)?\n      (\n        null_notnull\n      | (\n            (PRIMARY KEY | UNIQUE)\n            clustered?\n            primary_key_options\n        )\n      | (\n            (FOREIGN KEY)?\n            foreign_key_options\n        )\n      | check_constraint\n      )\n    ;\n\ncolumn_index\n    :\n        INDEX index_name=id_ clustered?\n        create_table_index_options?\n        on_partition_or_filegroup?\n        ( FILESTREAM_ON ( filestream_filegroup_or_partition_schema_name=id_ | NULL_DOUBLE_QUOTE ) )?\n    ;\n\non_partition_or_filegroup\n    :\n        ON (\n            (partition_scheme_name=id_ '(' partition_column_name=id_ ')')\n            | filegroup=id_\n            | DEFAULT_DOUBLE_QUOTE\n        )\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms188066.aspx\ntable_constraint\n    : (CONSTRAINT constraint=id_)?\n        (\n            (\n                (PRIMARY KEY | UNIQUE)\n                clustered?\n                '(' column_name_list_with_order ')'\n                primary_key_options\n            )\n            |\n            (\n                FOREIGN KEY\n                '(' fk = column_name_list ')'\n                foreign_key_options\n            )\n            |\n            (\n                CONNECTION\n                '(' connection_node ( ',' connection_node )* ')'\n            )\n            |\n            (\n                DEFAULT constant_expr=expression FOR column=id_ (WITH VALUES)?\n            )\n            | check_constraint\n        )\n    ;\n\nconnection_node\n    :\n        from_node_table=id_ TO to_node_table=id_\n    ;\n\nprimary_key_options\n    :\n        (WITH FILLFACTOR '=' DECIMAL)?\n        alter_table_index_options?\n        on_partition_or_filegroup?\n    ;\n\nforeign_key_options\n    :\n        REFERENCES table_name '(' pk = column_name_list')'\n        (on_delete | on_update)*\n        (NOT FOR REPLICATION)?\n    ;\n\ncheck_constraint\n    :\n    CHECK (NOT FOR REPLICATION)? '(' search_condition ')'\n    ;\n\non_delete\n    : ON DELETE (NO ACTION | CASCADE | SET NULL_ | SET DEFAULT)\n    ;\n\non_update\n    : ON UPDATE (NO ACTION | CASCADE | SET NULL_ | SET DEFAULT)\n    ;\n\nalter_table_index_options\n    : WITH '(' alter_table_index_option (',' alter_table_index_option)* ')'\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms186869.aspx\nalter_table_index_option\n    : PAD_INDEX '=' on_off\n    | FILLFACTOR '=' DECIMAL\n    | IGNORE_DUP_KEY '=' on_off\n    | STATISTICS_NORECOMPUTE '=' on_off\n    | ALLOW_ROW_LOCKS '=' on_off\n    | ALLOW_PAGE_LOCKS '=' on_off\n    | OPTIMIZE_FOR_SEQUENTIAL_KEY '=' on_off\n    | SORT_IN_TEMPDB '=' on_off\n    | MAXDOP '=' max_degree_of_parallelism=DECIMAL\n    | DATA_COMPRESSION '=' (NONE | ROW | PAGE | COLUMNSTORE | COLUMNSTORE_ARCHIVE)\n        on_partitions?\n    | XML_COMPRESSION '=' on_off\n        on_partitions?\n    | DISTRIBUTION '=' HASH '(' id_ ')' | CLUSTERED INDEX '(' id_ (ASC | DESC)? (',' id_ (ASC | DESC)?)* ')'\n    | ONLINE '=' (ON ('(' low_priority_lock_wait ')')? | OFF)\n    | RESUMABLE '=' on_off\n    | MAX_DURATION '=' times=DECIMAL MINUTES?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms180169.aspx\ndeclare_cursor\n    : DECLARE cursor_name\n      (CURSOR (declare_set_cursor_common (FOR UPDATE (OF column_name_list)?)?)?\n      | (SEMI_SENSITIVE | INSENSITIVE)? SCROLL? CURSOR FOR select_statement_standalone (FOR (READ ONLY | UPDATE | (OF column_name_list)))?\n      ) ';'?\n    ;\n\ndeclare_set_cursor_common\n    : declare_set_cursor_common_partial*\n      FOR select_statement_standalone\n    ;\n\ndeclare_set_cursor_common_partial\n    : (LOCAL | GLOBAL)\n    | (FORWARD_ONLY | SCROLL)\n    | (STATIC | KEYSET | DYNAMIC | FAST_FORWARD)\n    | (READ_ONLY | SCROLL_LOCKS | OPTIMISTIC)\n    | TYPE_WARNING\n    ;\n\nfetch_cursor\n    : FETCH ((NEXT | PRIOR | FIRST | LAST | (ABSOLUTE | RELATIVE) expression)? FROM)?\n      GLOBAL? cursor_name (INTO LOCAL_ID (',' LOCAL_ID)*)? ';'?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms190356.aspx\n// Runtime check.\nset_special\n    : SET id_ (id_ | constant_LOCAL_ID | on_off) ';'?\n    | SET STATISTICS (IO | TIME | XML | PROFILE) on_off ';'?\n    | SET ROWCOUNT (LOCAL_ID | DECIMAL) ';'?\n    | SET TEXTSIZE DECIMAL ';'?\n    // https://msdn.microsoft.com/en-us/library/ms173763.aspx\n    | SET TRANSACTION ISOLATION LEVEL\n      (READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SNAPSHOT | SERIALIZABLE | DECIMAL) ';'?\n    // https://msdn.microsoft.com/en-us/library/ms188059.aspx\n    | SET IDENTITY_INSERT table_name on_off ';'?\n    | SET special_list (',' special_list)* on_off\n    | SET modify_method\n    ;\n\nspecial_list\n    : ANSI_NULLS\n    | QUOTED_IDENTIFIER\n    | ANSI_PADDING\n    | ANSI_WARNINGS\n    | ANSI_DEFAULTS\n    | ANSI_NULL_DFLT_OFF\n    | ANSI_NULL_DFLT_ON\n    | ARITHABORT\n    | ARITHIGNORE\n    | CONCAT_NULL_YIELDS_NULL\n    | CURSOR_CLOSE_ON_COMMIT\n    | FMTONLY\n    | FORCEPLAN\n    | IMPLICIT_TRANSACTIONS\n    | NOCOUNT\n    | NOEXEC\n    | NUMERIC_ROUNDABORT\n    | PARSEONLY\n    | REMOTE_PROC_TRANSACTIONS\n    | SHOWPLAN_ALL\n    | SHOWPLAN_TEXT\n    | SHOWPLAN_XML\n    | XACT_ABORT\n    ;\n\nconstant_LOCAL_ID\n    : constant\n    | LOCAL_ID\n    ;\n\n// Expression.\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/expressions-transact-sql\n// Operator precendence: https://docs.microsoft.com/en-us/sql/t-sql/language-elements/operator-precedence-transact-sql\nexpression\n    : primitive_expression\n    | function_call\n    | expression '.' (value_call | query_call | exist_call | modify_call)\n    | expression '.' hierarchyid_call\n    | expression COLLATE id_\n    | case_expression\n    | full_column_name\n    | bracket_expression\n    | unary_operator_expression\n    | expression op=('*' | '/' | '%') expression\n    | expression op=('+' | '-' | '&' | '^' | '|' | '||') expression\n    | expression time_zone\n    | over_clause\n    | DOLLAR_ACTION\n    ;\n\nparameter\n    : PLACEHOLDER;\n\ntime_zone\n    : AT_KEYWORD TIME ZONE expression\n    ;\n\nprimitive_expression\n    : DEFAULT | NULL_ | LOCAL_ID | primitive_constant\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/language-elements/case-transact-sql\ncase_expression\n    : CASE caseExpr=expression switch_section+ (ELSE elseExpr=expression)? END\n    | CASE switch_search_condition_section+ (ELSE elseExpr=expression)? END\n    ;\n\nunary_operator_expression\n    : '~' expression\n    | op=('+' | '-') expression\n    ;\n\nbracket_expression\n    : '(' expression ')' | '(' subquery ')'\n    ;\n\nsubquery\n    : select_statement\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms175972.aspx\nwith_expression\n    : WITH ctes+=common_table_expression (',' ctes+=common_table_expression)*\n    ;\n\ncommon_table_expression\n    : expression_name=id_ ('(' columns=column_name_list ')')? AS '(' cte_query=select_statement ')'\n    ;\n\nupdate_elem\n    : LOCAL_ID '=' full_column_name ('=' | assignment_operator) expression //Combined variable and column update\n    | (full_column_name | LOCAL_ID) ('=' | assignment_operator) expression\n    | udt_column_name=id_ '.' method_name=id_ '(' expression_list_ ')'\n    //| full_column_name '.' WRITE (expression, )\n    ;\n\nupdate_elem_merge\n    : (full_column_name | LOCAL_ID) ('=' | assignment_operator) expression\n    | udt_column_name=id_ '.' method_name=id_ '(' expression_list_ ')'\n    //| full_column_name '.' WRITE (expression, )\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/queries/search-condition-transact-sql\nsearch_condition\n    : NOT* (predicate | '(' search_condition ')')\n    | search_condition AND search_condition // AND takes precedence over OR\n    | search_condition OR search_condition\n    ;\n\npredicate\n    : EXISTS '(' subquery ')'\n    | freetext_predicate\n    | expression comparison_operator expression\n    | expression MULT_ASSIGN expression ////SQL-82 syntax for left outer joins; '*='. See https://stackoverflow.com/questions/40665/in-sybase-sql\n    | expression comparison_operator (ALL | SOME | ANY) '(' subquery ')'\n    | expression NOT* BETWEEN expression AND expression\n    | expression NOT* IN '(' (subquery | expression_list_) ')'\n    | expression NOT* LIKE expression (ESCAPE expression)?\n    | expression IS null_notnull\n    ;\n\n// Changed union rule to sql_union to avoid union construct with C++ target.  Issue reported by person who generates into C++.  This individual reports change causes generated code to work\n\nquery_expression\n    : query_specification select_order_by_clause? unions+=sql_union* //if using top, order by can be on the \"top\" side of union :/\n    | '(' query_expression ')' (UNION ALL? query_expression)?\n    ;\n\nsql_union\n    : (UNION ALL? | EXCEPT | INTERSECT) (spec=query_specification | ('(' op=query_expression ')'))\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms176104.aspx\nquery_specification\n    : SELECT allOrDistinct=(ALL | DISTINCT)? top=top_clause?\n      columns=select_list\n      // https://msdn.microsoft.com/en-us/library/ms188029.aspx\n      (INTO into=table_name)?\n      (FROM from=table_sources)?\n      (WHERE where=search_condition)?\n      // https://msdn.microsoft.com/en-us/library/ms177673.aspx\n      (GROUP BY ((groupByAll=ALL? groupBys+=group_by_item (',' groupBys+=group_by_item)*) | GROUPING SETS '(' groupSets+=grouping_sets_item (',' groupSets+=grouping_sets_item)* ')'))?\n      (HAVING having=search_condition)?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms189463.aspx\ntop_clause\n    : TOP (top_percent | top_count) (WITH TIES)?\n    ;\n\ntop_percent\n    : percent_constant=(REAL | FLOAT | DECIMAL) PERCENT\n    | '(' topper_expression=expression ')' PERCENT\n    ;\n\ntop_count\n    : count_constant=DECIMAL\n    | '(' topcount_expression=expression ')'\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql?view=sql-server-ver16\norder_by_clause\n    : ORDER BY order_bys+=order_by_expression (',' order_bys+=order_by_expression)*\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms188385.aspx\nselect_order_by_clause\n    : order_by_clause\n      (OFFSET offset_exp=expression offset_rows=(ROW | ROWS) (FETCH fetch_offset=(FIRST | NEXT) fetch_exp=expression fetch_rows=(ROW | ROWS) ONLY)?)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/queries/select-for-clause-transact-sql\nfor_clause\n    : FOR BROWSE\n    | FOR XML (RAW ('(' STRING ')')? | AUTO) xml_common_directives*\n      (COMMA (XMLDATA | XMLSCHEMA ('(' STRING ')')?))?\n      (COMMA ELEMENTS (XSINIL | ABSENT)?)?\n    | FOR XML EXPLICIT xml_common_directives*\n      (COMMA XMLDATA)?\n    | FOR XML PATH ('(' STRING ')')? xml_common_directives*\n      (COMMA ELEMENTS (XSINIL | ABSENT)?)?\n    | FOR JSON (AUTO | PATH)\n      ( COMMA\n        ( ROOT ('(' STRING ')')\n        | INCLUDE_NULL_VALUES\n        | WITHOUT_ARRAY_WRAPPER\n        )\n      )*\n    ;\n\nxml_common_directives\n    : ',' (BINARY_KEYWORD BASE64 | TYPE | ROOT ('(' STRING ')')?)\n    ;\n\norder_by_expression\n    : order_by=expression (ascending=ASC | descending=DESC)?\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/queries/select-group-by-transact-sql?view=sql-server-ver15\ngrouping_sets_item\n    : '('? groupSetItems+=group_by_item (',' groupSetItems+=group_by_item)* ')'?\n    | '(' ')'\n    ;\n\ngroup_by_item\n    : expression\n    /*| rollup_spec\n    | cube_spec\n    | grouping_sets_spec\n    | grand_total*/\n    ;\n\noption_clause\n    // https://msdn.microsoft.com/en-us/library/ms181714.aspx\n    : OPTION '(' options_ += option (',' options_ += option)* ')'\n    ;\n\noption\n    : FAST number_rows=DECIMAL\n    | (HASH | ORDER) GROUP\n    | (MERGE | HASH | CONCAT) UNION\n    | (LOOP | MERGE | HASH) JOIN\n    | EXPAND VIEWS\n    | FORCE ORDER\n    | IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX\n    | KEEP PLAN\n    | KEEPFIXED PLAN\n    | MAXDOP number_of_processors=DECIMAL\n    | MAXRECURSION number_recursion=DECIMAL\n    | OPTIMIZE FOR '(' optimize_for_arg (',' optimize_for_arg)* ')'\n    | OPTIMIZE FOR UNKNOWN\n    | PARAMETERIZATION (SIMPLE | FORCED)\n    | RECOMPILE\n    | ROBUST PLAN\n    | USE PLAN STRING\n    ;\n\noptimize_for_arg\n    : LOCAL_ID (UNKNOWN | '=' (constant | NULL_))\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms176104.aspx\nselect_list\n    : selectElement+=select_list_elem (',' selectElement+=select_list_elem)*\n    ;\n\nudt_method_arguments\n    : '(' argument+=execute_var_string (',' argument+=execute_var_string)* ')'\n    ;\n\n// https://docs.microsoft.com/ru-ru/sql/t-sql/queries/select-clause-transact-sql\nasterisk\n    : (table_name '.')? '*'\n    | (INSERTED | DELETED) '.' '*'\n    ;\n\nudt_elem\n    : udt_column_name=id_ '.' non_static_attr=id_ udt_method_arguments as_column_alias?\n    | udt_column_name=id_ DOUBLE_COLON static_attr=id_ udt_method_arguments? as_column_alias?\n    ;\n\nexpression_elem\n    : leftAlias=column_alias eq='=' leftAssignment=expression\n    | expressionAs=expression as_column_alias?\n    ;\n\nselect_list_elem\n    : asterisk\n    | udt_elem\n    | LOCAL_ID (assignment_operator | '=') expression\n    | expression_elem\n    ;\n\ntable_sources\n    : non_ansi_join\n    | source+=table_source (',' source+=table_source)*\n    ;\n\n// https://sqlenlight.com/support/help/sa0006/\nnon_ansi_join\n    : source+=table_source (',' source+=table_source)+\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/queries/from-transact-sql\ntable_source\n    : table_source_item joins+=join_part*\n    ;\n\ntable_source_item\n    : full_table_name             deprecated_table_hint as_table_alias // this is currently allowed\n    | full_table_name             as_table_alias? (with_table_hints | deprecated_table_hint | sybase_legacy_hints)?\n    | rowset_function             as_table_alias?\n    | '(' derived_table ')'       (as_table_alias column_alias_list?)?\n    | change_table                as_table_alias?\n    | nodes_method                (as_table_alias column_alias_list?)?\n    | function_call               (as_table_alias column_alias_list?)?\n    | loc_id=LOCAL_ID             as_table_alias?\n    | loc_id_call=LOCAL_ID '.' loc_fcall=function_call (as_table_alias column_alias_list?)?\n    | open_xml\n    | open_json\n    | DOUBLE_COLON oldstyle_fcall=function_call       as_table_alias? // Build-in function (old syntax)\n    | '(' table_source ')'\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/functions/openxml-transact-sql\nopen_xml\n    : OPENXML '(' expression ',' expression (',' expression)? ')'\n    (WITH '(' schema_declaration ')' )? as_table_alias?\n    ;\n\nopen_json\n    : OPENJSON '(' expression (',' expression)? ')'\n    (WITH '(' json_declaration ')' )? as_table_alias?\n    ;\n\njson_declaration\n    : json_col+=json_column_declaration (',' json_col+=json_column_declaration)*\n    ;\n\njson_column_declaration\n    : column_declaration (AS JSON)?\n    ;\n\nschema_declaration\n    : xml_col+=column_declaration (',' xml_col+=column_declaration)*\n    ;\n\ncolumn_declaration\n    : id_ data_type STRING?\n    ;\n\nchange_table\n    : change_table_changes\n    | change_table_version\n    ;\n\nchange_table_changes\n    : CHANGETABLE '(' CHANGES changetable=table_name ',' changesid=(NULL_ | DECIMAL | LOCAL_ID) ')'\n    ;\nchange_table_version\n    : CHANGETABLE '(' VERSION versiontable=table_name ',' pk_columns=full_column_name_list ',' pk_values=select_list  ')'\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms191472.aspx\njoin_part\n    // https://msdn.microsoft.com/en-us/library/ms173815(v=sql.120).aspx\n    : join_on\n    | cross_join\n    | apply_\n    | pivot\n    | unpivot\n    ;\njoin_on\n    : (inner=INNER? | join_type=(LEFT | RIGHT | FULL) outer=OUTER?) (join_hint=(LOOP | HASH | MERGE | REMOTE))?\n       JOIN source=table_source ON cond=search_condition\n    ;\n\ncross_join\n    : CROSS JOIN table_source_item\n    ;\n\napply_\n    : apply_style=(CROSS | OUTER) APPLY source=table_source_item\n    ;\n\npivot\n    : PIVOT pivot_clause as_table_alias\n    ;\n\nunpivot\n    : UNPIVOT unpivot_clause as_table_alias\n    ;\n\npivot_clause\n    : '(' aggregate_windowed_function FOR full_column_name IN column_alias_list ')'\n    ;\n\nunpivot_clause\n    : '(' unpivot_exp=expression FOR full_column_name IN '(' full_column_name_list ')' ')'\n    ;\n\nfull_column_name_list\n    : column+=full_column_name (',' column+=full_column_name)*\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms190312.aspx\nrowset_function\n    :  (\n        OPENROWSET LR_BRACKET provider_name = STRING COMMA connectionString = STRING COMMA sql = STRING RR_BRACKET\n     )\n     | ( OPENROWSET '(' BULK data_file=STRING ',' (bulk_option (',' bulk_option)* | id_)')' )\n    ;\n\n// runtime check.\nbulk_option\n    : id_ '=' bulk_option_value=(DECIMAL | STRING)\n    ;\n\nderived_table\n    : subquery\n    | '(' subquery (UNION ALL subquery)* ')'\n    | table_value_constructor\n    | '(' table_value_constructor ')'\n    ;\n\nfunction_call\n    : ranking_windowed_function                         #RANKING_WINDOWED_FUNC\n    | aggregate_windowed_function                       #AGGREGATE_WINDOWED_FUNC\n    | analytic_windowed_function                        #ANALYTIC_WINDOWED_FUNC\n    | built_in_functions                                #BUILT_IN_FUNC\n    | scalar_function_name '(' expression_list_? ')'     #SCALAR_FUNCTION\n    | freetext_function                                 #FREE_TEXT\n    | partition_function                                #PARTITION_FUNC\n    | hierarchyid_static_method                         #HIERARCHYID_METHOD\n    ;\n\npartition_function\n    : (database=id_ '.')? DOLLAR_PARTITION '.' func_name=id_ '(' expression ')'\n    ;\n\nfreetext_function\n    : (CONTAINSTABLE | FREETEXTTABLE) '(' table_name ',' (full_column_name | '(' full_column_name (',' full_column_name)* ')' | '*' ) ',' expression  (',' LANGUAGE expression)? (',' expression)? ')'\n    | (SEMANTICSIMILARITYTABLE | SEMANTICKEYPHRASETABLE) '(' table_name ',' (full_column_name | '(' full_column_name (',' full_column_name)* ')' | '*' ) ',' expression ')'\n    | SEMANTICSIMILARITYDETAILSTABLE '(' table_name ',' full_column_name ',' expression ',' full_column_name ',' expression ')'\n    ;\n\nfreetext_predicate\n    : CONTAINS '(' (full_column_name | '(' full_column_name (',' full_column_name)* ')' | '*' | PROPERTY '(' full_column_name ',' expression ')') ',' expression ')'\n    | FREETEXT '(' table_name ',' (full_column_name | '(' full_column_name (',' full_column_name)* ')' | '*' ) ',' expression  (',' LANGUAGE expression)? ')'\n    ;\n\njson_key_value\n    : json_key_name=expression ':' value_expression=expression\n    ;\n\njson_null_clause\n    : (ABSENT | NULL_) ON NULL_\n    ;\n\nbuilt_in_functions\n    // Metadata functions\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/app-name-transact-sql?view=sql-server-ver16\n    : APP_NAME '(' ')'                                                      #APP_NAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/applock-mode-transact-sql?view=sql-server-ver16\n    | APPLOCK_MODE '(' database_principal=expression ',' resource_name=expression ',' lock_owner=expression ')' #APPLOCK_MODE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/applock-test-transact-sql?view=sql-server-ver16\n    | APPLOCK_TEST '(' database_principal=expression ',' resource_name=expression ',' lock_mode=expression ',' lock_owner=expression ')' #APPLOCK_TEST\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/assemblyproperty-transact-sql?view=sql-server-ver16\n    | ASSEMBLYPROPERTY '(' assembly_name=expression ',' property_name=expression ')' #ASSEMBLYPROPERTY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/col-length-transact-sql?view=sql-server-ver16\n    | COL_LENGTH '(' table=expression ',' column=expression ')'             #COL_LENGTH\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/col-name-transact-sql?view=sql-server-ver16\n    | COL_NAME '(' table_id=expression ',' column_id=expression ')'         #COL_NAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/columnproperty-transact-sql?view=sql-server-ver16\n    | COLUMNPROPERTY '(' id=expression ',' column=expression ',' property=expression ')' #COLUMNPROPERTY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/databasepropertyex-transact-sql?view=sql-server-ver16\n    | DATABASEPROPERTYEX '(' database=expression ',' property=expression ')' #DATABASEPROPERTYEX\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/db-id-transact-sql?view=sql-server-ver16\n    | DB_ID '(' database_name=expression? ')'                               #DB_ID\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/db-name-transact-sql?view=sql-server-ver16\n    | DB_NAME '(' database_id=expression? ')'                               #DB_NAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/file-id-transact-sql?view=sql-server-ver16\n    | FILE_ID '(' file_name=expression ')'                                  #FILE_ID\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/file-idex-transact-sql?view=sql-server-ver16\n    | FILE_IDEX '(' file_name=expression ')'                                #FILE_IDEX\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/file-name-transact-sql?view=sql-server-ver16\n    | FILE_NAME '(' file_id=expression ')'                                  #FILE_NAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/filegroup-id-transact-sql?view=sql-server-ver16\n    | FILEGROUP_ID '(' filegroup_name=expression ')'                        #FILEGROUP_ID\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/filegroup-name-transact-sql?view=sql-server-ver16\n    | FILEGROUP_NAME '(' filegroup_id=expression ')'                        #FILEGROUP_NAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/filegroupproperty-transact-sql?view=sql-server-ver16\n    | FILEGROUPPROPERTY '(' filegroup_name=expression ',' property=expression ')' #FILEGROUPPROPERTY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/fileproperty-transact-sql?view=sql-server-ver16\n    | FILEPROPERTY '(' file_name=expression ',' property=expression ')'     #FILEPROPERTY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/filepropertyex-transact-sql?view=sql-server-ver16\n    | FILEPROPERTYEX '(' name=expression ',' property=expression ')'        #FILEPROPERTYEX\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/fulltextcatalogproperty-transact-sql?view=sql-server-ver16\n    | FULLTEXTCATALOGPROPERTY '(' catalog_name=expression ',' property=expression ')' #FULLTEXTCATALOGPROPERTY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/fulltextserviceproperty-transact-sql?view=sql-server-ver16\n    | FULLTEXTSERVICEPROPERTY '(' property=expression ')'                   #FULLTEXTSERVICEPROPERTY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/index-col-transact-sql?view=sql-server-ver16\n    | INDEX_COL '(' table_or_view_name=expression ',' index_id=expression ',' key_id=expression ')' #INDEX_COL\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/indexkey-property-transact-sql?view=sql-server-ver16\n    | INDEXKEY_PROPERTY '(' object_id=expression ',' index_id=expression ',' key_id=expression ',' property=expression ')' #INDEXKEY_PROPERTY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/indexproperty-transact-sql?view=sql-server-ver16\n    | INDEXPROPERTY '(' object_id=expression ',' index_or_statistics_name=expression ',' property=expression ')' #INDEXPROPERTY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16\n    | NEXT VALUE FOR sequence_name=table_name ( OVER '(' order_by_clause ')' )? #NEXT_VALUE_FOR\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/object-definition-transact-sql?view=sql-server-ver16\n    | OBJECT_DEFINITION '(' object_id=expression ')'                        #OBJECT_DEFINITION\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/object-id-transact-sql?view=sql-server-ver16\n    | OBJECT_ID '(' object_name=expression ( ',' object_type=expression )? ')'      #OBJECT_ID\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/object-name-transact-sql?view=sql-server-ver16\n    | OBJECT_NAME '(' object_id=expression ( ',' database_id=expression )? ')' #OBJECT_NAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/object-schema-name-transact-sql?view=sql-server-ver16\n    | OBJECT_SCHEMA_NAME '(' object_id=expression ( ',' database_id=expression )? ')' #OBJECT_SCHEMA_NAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/objectproperty-transact-sql?view=sql-server-ver16\n    | OBJECTPROPERTY '(' id=expression ',' property=expression ')'          #OBJECTPROPERTY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/objectpropertyex-transact-sql?view=sql-server-ver16\n    | OBJECTPROPERTYEX '(' id=expression ',' property=expression ')'        #OBJECTPROPERTYEX\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/original-db-name-transact-sql?view=sql-server-ver16\n    | ORIGINAL_DB_NAME '(' ')'                                              #ORIGINAL_DB_NAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/parsename-transact-sql?view=sql-server-ver16\n    | PARSENAME '(' object_name=expression ',' object_piece=expression ')'  #PARSENAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/schema-id-transact-sql?view=sql-server-ver16\n    | SCHEMA_ID '(' schema_name=expression? ')'                             #SCHEMA_ID\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/schema-name-transact-sql?view=sql-server-ver16\n    | SCHEMA_NAME '(' schema_id=expression? ')'                             #SCHEMA_NAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql?view=sql-server-ver16\n    | SCOPE_IDENTITY '(' ')'                                                #SCOPE_IDENTITY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/serverproperty-transact-sql?view=sql-server-ver16\n    | SERVERPROPERTY '(' property=expression ')'                            #SERVERPROPERTY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/stats-date-transact-sql?view=sql-server-ver16\n    | STATS_DATE '(' object_id=expression ',' stats_id=expression ')'       #STATS_DATE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/type-id-transact-sql?view=sql-server-ver16\n    | TYPE_ID '(' type_name=expression ')'                                  #TYPE_ID\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/type-name-transact-sql?view=sql-server-ver16\n    | TYPE_NAME '(' type_id=expression ')'                                  #TYPE_NAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/typeproperty-transact-sql?view=sql-server-ver16\n    | TYPEPROPERTY '(' type=expression ',' property=expression ')'          #TYPEPROPERTY\n    // String functions\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/ascii-transact-sql?view=sql-server-ver16\n    | ASCII '(' character_expression=expression ')'                         #ASCII\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/char-transact-sql?view=sql-server-ver16\n    | CHAR '(' integer_expression=expression ')'                            #CHAR\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/charindex-transact-sql?view=sql-server-ver16\n    | CHARINDEX '(' expressionToFind=expression ',' expressionToSearch=expression ( ',' start_location=expression )? ')' #CHARINDEX\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/concat-transact-sql?view=sql-server-ver16\n    | CONCAT '(' string_value_1=expression ',' string_value_2=expression ( ',' string_value_n+=expression )* ')' #CONCAT\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/concat-ws-transact-sql?view=sql-server-ver16\n    | CONCAT_WS '(' separator=expression ',' argument_1=expression ',' argument_2=expression ( ',' argument_n+=expression )* ')' #CONCAT_WS\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/difference-transact-sql?view=sql-server-ver16\n    | DIFFERENCE '(' character_expression_1=expression ',' character_expression_2=expression ')' #DIFFERENCE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql?view=sql-server-ver16\n    | FORMAT '(' value=expression ',' format=expression ( ',' culture=expression )? ')' #FORMAT\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/left-transact-sql?view=sql-server-ver16\n    | LEFT '(' character_expression=expression ',' integer_expression=expression ')' #LEFT\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/len-transact-sql?view=sql-server-ver16\n    | LEN '(' string_expression=expression ')'                              #LEN\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/lower-transact-sql?view=sql-server-ver16\n    | LOWER '(' character_expression=expression ')'                         #LOWER\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/ltrim-transact-sql?view=sql-server-ver16\n    | LTRIM '(' character_expression=expression ')'                         #LTRIM\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/nchar-transact-sql?view=sql-server-ver16\n    | NCHAR '(' integer_expression=expression ')'                           #NCHAR\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/patindex-transact-sql?view=sql-server-ver16\n    | PATINDEX '(' pattern=expression ',' string_expression=expression ')'  #PATINDEX\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/quotename-transact-sql?view=sql-server-ver16\n    | QUOTENAME '(' character_string=expression ( ',' quote_character=expression )? ')' #QUOTENAME\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/replace-transact-sql?view=sql-server-ver16\n    | REPLACE '(' input=expression ',' replacing=expression ',' with=expression ')'   #REPLACE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/replicate-transact-sql?view=sql-server-ver16\n    | REPLICATE '(' string_expression=expression ',' integer_expression=expression ')' #REPLICATE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/reverse-transact-sql?view=sql-server-ver16\n    | REVERSE '(' string_expression=expression ')'                          #REVERSE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/right-transact-sql?view=sql-server-ver16\n    | RIGHT '(' character_expression=expression ',' integer_expression=expression ')' #RIGHT\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/rtrim-transact-sql?view=sql-server-ver16\n    | RTRIM '(' character_expression=expression ')'                         #RTRIM\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/soundex-transact-sql?view=sql-server-ver16\n    | SOUNDEX '(' character_expression=expression ')'                       #SOUNDEX\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/space-transact-sql?view=sql-server-ver16\n    | SPACE_KEYWORD '(' integer_expression=expression ')'                   #SPACE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/str-transact-sql?view=sql-server-ver16\n    | STR '(' float_expression=expression ( ',' length_expression=expression ( ',' decimal=expression )? )? ')' #STR\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/string-agg-transact-sql?view=sql-server-ver16\n    | STRING_AGG '(' expr=expression ',' separator=expression ')' (WITHIN GROUP '(' order_by_clause ')')?  #STRINGAGG\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/string-escape-transact-sql?view=sql-server-ver16\n    | STRING_ESCAPE '(' text_=expression ',' type_=expression ')'           #STRING_ESCAPE\n    // https://msdn.microsoft.com/fr-fr/library/ms188043.aspx\n    | STUFF '(' str=expression ',' from=expression ',' to=expression ',' str_with=expression ')' #STUFF\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/substring-transact-sql?view=sql-server-ver16\n    | SUBSTRING '(' string_expression=expression ',' start_=expression ',' length=expression ')' #SUBSTRING\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/translate-transact-sql?view=sql-server-ver16\n    | TRANSLATE '(' inputString=expression ',' characters=expression ',' translations=expression ')' #TRANSLATE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/trim-transact-sql?view=sql-server-ver16\n    | TRIM '(' ( characters=expression FROM )? string_=expression ')'       #TRIM\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/unicode-transact-sql?view=sql-server-ver16\n    | UNICODE '(' ncharacter_expression=expression ')'                      #UNICODE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/upper-transact-sql?view=sql-server-ver16\n    | UPPER '(' character_expression=expression ')'                         #UPPER\n    // System functions\n    // https://msdn.microsoft.com/en-us/library/ms173784.aspx\n    | BINARY_CHECKSUM '(' ( star='*' | expression (',' expression)* ) ')'   #BINARY_CHECKSUM\n    // https://msdn.microsoft.com/en-us/library/ms189788.aspx\n    | CHECKSUM '(' ( star='*' | expression (',' expression)* ) ')'          #CHECKSUM\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/compress-transact-sql?view=sql-server-ver16\n    | COMPRESS '(' expr=expression ')'                                      #COMPRESS\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/connectionproperty-transact-sql?view=sql-server-ver16\n    | CONNECTIONPROPERTY '(' property=STRING ')'                            #CONNECTIONPROPERTY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/context-info-transact-sql?view=sql-server-ver16\n    | CONTEXT_INFO '(' ')'                                                  #CONTEXT_INFO\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/current-request-id-transact-sql?view=sql-server-ver16\n    | CURRENT_REQUEST_ID '(' ')'                                            #CURRENT_REQUEST_ID\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/current-transaction-id-transact-sql?view=sql-server-ver16\n    | CURRENT_TRANSACTION_ID '(' ')'                                        #CURRENT_TRANSACTION_ID\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/decompress-transact-sql?view=sql-server-ver16\n    | DECOMPRESS '(' expr=expression ')'                                    #DECOMPRESS\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/error-line-transact-sql?view=sql-server-ver16\n    | ERROR_LINE '(' ')'                                                    #ERROR_LINE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/error-message-transact-sql?view=sql-server-ver16\n    | ERROR_MESSAGE '(' ')'                                                 #ERROR_MESSAGE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/error-number-transact-sql?view=sql-server-ver16\n    | ERROR_NUMBER '(' ')'                                                  #ERROR_NUMBER\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/error-procedure-transact-sql?view=sql-server-ver16\n    | ERROR_PROCEDURE '(' ')'                                               #ERROR_PROCEDURE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/error-severity-transact-sql?view=sql-server-ver16\n    | ERROR_SEVERITY '(' ')'                                                #ERROR_SEVERITY\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/error-state-transact-sql?view=sql-server-ver16\n    | ERROR_STATE '(' ')'                                                   #ERROR_STATE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/formatmessage-transact-sql?view=sql-server-ver16\n    | FORMATMESSAGE '(' (msg_number=DECIMAL | msg_string=STRING | msg_variable=LOCAL_ID) ',' expression (',' expression)* ')' #FORMATMESSAGE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/get-filestream-transaction-context-transact-sql?view=sql-server-ver16\n    | GET_FILESTREAM_TRANSACTION_CONTEXT '(' ')'                            #GET_FILESTREAM_TRANSACTION_CONTEXT\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/getansinull-transact-sql?view=sql-server-ver16\n    | GETANSINULL '(' (database=STRING)? ')'                                #GETANSINULL\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/host-id-transact-sql?view=sql-server-ver16\n    | HOST_ID '(' ')'                                                       #HOST_ID\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/host-name-transact-sql?view=sql-server-ver16\n    | HOST_NAME '(' ')'                                                     #HOST_NAME\n    // https://msdn.microsoft.com/en-us/library/ms184325.aspx\n    | ISNULL '(' left=expression ',' right=expression ')'                   #ISNULL\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/isnumeric-transact-sql?view=sql-server-ver16\n    | ISNUMERIC '(' expression ')'                                          #ISNUMERIC\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/min-active-rowversion-transact-sql?view=sql-server-ver16\n    | MIN_ACTIVE_ROWVERSION '(' ')'                                         #MIN_ACTIVE_ROWVERSION\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/newid-transact-sql?view=sql-server-ver16\n    | NEWID '(' ')'                                                         #NEWID\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/newsequentialid-transact-sql?view=sql-server-ver16\n    | NEWSEQUENTIALID '(' ')'                                               #NEWSEQUENTIALID\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/rowcount-big-transact-sql?view=sql-server-ver16\n    | ROWCOUNT_BIG '(' ')'                                                  #ROWCOUNT_BIG\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/session-context-transact-sql?view=sql-server-ver16\n    | SESSION_CONTEXT '(' key=STRING ')'                                    #SESSION_CONTEXT\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/xact-state-transact-sql?view=sql-server-ver16\n    | XACT_STATE '(' ')'                                                    #XACT_STATE\n    // https://msdn.microsoft.com/en-us/library/hh231076.aspx\n    // https://msdn.microsoft.com/en-us/library/ms187928.aspx\n    | CAST '(' expression AS data_type ')'              #CAST\n    | TRY_CAST '(' expression AS data_type ')'          #TRY_CAST\n    | CONVERT '(' convert_data_type=data_type ','convert_expression=expression (',' style=expression)? ')'                              #CONVERT\n    // https://msdn.microsoft.com/en-us/library/ms190349.aspx\n    | COALESCE '(' expression_list_ ')'                  #COALESCE\n    // Cursor functions\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/cursor-rows-transact-sql?view=sql-server-ver16\n    | CURSOR_ROWS                                       #CURSOR_ROWS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/cursor-rows-transact-sql?view=sql-server-ver16\n    | FETCH_STATUS                                      #FETCH_STATUS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/cursor-status-transact-sql?view=sql-server-ver16\n    | CURSOR_STATUS '(' scope=STRING ',' cursor=expression ')' #CURSOR_STATUS\n    // Cryptographic functions\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/cert-id-transact-sql?view=sql-server-ver16\n    | CERT_ID '(' cert_name=expression ')'              #CERT_ID\n    // Data type functions\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/datalength-transact-sql?view=sql-server-ver16\n    | DATALENGTH '(' expression ')'                     #DATALENGTH\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/ident-current-transact-sql?view=sql-server-ver16\n    | IDENT_CURRENT '(' table_or_view=expression ')'    # IDENT_CURRENT\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/ident-incr-transact-sql?view=sql-server-ver16\n    | IDENT_INCR '(' table_or_view=expression ')'       # IDENT_INCR\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/ident-seed-transact-sql?view=sql-server-ver16\n    | IDENT_SEED '(' table_or_view=expression ')'       # IDENT_SEED\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/ident-seed-transact-sql?view=sql-server-ver16\n    | IDENTITY '(' datatype=data_type (',' seed=DECIMAL ',' increment=DECIMAL)? ')' #IDENTITY\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/ident-seed-transact-sql?view=sql-server-ver16\n    | SQL_VARIANT_PROPERTY '(' expr=expression ',' property=STRING ')' #SQL_VARIANT_PROPERTY\n    // Date functions\n    //https://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc36271.1572/html/blocks/CJADIDHD.htm\n    | CURRENT_DATE '(' ')'                              #CURRENT_DATE\n    // https://msdn.microsoft.com/en-us/library/ms188751.aspx\n    | CURRENT_TIMESTAMP                                 #CURRENT_TIMESTAMP\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/current-timezone-transact-sql?view=sql-server-ver16\n    | CURRENT_TIMEZONE '(' ')'                          #CURRENT_TIMEZONE\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/current-timezone-id-transact-sql?view=sql-server-ver16\n    | CURRENT_TIMEZONE_ID '(' ')'                       #CURRENT_TIMEZONE_ID\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/date-bucket-transact-sql?view=sql-server-ver16\n    | DATE_BUCKET '(' datepart=dateparts_9 ',' number=expression ',' date=expression (',' origin=expression)? ')' #DATE_BUCKET\n    // https://msdn.microsoft.com/en-us/library/ms186819.aspx\n    | DATEADD '(' datepart=dateparts_12 ',' number=expression ',' date=expression ')'  #DATEADD\n    // https://msdn.microsoft.com/en-us/library/ms189794.aspx\n    | DATEDIFF '(' datepart=dateparts_12 ',' date_first=expression ',' date_second=expression ')' #DATEDIFF\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/datediff-big-transact-sql?view=sql-server-ver16\n    | DATEDIFF_BIG '(' datepart=dateparts_12 ',' startdate=expression ',' enddate=expression ')' #DATEDIFF_BIG\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/datefromparts-transact-sql?view=sql-server-ver16\n    | DATEFROMPARTS '(' year=expression ',' month=expression ',' day=expression ')'#DATEFROMPARTS\n    // https://msdn.microsoft.com/en-us/library/ms174395.aspx\n    | DATENAME '(' datepart=dateparts_15 ',' date=expression ')'                #DATENAME\n    // https://msdn.microsoft.com/en-us/library/ms174420.aspx\n    | DATEPART '(' datepart=dateparts_15 ',' date=expression ')'                #DATEPART\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/datetime2fromparts-transact-sql?view=sql-server-ver16\n    | DATETIME2FROMPARTS '(' year=expression ',' month=expression ',' day=expression ',' hour=expression ',' minute=expression ',' seconds=expression ',' fractions=expression ',' precision=expression ')' #DATETIME2FROMPARTS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/datetimefromparts-transact-sql?view=sql-server-ver16\n    | DATETIMEFROMPARTS '(' year=expression ',' month=expression ',' day=expression ',' hour=expression ',' minute=expression ',' seconds=expression ',' milliseconds=expression ')' #DATETIMEFROMPARTS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/datetimeoffsetfromparts-transact-sql?view=sql-server-ver16\n    | DATETIMEOFFSETFROMPARTS '(' year=expression ',' month=expression ',' day=expression ',' hour=expression ',' minute=expression ',' seconds=expression ',' fractions=expression ',' hour_offset=expression ',' minute_offset=expression ',' precision=DECIMAL ')' #DATETIMEOFFSETFROMPARTS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/datetrunc-transact-sql?view=sql-server-ver16\n    | DATETRUNC '(' datepart=dateparts_datetrunc ',' date=expression ')' #DATETRUNC\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/day-transact-sql?view=sql-server-ver16\n    | DAY '(' date=expression ')' #DAY\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/eomonth-transact-sql?view=sql-server-ver16\n    | EOMONTH '(' start_date=expression (',' month_to_add=expression)? ')'#EOMONTH\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/getdate-transact-sql\n    | GETDATE '(' ')'                                   #GETDATE\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/getdate-transact-sql\n    | GETUTCDATE '(' ')'                                #GETUTCDATE\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/isdate-transact-sql?view=sql-server-ver16\n    | ISDATE '(' expression ')' #ISDATE\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/month-transact-sql?view=sql-server-ver16\n    | MONTH '(' date=expression ')' #MONTH\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/smalldatetimefromparts-transact-sql?view=sql-server-ver16\n    | SMALLDATETIMEFROMPARTS '(' year=expression ',' month=expression ',' day=expression ',' hour=expression ',' minute=expression ')' #SMALLDATETIMEFROMPARTS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/switchoffset-transact-sql?view=sql-server-ver16\n    | SWITCHOFFSET '(' datetimeoffset_expression=expression ',' timezoneoffset_expression=expression ')' #SWITCHOFFSET\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/sysdatetime-transact-sql?view=sql-server-ver16\n    | SYSDATETIME '(' ')' #SYSDATETIME\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/sysdatetimeoffset-transact-sql?view=sql-server-ver16\n    | SYSDATETIMEOFFSET '(' ')' #SYSDATETIMEOFFSET\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/sysutcdatetime-transact-sql?view=sql-server-ver16\n    | SYSUTCDATETIME '(' ')' #SYSUTCDATETIME\n    //https://learn.microsoft.com/en-us/sql/t-sql/functions/timefromparts-transact-sql?view=sql-server-ver16\n    | TIMEFROMPARTS '(' hour=expression ',' minute=expression ',' seconds=expression ',' fractions=expression ',' precision=DECIMAL ')' #TIMEFROMPARTS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/todatetimeoffset-transact-sql?view=sql-server-ver16\n    | TODATETIMEOFFSET '(' datetime_expression=expression ',' timezoneoffset_expression=expression ')' #TODATETIMEOFFSET\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/year-transact-sql?view=sql-server-ver16\n    | YEAR '(' date=expression ')' #YEAR\n    // https://msdn.microsoft.com/en-us/library/ms189838.aspx\n    | IDENTITY '(' data_type (',' seed=DECIMAL)? (',' increment=DECIMAL)? ')'                                                           #IDENTITY\n    // https://msdn.microsoft.com/en-us/library/bb839514.aspx\n    | MIN_ACTIVE_ROWVERSION '(' ')'                     #MIN_ACTIVE_ROWVERSION\n    // https://msdn.microsoft.com/en-us/library/ms177562.aspx\n    | NULLIF '(' left=expression ',' right=expression ')'          #NULLIF\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/parse-transact-sql\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/try-parse-transact-sql\n    | PARSE '(' str=expression AS data_type ( USING culture=expression )? ')'          #PARSE\n    // https://docs.microsoft.com/en-us/sql/t-sql/xml/xml-data-type-methods\n    | xml_data_type_methods                             #XML_DATA_TYPE_FUNC\n    // https://docs.microsoft.com/en-us/sql/t-sql/functions/logical-functions-iif-transact-sql\n    | IIF '(' cond=search_condition ',' left=expression ',' right=expression ')'   #IIF\n    // JSON functions\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/isjson-transact-sql?view=azure-sqldw-latest\n    | ISJSON '(' json_expr=expression (',' json_type_constraint=expression)? ')' #ISJSON\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/json-object-transact-sql?view=azure-sqldw-latest\n    | JSON_OBJECT '(' (key_value=json_key_value (',' key_value=json_key_value)*)? json_null_clause? ')' #JSON_OBJECT\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/json-array-transact-sql?view=azure-sqldw-latest\n    | JSON_ARRAY '(' expression_list_? json_null_clause? ')' #JSON_ARRAY\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/json-value-transact-sql?view=azure-sqldw-latest\n    | JSON_VALUE '(' expr=expression ',' path=expression ')' #JSON_VALUE\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/json-query-transact-sql?view=azure-sqldw-latest\n    | JSON_QUERY '(' expr=expression (',' path=expression)? ')' #JSON_QUERY\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/json-modify-transact-sql?view=azure-sqldw-latest\n    | JSON_MODIFY '(' expr=expression ',' path=expression ',' new_value=expression ')' #JSON_MODIFY\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/json-path-exists-transact-sql?view=azure-sqldw-latest\n    | JSON_PATH_EXISTS '(' value_expression=expression ',' sql_json_path=expression ')' #JSON_PATH_EXISTS\n    // Math functions\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/abs-transact-sql?view=sql-server-ver16\n    | ABS '(' numeric_expression=expression ')' #ABS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/acos-transact-sql?view=sql-server-ver16\n    | ACOS '(' float_expression=expression ')' #ACOS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/asin-transact-sql?view=sql-server-ver16\n    | ASIN '(' float_expression=expression ')' #ASIN\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/atan-transact-sql?view=sql-server-ver16\n    | ATAN '(' float_expression=expression ')' #ATAN\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/atn2-transact-sql?view=sql-server-ver16\n    | ATN2 '(' float_expression=expression ',' float_expression=expression ')' #ATN2\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/ceiling-transact-sql?view=sql-server-ver16\n    | CEILING '(' numeric_expression=expression ')' #CEILING\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/cos-transact-sql?view=sql-server-ver16\n    | COS '(' float_expression=expression ')' #COS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/cot-transact-sql?view=sql-server-ver16\n    | COT '(' float_expression=expression ')' #COT\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/degrees-transact-sql?view=sql-server-ver16\n    | DEGREES '(' numeric_expression=expression ')' #DEGREES\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/exp-transact-sql?view=sql-server-ver16\n    | EXP '(' float_expression=expression ')' #EXP\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/floor-transact-sql?view=sql-server-ver16\n    | FLOOR '(' numeric_expression=expression ')' #FLOOR\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/log-transact-sql?view=sql-server-ver16\n    | LOG '(' float_expression=expression (',' base=expression)? ')' #LOG\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/log10-transact-sql?view=sql-server-ver16\n    | LOG10 '(' float_expression=expression ')' #LOG10\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/pi-transact-sql?view=sql-server-ver16\n    | PI '(' ')' #PI\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/power-transact-sql?view=sql-server-ver16\n    | POWER '(' float_expression=expression ',' y=expression ')' #POWER\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/radians-transact-sql?view=sql-server-ver16\n    | RADIANS '(' numeric_expression=expression ')' #RADIANS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/rand-transact-sql?view=sql-server-ver16\n    | RAND '(' (seed=expression)? ')' #RAND\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16\n    | ROUND '(' numeric_expression=expression ',' length=expression (',' function=expression)? ')' #ROUND\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/sign-transact-sql?view=sql-server-ver16\n    | SIGN '(' numeric_expression=expression ')' #MATH_SIGN\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/sin-transact-sql?view=sql-server-ver16\n    | SIN '(' float_expression=expression ')' #SIN\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/sqrt-transact-sql?view=sql-server-ver16\n    | SQRT '(' float_expression=expression ')' #SQRT\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/square-transact-sql?view=sql-server-ver16\n    | SQUARE '(' float_expression=expression ')' #SQUARE\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/tan-transact-sql?view=sql-server-ver16\n    | TAN '(' float_expression=expression ')' #TAN\n    // Logical functions\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/logical-functions-greatest-transact-sql?view=azure-sqldw-latest\n    | GREATEST '(' expression_list_ ')' #GREATEST\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/logical-functions-least-transact-sql?view=azure-sqldw-latest\n    | LEAST '(' expression_list_ ')' #LEAST\n    // Security functions\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/certencoded-transact-sql?view=sql-server-ver16\n    | CERTENCODED '(' certid=expression ')'             #CERTENCODED\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/certprivatekey-transact-sql?view=sql-server-ver16\n    | CERTPRIVATEKEY '(' certid=expression ',' encryption_password=expression (',' decryption_pasword=expression)? ')' #CERTPRIVATEKEY\n    // https://msdn.microsoft.com/en-us/library/ms176050.aspx\n    | CURRENT_USER                                      #CURRENT_USER\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/database-principal-id-transact-sql?view=sql-server-ver16\n    | DATABASE_PRINCIPAL_ID '(' (principal_name=expression)? ')' #DATABASE_PRINCIPAL_ID\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/has-dbaccess-transact-sql?view=sql-server-ver16\n    | HAS_DBACCESS '(' database_name=expression ')'     #HAS_DBACCESS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/has-perms-by-name-transact-sql?view=sql-server-ver16\n    | HAS_PERMS_BY_NAME '(' securable=expression ',' securable_class=expression ',' permission=expression ( ',' sub_securable=expression (',' sub_securable_class=expression )? )? ')' #HAS_PERMS_BY_NAME\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/is-member-transact-sql?view=sql-server-ver16\n    | IS_MEMBER '(' group_or_role=expression ')'        #IS_MEMBER\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/is-rolemember-transact-sql?view=sql-server-ver16\n    | IS_ROLEMEMBER '(' role=expression ( ',' database_principal=expression )? ')' #IS_ROLEMEMBER\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/is-srvrolemember-transact-sql?view=sql-server-ver16\n    | IS_SRVROLEMEMBER '(' role=expression ( ',' login=expression )? ')' #IS_SRVROLEMEMBER\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/loginproperty-transact-sql?view=sql-server-ver16\n    | LOGINPROPERTY '(' login_name=expression ',' property_name=expression ')' #LOGINPROPERTY\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/original-login-transact-sql?view=sql-server-ver16\n    | ORIGINAL_LOGIN '(' ')'                            #ORIGINAL_LOGIN\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/permissions-transact-sql?view=sql-server-ver16\n    | PERMISSIONS '(' ( object_id=expression (',' column=expression)? )? ')' #PERMISSIONS\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/pwdencrypt-transact-sql?view=sql-server-ver16\n    | PWDENCRYPT '(' password=expression ')'            #PWDENCRYPT\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/pwdcompare-transact-sql?view=sql-server-ver16\n    | PWDCOMPARE '(' clear_text_password=expression ',' password_hash=expression (',' version=expression )?')' #PWDCOMPARE\n    // https://msdn.microsoft.com/en-us/library/ms177587.aspx\n    | SESSION_USER                                      #SESSION_USER\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/sessionproperty-transact-sql?view=sql-server-ver16\n    | SESSIONPROPERTY '(' option_name=expression ')'    #SESSIONPROPERTY\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/suser-id-transact-sql?view=sql-server-ver16\n    | SUSER_ID '(' (login=expression)? ')'              #SUSER_ID\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/suser-name-transact-sql?view=sql-server-ver16\n    | SUSER_NAME '(' (server_user_sid=expression)? ')'  #SUSER_SNAME\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/suser-sid-transact-sql?view=sql-server-ver16\n    | SUSER_SID '(' (login=expression (',' param2=expression)?)? ')' #SUSER_SID\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/suser-sname-transact-sql?view=sql-server-ver16\n    | SUSER_SNAME '(' (server_user_sid=expression)? ')' #SUSER_SNAME\n    // https://msdn.microsoft.com/en-us/library/ms179930.aspx\n    | SYSTEM_USER                                       #SYSTEM_USER\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/user-transact-sql?view=sql-server-ver16\n    | USER                                              #USER\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/user-id-transact-sql?view=sql-server-ver16\n    | USER_ID '(' (user=expression)? ')'                #USER_ID\n    // https://learn.microsoft.com/en-us/sql/t-sql/functions/user-name-transact-sql?view=sql-server-ver16\n    | USER_NAME '(' (id=expression)? ')' #USER_NAME\n    ;\n\nxml_data_type_methods\n    : value_method\n    | query_method\n    | exist_method\n    | modify_method\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/functions/date-bucket-transact-sql?view=sql-server-ver16\ndateparts_9\n    : YEAR | YEAR_ABBR\n    | QUARTER | QUARTER_ABBR\n    | MONTH | MONTH_ABBR\n    | DAY | DAY_ABBR\n    | WEEK | WEEK_ABBR\n    | HOUR | HOUR_ABBR\n    | MINUTE | MINUTE_ABBR\n    | SECOND | SECOND_ABBR\n    | MILLISECOND | MILLISECOND_ABBR\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/functions/dateadd-transact-sql?view=sql-server-ver16\ndateparts_12\n    : dateparts_9\n    | DAYOFYEAR | DAYOFYEAR_ABBR\n    | MICROSECOND | MICROSECOND_ABBR\n    | NANOSECOND | NANOSECOND_ABBR\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/functions/datename-transact-sql?view=sql-server-ver16\ndateparts_15\n    : dateparts_12\n    | WEEKDAY | WEEKDAY_ABBR\n    | TZOFFSET | TZOFFSET_ABBR\n    | ISO_WEEK | ISO_WEEK_ABBR\n    ;\n\n// https://learn.microsoft.com/en-us/sql/t-sql/functions/datetrunc-transact-sql?view=sql-server-ver16\ndateparts_datetrunc\n    : dateparts_9\n    | DAYOFYEAR | DAYOFYEAR_ABBR\n    | MICROSECOND | MICROSECOND_ABBR\n    | ISO_WEEK | ISO_WEEK_ABBR\n    ;\n\nvalue_method\n    : (loc_id=LOCAL_ID | value_id=full_column_name | eventdata=EVENTDATA '(' ')'  | query=query_method | '(' subquery ')') '.' call=value_call\n    ;\n\nvalue_call\n    :  (VALUE | VALUE_SQUARE_BRACKET) '(' xquery=STRING ',' sqltype=STRING ')'\n    ;\n\nquery_method\n    : (loc_id=LOCAL_ID | value_id=full_column_name | '(' subquery ')' ) '.' call=query_call\n    ;\n\nquery_call\n    : (QUERY | QUERY_SQUARE_BRACKET) '(' xquery=STRING ')'\n    ;\n\nexist_method\n    : (loc_id=LOCAL_ID | value_id=full_column_name | '(' subquery ')') '.' call=exist_call\n    ;\n\nexist_call\n    : (EXIST | EXIST_SQUARE_BRACKET) '(' xquery=STRING ')'\n    ;\n\nmodify_method\n    : (loc_id=LOCAL_ID | value_id=full_column_name | '(' subquery ')') '.' call=modify_call\n    ;\n\nmodify_call\n    : (MODIFY | MODIFY_SQUARE_BRACKET) '(' xml_dml=STRING ')'\n    ;\n\nhierarchyid_call\n    : GETANCESTOR '(' n=expression ')'\n    | GETDESCENDANT '(' child1=expression ',' child2=expression ')'\n    | GETLEVEL '(' ')'\n    | ISDESCENDANTOF '(' parent_=expression ')'\n    | GETREPARENTEDVALUE '(' oldroot=expression ',' newroot=expression ')'\n    | TOSTRING '(' ')'\n    ;\n\nhierarchyid_static_method\n    : HIERARCHYID DOUBLE_COLON (GETROOT '(' ')' | PARSE '(' input=expression ')')\n    ;\n\nnodes_method\n    : (loc_id=LOCAL_ID | value_id=full_column_name | '(' subquery ')') '.' NODES '(' xquery=STRING ')'\n    ;\n\n\nswitch_section\n    : WHEN expression THEN expression\n    ;\n\nswitch_search_condition_section\n    : WHEN search_condition THEN expression\n    ;\n\nas_column_alias\n    : AS? column_alias\n    ;\n\nas_table_alias\n    : AS? table_alias\n    ;\n\ntable_alias\n    : id_\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms187373.aspx\nwith_table_hints\n    : WITH '(' hint+=table_hint (','? hint+=table_hint)* ')'\n    ;\n\ndeprecated_table_hint\n    : '(' table_hint ')'\n    ;\n\n// https://infocenter-archive.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc00938.1502/html/locking/locking103.htm\n// https://infocenter-archive.sybase.com/help/index.jsp?topic=/com.sybase.dc32300_1250/html/sqlug/sqlug792.htm\n// https://infocenter-archive.sybase.com/help/index.jsp?topic=/com.sybase.dc36271_36272_36273_36274_1250/html/refman/X35229.htm\n// Legacy hint with no parenthesis and no WITH keyword. Actually conflicts with table alias name except for holdlock which is\n// a reserved keyword in this grammar. We might want a separate sybase grammar variant.\nsybase_legacy_hints\n    : sybase_legacy_hint+\n    ;\n\nsybase_legacy_hint\n    : HOLDLOCK\n    | NOHOLDLOCK\n    | READPAST\n    | SHARED\n    ;\n\n// For simplicity, we don't build subsets for INSERT/UPDATE/DELETE/SELECT/MERGE\n// which means the grammar accept slightly more than the what the specification (documentation) says.\ntable_hint\n    : NOEXPAND\n    | INDEX (\n            '(' index_value (',' index_value)* ')'\n            | '=' '(' index_value ')'\n            | '=' index_value // examples in the doc include this syntax\n            )\n    | FORCESEEK ( '(' index_value '(' column_name_list ')' ')' )?\n    | FORCESCAN\n    | HOLDLOCK\n    | NOLOCK\n    | NOWAIT\n    | PAGLOCK\n    | READCOMMITTED\n    | READCOMMITTEDLOCK\n    | READPAST\n    | READUNCOMMITTED\n    | REPEATABLEREAD\n    | ROWLOCK\n    | SERIALIZABLE\n    | SNAPSHOT\n    | SPATIAL_WINDOW_MAX_CELLS '=' DECIMAL\n    | TABLOCK\n    | TABLOCKX\n    | UPDLOCK\n    | XLOCK\n    | KEEPIDENTITY\n    | KEEPDEFAULTS\n    | IGNORE_CONSTRAINTS\n    | IGNORE_TRIGGERS\n    ;\n\nindex_value\n    : id_ | DECIMAL\n    ;\n\ncolumn_alias_list\n    : '(' alias+=column_alias (',' alias+=column_alias)* ')'\n    ;\n\ncolumn_alias\n    : id_\n    | STRING\n    ;\n\ntable_value_constructor\n    : VALUES '(' exps+=expression_list_ ')' (',' '(' exps+=expression_list_ ')')*\n    ;\n\nexpression_list_\n    : exp+=expression (',' exp+=expression)*\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms189798.aspx\nranking_windowed_function\n    : (RANK | DENSE_RANK | ROW_NUMBER) '(' ')' over_clause\n    | NTILE '(' expression ')' over_clause\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms173454.aspx\naggregate_windowed_function\n    : agg_func=(AVG | MAX | MIN | SUM | STDEV | STDEVP | VAR | VARP)\n      '(' all_distinct_expression ')' over_clause?\n    | cnt=(COUNT | COUNT_BIG)\n      '(' ('*' | all_distinct_expression) ')' over_clause?\n    | CHECKSUM_AGG '(' all_distinct_expression ')'\n    | GROUPING '(' expression ')'\n    | GROUPING_ID '(' expression_list_ ')'\n    ;\n\n// https://docs.microsoft.com/en-us/sql/t-sql/functions/analytic-functions-transact-sql\nanalytic_windowed_function\n    : (FIRST_VALUE | LAST_VALUE) '(' expression ')' over_clause\n    | (LAG | LEAD) '(' expression  (',' expression (',' expression)? )? ')' over_clause\n    | (CUME_DIST | PERCENT_RANK) '(' ')' OVER '(' (PARTITION BY expression_list_)? order_by_clause ')'\n    | (PERCENTILE_CONT | PERCENTILE_DISC) '(' expression ')' WITHIN GROUP '(' order_by_clause ')' OVER '(' (PARTITION BY expression_list_)? ')'\n    ;\n\nall_distinct_expression\n    : (ALL | DISTINCT)? expression\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms189461.aspx\nover_clause\n    : OVER '(' (PARTITION BY expression_list_)? order_by_clause? row_or_range_clause? ')'\n    ;\n\nrow_or_range_clause\n    : (ROWS | RANGE) window_frame_extent\n    ;\n\nwindow_frame_extent\n    : window_frame_preceding\n    | BETWEEN window_frame_bound AND window_frame_bound\n    ;\n\nwindow_frame_bound\n    : window_frame_preceding\n    | window_frame_following\n    ;\n\nwindow_frame_preceding\n    : UNBOUNDED PRECEDING\n    | DECIMAL PRECEDING\n    | CURRENT ROW\n    ;\n\nwindow_frame_following\n    : UNBOUNDED FOLLOWING\n    | DECIMAL FOLLOWING\n    ;\n\ncreate_database_option\n    : FILESTREAM ( database_filestream_option (',' database_filestream_option)* )\n    | DEFAULT_LANGUAGE EQUAL ( id_ | STRING )\n    | DEFAULT_FULLTEXT_LANGUAGE EQUAL ( id_ | STRING )\n    | NESTED_TRIGGERS EQUAL ( OFF | ON )\n    | TRANSFORM_NOISE_WORDS EQUAL ( OFF | ON )\n    | TWO_DIGIT_YEAR_CUTOFF EQUAL DECIMAL\n    | DB_CHAINING ( OFF | ON )\n    | TRUSTWORTHY ( OFF | ON )\n    ;\n\ndatabase_filestream_option\n    : LR_BRACKET\n     (\n         ( NON_TRANSACTED_ACCESS EQUAL ( OFF | READ_ONLY | FULL ) )\n         |\n         ( DIRECTORY_NAME EQUAL STRING )\n     )\n     RR_BRACKET\n    ;\n\ndatabase_file_spec\n    : file_group | file_spec\n    ;\n\nfile_group\n    : FILEGROUP id_\n     ( CONTAINS FILESTREAM )?\n     ( DEFAULT )?\n     ( CONTAINS MEMORY_OPTIMIZED_DATA )?\n     file_spec ( ',' file_spec )*\n    ;\nfile_spec\n    : LR_BRACKET\n      NAME EQUAL ( id_ | STRING ) ','?\n      FILENAME EQUAL file = STRING ','?\n      ( SIZE EQUAL file_size ','? )?\n      ( MAXSIZE EQUAL (file_size | UNLIMITED )','? )?\n      ( FILEGROWTH EQUAL file_size ','? )?\n      RR_BRACKET\n    ;\n\n\n// Primitive.\nentity_name\n    : (server=id_ '.' database=id_ '.'  schema=id_   '.'\n    |                database=id_ '.' (schema=id_)? '.'\n    |                                 schema=id_   '.')? table=id_\n    ;\n\n\nentity_name_for_azure_dw\n    : schema=id_\n    | schema=id_ '.' object_name=id_\n    ;\n\nentity_name_for_parallel_dw\n    : schema_database=id_\n    | schema=id_ '.' object_name=id_\n    ;\n\nfull_table_name\n    : (linkedServer=id_ '.' '.' schema=id_   '.'\n    |                       server=id_    '.' database=id_ '.'  schema=id_   '.'\n    |                                         database=id_ '.'  schema=id_? '.'\n    |                                                           schema=id_    '.')? table=id_\n    ;\n\ntable_name\n    : (database=id_ '.' schema=id_? '.' | schema=id_ '.')? (table=id_ | blocking_hierarchy=BLOCKING_HIERARCHY)\n    ;\n\nsimple_name\n    : (schema=id_ '.')? name=id_\n    ;\n\nfunc_proc_name_schema\n    : ((schema=id_) '.')? procedure=id_\n    ;\n\nfunc_proc_name_database_schema\n    : database=id_? '.' schema=id_? '.' procedure=id_\n    | func_proc_name_schema\n    ;\n\nfunc_proc_name_server_database_schema\n    : server=id_? '.' database=id_? '.' schema=id_? '.' procedure=id_\n    | func_proc_name_database_schema\n    ;\n\nddl_object\n    : full_table_name\n    | LOCAL_ID\n    ;\n\nfull_column_name\n    : ((DELETED | INSERTED | full_table_name) '.')? (column_name=id_ | ('$' (IDENTITY | ROWGUID)))\n    ;\n\ncolumn_name_list_with_order\n    : id_ (ASC | DESC)? (',' id_ (ASC | DESC)?)*\n    ;\n\n//For some reason, sql server allows any number of prefixes:  Here, h is the column: a.b.c.d.e.f.g.h\ninsert_column_name_list\n    : col+=insert_column_id (',' col+=insert_column_id)*\n    ;\n\ninsert_column_id\n    : (ignore+=id_? '.' )* id_\n    ;\n\ncolumn_name_list\n    : col+=id_ (',' col+=id_)*\n    ;\n\ncursor_name\n    : id_\n    | LOCAL_ID\n    ;\n\non_off\n    : ON\n    | OFF\n    ;\n\nclustered\n    : CLUSTERED\n    | NONCLUSTERED\n    ;\n\nnull_notnull\n    : NOT? NULL_\n    ;\n\nscalar_function_name\n    : func_proc_name_server_database_schema\n    | RIGHT\n    | LEFT\n    | BINARY_CHECKSUM\n    | CHECKSUM\n    ;\n\nbegin_conversation_timer\n    : BEGIN CONVERSATION TIMER '(' LOCAL_ID ')' TIMEOUT '=' time ';'?\n    ;\n\nbegin_conversation_dialog\n    : BEGIN DIALOG (CONVERSATION)? dialog_handle=LOCAL_ID\n      FROM SERVICE initiator_service_name=service_name\n      TO SERVICE target_service_name=service_name (',' service_broker_guid=STRING)?\n      ON CONTRACT contract_name\n      (WITH\n        ((RELATED_CONVERSATION | RELATED_CONVERSATION_GROUP) '=' LOCAL_ID ','?)?\n        (LIFETIME '=' (DECIMAL | LOCAL_ID) ','?)?\n        (ENCRYPTION '=' on_off)? )?\n      ';'?\n    ;\n\ncontract_name\n    : (id_ | expression)\n    ;\n\nservice_name\n    : (id_ | expression)\n    ;\n\nend_conversation\n    : END CONVERSATION conversation_handle=LOCAL_ID ';'?\n      (WITH (ERROR '=' faliure_code=(LOCAL_ID | STRING) DESCRIPTION '=' failure_text=(LOCAL_ID | STRING))? CLEANUP? )?\n    ;\n\nwaitfor_conversation\n    : WAITFOR? '(' get_conversation ')' (','? TIMEOUT timeout=time)? ';'?\n    ;\n\nget_conversation\n    :GET CONVERSATION GROUP conversation_group_id=(STRING | LOCAL_ID) FROM queue=queue_id ';'?\n    ;\n\nqueue_id\n    : (database_name=id_ '.' schema_name=id_ '.' name=id_)\n    | id_\n    ;\n\nsend_conversation\n    : SEND ON CONVERSATION conversation_handle=(STRING | LOCAL_ID)\n      MESSAGE TYPE message_type_name=expression\n      ('(' message_body_expression=(STRING | LOCAL_ID) ')' )?\n      ';'?\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms187752.aspx\n// TODO: implement runtime check or add new tokens.\n\ndata_type\n    : scaled=(VARCHAR | NVARCHAR | BINARY_KEYWORD | VARBINARY_KEYWORD | SQUARE_BRACKET_ID) '(' MAX ')'\n    | ext_type=id_ '(' scale=DECIMAL ',' prec=DECIMAL ')'\n    | ext_type=id_ '(' scale=DECIMAL ')'\n    | ext_type=id_ IDENTITY ('(' seed=DECIMAL ',' inc=DECIMAL ')')?\n    | double_prec=DOUBLE PRECISION?\n    | unscaled_type=id_\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms179899.aspx\nconstant\n    : STRING // string, datetime or uniqueidentifier\n    | BINARY\n    | '-'? (DECIMAL | REAL | FLOAT)     // float or decimal\n    | '-'? dollar='$' ('-'|'+')? (DECIMAL | FLOAT) // money\n    | parameter\n    ;\n\n// To reduce ambiguity, -X is considered as an application of unary operator\nprimitive_constant\n    : STRING // string, datetime or uniqueidentifier\n    | BINARY\n    | (DECIMAL | REAL | FLOAT)          // float or decimal\n    | dollar='$' ('-'|'+')? (DECIMAL | FLOAT) // money\n    | parameter\n    ;\n\nkeyword\n    : ABORT\n    | ABSOLUTE\n    | ACCENT_SENSITIVITY\n    | ACCESS\n    | ACTION\n    | ACTIVATION\n    | ACTIVE\n    | ADD   // ?\n    | ADDRESS\n    | AES_128\n    | AES_192\n    | AES_256\n    | AFFINITY\n    | AFTER\n    | AGGREGATE\n    | ALGORITHM\n    | ALL_CONSTRAINTS\n    | ALL_ERRORMSGS\n    | ALL_INDEXES\n    | ALL_LEVELS\n    | ALLOW_ENCRYPTED_VALUE_MODIFICATIONS\n    | ALLOW_PAGE_LOCKS\n    | ALLOW_ROW_LOCKS\n    | ALLOW_SNAPSHOT_ISOLATION\n    | ALLOWED\n    | ALWAYS\n    | ANSI_DEFAULTS\n    | ANSI_NULL_DEFAULT\n    | ANSI_NULL_DFLT_OFF\n    | ANSI_NULL_DFLT_ON\n    | ANSI_NULLS\n    | ANSI_PADDING\n    | ANSI_WARNINGS\n    | APP_NAME\n    | APPLICATION_LOG\n    | APPLOCK_MODE\n    | APPLOCK_TEST\n    | APPLY\n    | ARITHABORT\n    | ARITHIGNORE\n    | ASCII\n    | ASSEMBLY\n    | ASSEMBLYPROPERTY\n    | AT_KEYWORD\n    | AUDIT\n    | AUDIT_GUID\n    | AUTO\n    | AUTO_CLEANUP\n    | AUTO_CLOSE\n    | AUTO_CREATE_STATISTICS\n    | AUTO_DROP\n    | AUTO_SHRINK\n    | AUTO_UPDATE_STATISTICS\n    | AUTO_UPDATE_STATISTICS_ASYNC\n    | AUTOGROW_ALL_FILES\n    | AUTOGROW_SINGLE_FILE\n    | AVAILABILITY\n    | AVG\n    | BACKUP_CLONEDB\n    | BACKUP_PRIORITY\n    | BASE64\n    | BEGIN_DIALOG\n    | BIGINT\n    | BINARY_KEYWORD\n    | BINARY_CHECKSUM\n    | BINDING\n    | BLOB_STORAGE\n    | BROKER\n    | BROKER_INSTANCE\n    | BULK_LOGGED\n    | CALLER\n    | CAP_CPU_PERCENT\n    | CAST\n    | TRY_CAST\n    | CATALOG\n    | CATCH\n    | CERT_ID\n    | CERTENCODED\n    | CERTPRIVATEKEY\n    | CHANGE\n    | CHANGE_RETENTION\n    | CHANGE_TRACKING\n    | CHAR\n    | CHARINDEX\n    | CHECKALLOC\n    | CHECKCATALOG\n    | CHECKCONSTRAINTS\n    | CHECKDB\n    | CHECKFILEGROUP\n    | CHECKSUM\n    | CHECKSUM_AGG\n    | CHECKTABLE\n    | CLEANTABLE\n    | CLEANUP\n    | CLONEDATABASE\n    | COL_LENGTH\n    | COL_NAME\n    | COLLECTION\n    | COLUMN_ENCRYPTION_KEY\n    | COLUMN_MASTER_KEY\n    | COLUMNPROPERTY\n    | COLUMNS\n    | COLUMNSTORE\n    | COLUMNSTORE_ARCHIVE\n    | COMMITTED\n    | COMPATIBILITY_LEVEL\n    | COMPRESS_ALL_ROW_GROUPS\n    | COMPRESSION_DELAY\n    | CONCAT\n    | CONCAT_WS\n    | CONCAT_NULL_YIELDS_NULL\n    | CONTENT\n    | CONTROL\n    | COOKIE\n    | COUNT\n    | COUNT_BIG\n    | COUNTER\n    | CPU\n    | CREATE_NEW\n    | CREATION_DISPOSITION\n    | CREDENTIAL\n    | CRYPTOGRAPHIC\n    | CUME_DIST\n    | CURSOR_CLOSE_ON_COMMIT\n    | CURSOR_DEFAULT\n    | CURSOR_STATUS\n    | DATA\n    | DATA_PURITY\n    | DATABASE_PRINCIPAL_ID\n    | DATABASEPROPERTYEX\n    | DATALENGTH\n    | DATE_CORRELATION_OPTIMIZATION\n    | DATEADD\n    | DATEDIFF\n    | DATENAME\n    | DATEPART\n    | DAYS\n    | DB_CHAINING\n    | DB_FAILOVER\n    | DB_ID\n    | DB_NAME\n    | DBCC\n    | DBREINDEX\n    | DECRYPTION\n    | DEFAULT_DOUBLE_QUOTE\n    | DEFAULT_FULLTEXT_LANGUAGE\n    | DEFAULT_LANGUAGE\n    | DEFINITION\n    | DELAY\n    | DELAYED_DURABILITY\n    | DELETED\n    | DENSE_RANK\n    | DEPENDENTS\n    | DES\n    | DESCRIPTION\n    | DESX\n    | DETERMINISTIC\n    | DHCP\n    | DIALOG\n    | DIFFERENCE\n    | DIRECTORY_NAME\n    | DISABLE\n    | DISABLE_BROKER\n    | DISABLED\n    | DOCUMENT\n    | DROP_EXISTING\n    | DROPCLEANBUFFERS\n    | DYNAMIC\n    | ELEMENTS\n    | EMERGENCY\n    | EMPTY\n    | ENABLE\n    | ENABLE_BROKER\n    | ENCRYPTED\n    | ENCRYPTED_VALUE\n    | ENCRYPTION\n    | ENCRYPTION_TYPE\n    | ENDPOINT_URL\n    | ERROR_BROKER_CONVERSATIONS\n    | ESTIMATEONLY\n    | EXCLUSIVE\n    | EXECUTABLE\n    | EXIST\n    | EXIST_SQUARE_BRACKET\n    | EXPAND\n    | EXPIRY_DATE\n    | EXPLICIT\n    | EXTENDED_LOGICAL_CHECKS\n    | FAIL_OPERATION\n    | FAILOVER_MODE\n    | FAILURE\n    | FAILURE_CONDITION_LEVEL\n    | FAST\n    | FAST_FORWARD\n    | FILE_ID\n    | FILE_IDEX\n    | FILE_NAME\n    | FILEGROUP\n    | FILEGROUP_ID\n    | FILEGROUP_NAME\n    | FILEGROUPPROPERTY\n    | FILEGROWTH\n    | FILENAME\n    | FILEPATH\n    | FILEPROPERTY\n    | FILEPROPERTYEX\n    | FILESTREAM\n    | FILTER\n    | FIRST\n    | FIRST_VALUE\n    | FMTONLY\n    | FOLLOWING\n    | FORCE\n    | FORCE_FAILOVER_ALLOW_DATA_LOSS\n    | FORCED\n    | FORCEPLAN\n    | FORCESCAN\n    | FORMAT\n    | FORWARD_ONLY\n    | FREE\n    | FULLSCAN\n    | FULLTEXT\n    | FULLTEXTCATALOGPROPERTY\n    | FULLTEXTSERVICEPROPERTY\n    | GB\n    | GENERATED\n    | GETDATE\n    | GETUTCDATE\n    | GLOBAL\n    | GO\n    | GREATEST\n    | GROUP_MAX_REQUESTS\n    | GROUPING\n    | GROUPING_ID\n    | HADR\n    | HAS_DBACCESS\n    | HAS_PERMS_BY_NAME\n    | HASH\n    | HEALTH_CHECK_TIMEOUT\n    | HIDDEN_KEYWORD\n    | HIGH\n    | HONOR_BROKER_PRIORITY\n    | HOURS\n    | IDENT_CURRENT\n    | IDENT_INCR\n    | IDENT_SEED\n    | IDENTITY_VALUE\n    | IGNORE_CONSTRAINTS\n    | IGNORE_DUP_KEY\n    | IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX\n    | IGNORE_REPLICATED_TABLE_CACHE\n    | IGNORE_TRIGGERS\n    | IMMEDIATE\n    | IMPERSONATE\n    | IMPLICIT_TRANSACTIONS\n    | IMPORTANCE\n    | INCLUDE_NULL_VALUES\n    | INCREMENTAL\n    | INDEX_COL\n    | INDEXKEY_PROPERTY\n    | INDEXPROPERTY\n    | INITIATOR\n    | INPUT\n    | INSENSITIVE\n    | INSERTED\n    | INT\n    | IP\n    | IS_MEMBER\n    | IS_ROLEMEMBER\n    | IS_SRVROLEMEMBER\n    | ISJSON\n    | ISOLATION\n    | JOB\n    | JSON\n    | JSON_OBJECT\n    | JSON_ARRAY\n    | JSON_VALUE\n    | JSON_QUERY\n    | JSON_MODIFY\n    | JSON_PATH_EXISTS\n    | KB\n    | KEEP\n    | KEEPDEFAULTS\n    | KEEPFIXED\n    | KEEPIDENTITY\n    | KEY_SOURCE\n    | KEYS\n    | KEYSET\n    | LAG\n    | LAST\n    | LAST_VALUE\n    | LEAD\n    | LEAST\n    | LEN\n    | LEVEL\n    | LIST\n    | LISTENER\n    | LISTENER_URL\n    | LOB_COMPACTION\n    | LOCAL\n    | LOCATION\n    | LOCK\n    | LOCK_ESCALATION\n    | LOGIN\n    | LOGINPROPERTY\n    | LOOP\n    | LOW\n    | LOWER\n    | LTRIM\n    | MANUAL\n    | MARK\n    | MASKED\n    | MATERIALIZED\n    | MAX\n    | MAX_CPU_PERCENT\n    | MAX_DOP\n    | MAX_FILES\n    | MAX_IOPS_PER_VOLUME\n    | MAX_MEMORY_PERCENT\n    | MAX_PROCESSES\n    | MAX_QUEUE_READERS\n    | MAX_ROLLOVER_FILES\n    | MAXDOP\n    | MAXRECURSION\n    | MAXSIZE\n    | MB\n    | MEDIUM\n    | MEMORY_OPTIMIZED_DATA\n    | MESSAGE\n    | MIN\n    | MIN_ACTIVE_ROWVERSION\n    | MIN_CPU_PERCENT\n    | MIN_IOPS_PER_VOLUME\n    | MIN_MEMORY_PERCENT\n    | MINUTES\n    | MIRROR_ADDRESS\n    | MIXED_PAGE_ALLOCATION\n    | MODE\n    | MODIFY\n    | MODIFY_SQUARE_BRACKET\n    | MOVE\n    | MULTI_USER\n    | NAME\n    | NCHAR\n    | NESTED_TRIGGERS\n    | NEW_ACCOUNT\n    | NEW_BROKER\n    | NEW_PASSWORD\n    | NEWNAME\n    | NEXT\n    | NO\n    | NO_INFOMSGS\n    | NO_QUERYSTORE\n    | NO_STATISTICS\n    | NO_TRUNCATE\n    | NO_WAIT\n    | NOCOUNT\n    | NODES\n    | NOEXEC\n    | NOEXPAND\n    | NOINDEX\n    | NOLOCK\n    | NON_TRANSACTED_ACCESS\n    | NORECOMPUTE\n    | NORECOVERY\n    | NOTIFICATIONS\n    | NOWAIT\n    | NTILE\n    | NULL_DOUBLE_QUOTE\n    | NUMANODE\n    | NUMBER\n    | NUMERIC_ROUNDABORT\n    | OBJECT\n    | OBJECT_DEFINITION\n    | OBJECT_ID\n    | OBJECT_NAME\n    | OBJECT_SCHEMA_NAME\n    | OBJECTPROPERTY\n    | OBJECTPROPERTYEX\n    | OFFLINE\n    | OFFSET\n    | OLD_ACCOUNT\n    | ONLINE\n    | ONLY\n    | OPEN_EXISTING\n    | OPENJSON\n    | OPTIMISTIC\n    | OPTIMIZE\n    | OPTIMIZE_FOR_SEQUENTIAL_KEY\n    | ORIGINAL_DB_NAME\n    | ORIGINAL_LOGIN\n    | OUT\n    | OUTPUT\n    | OVERRIDE\n    | OWNER\n    | OWNERSHIP\n    | PAD_INDEX\n    | PAGE_VERIFY\n    | PAGECOUNT\n    | PAGLOCK\n    | PARAMETERIZATION\n    | PARSENAME\n    | PARSEONLY\n    | PARTITION\n    | PARTITIONS\n    | PARTNER\n    | PATH\n    | PATINDEX\n    | PAUSE\n    | PDW_SHOWSPACEUSED\n    | PERCENT_RANK\n    | PERCENTILE_CONT\n    | PERCENTILE_DISC\n    | PERMISSIONS\n    | PERSIST_SAMPLE_PERCENT\n    | PHYSICAL_ONLY\n    | POISON_MESSAGE_HANDLING\n    | POOL\n    | PORT\n    | PRECEDING\n    | PRIMARY_ROLE\n    | PRIOR\n    | PRIORITY\n    | PRIORITY_LEVEL\n    | PRIVATE\n    | PRIVATE_KEY\n    | PRIVILEGES\n    | PROCCACHE\n    | PROCEDURE_NAME\n    | PROPERTY\n    | PROVIDER\n    | PROVIDER_KEY_NAME\n    | PWDCOMPARE\n    | PWDENCRYPT\n    | QUERY\n    | QUERY_SQUARE_BRACKET\n    | QUEUE\n    | QUEUE_DELAY\n    | QUOTED_IDENTIFIER\n    | QUOTENAME\n    | RANDOMIZED\n    | RANGE\n    | RANK\n    | RC2\n    | RC4\n    | RC4_128\n    | READ_COMMITTED_SNAPSHOT\n    | READ_ONLY\n    | READ_ONLY_ROUTING_LIST\n    | READ_WRITE\n    | READCOMMITTED\n    | READCOMMITTEDLOCK\n    | READONLY\n    | READPAST\n    | READUNCOMMITTED\n    | READWRITE\n    | REBUILD\n    | RECEIVE\n    | RECOMPILE\n    | RECOVERY\n    | RECURSIVE_TRIGGERS\n    | RELATIVE\n    | REMOTE\n    | REMOTE_PROC_TRANSACTIONS\n    | REMOTE_SERVICE_NAME\n    | REMOVE\n    | REORGANIZE\n    | REPAIR_ALLOW_DATA_LOSS\n    | REPAIR_FAST\n    | REPAIR_REBUILD\n    | REPEATABLE\n    | REPEATABLEREAD\n    | REPLACE\n    | REPLICA\n    | REPLICATE\n    | REQUEST_MAX_CPU_TIME_SEC\n    | REQUEST_MAX_MEMORY_GRANT_PERCENT\n    | REQUEST_MEMORY_GRANT_TIMEOUT_SEC\n    | REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT\n    | RESAMPLE\n    | RESERVE_DISK_SPACE\n    | RESOURCE\n    | RESOURCE_MANAGER_LOCATION\n    | RESTRICTED_USER\n    | RESUMABLE\n    | RETENTION\n    | REVERSE\n    | ROBUST\n    | ROOT\n    | ROUTE\n    | ROW\n    | ROW_NUMBER\n    | ROWGUID\n    | ROWLOCK\n    | ROWS\n    | RTRIM\n    | SAMPLE\n    | SCHEMA_ID\n    | SCHEMA_NAME\n    | SCHEMABINDING\n    | SCOPE_IDENTITY\n    | SCOPED\n    | SCROLL\n    | SCROLL_LOCKS\n    | SEARCH\n    | SECONDARY\n    | SECONDARY_ONLY\n    | SECONDARY_ROLE\n    | SECONDS\n    | SECRET\n    | SECURABLES\n    | SECURITY\n    | SECURITY_LOG\n    | SEEDING_MODE\n    | SELF\n    | SEMI_SENSITIVE\n    | SEND\n    | SENT\n    | SEQUENCE\n    | SEQUENCE_NUMBER\n    | SERIALIZABLE\n    | SERVERPROPERTY\n    | SERVICEBROKER\n    | SESSIONPROPERTY\n    | SESSION_TIMEOUT\n    | SETERROR\n    | SHARE\n    | SHARED\n    | SHOWCONTIG\n    | SHOWPLAN\n    | SHOWPLAN_ALL\n    | SHOWPLAN_TEXT\n    | SHOWPLAN_XML\n    | SIGNATURE\n    | SIMPLE\n    | SINGLE_USER\n    | SIZE\n    | SMALLINT\n    | SNAPSHOT\n    | SORT_IN_TEMPDB\n    | SOUNDEX\n    | SPACE_KEYWORD\n    | SPARSE\n    | SPATIAL_WINDOW_MAX_CELLS\n    | SQL_VARIANT_PROPERTY\n    | STANDBY\n    | START_DATE\n    | STATIC\n    | STATISTICS_INCREMENTAL\n    | STATISTICS_NORECOMPUTE\n    | STATS_DATE\n    | STATS_STREAM\n    | STATUS\n    | STATUSONLY\n    | STDEV\n    | STDEVP\n    | STOPLIST\n    | STR\n    | STRING_AGG\n    | STRING_ESCAPE\n    | STUFF\n    | SUBJECT\n    | SUBSCRIBE\n    | SUBSCRIPTION\n    | SUBSTRING\n    | SUM\n    | SUSER_ID\n    | SUSER_NAME\n    | SUSER_SID\n    | SUSER_SNAME\n    | SUSPEND\n    | SYMMETRIC\n    | SYNCHRONOUS_COMMIT\n    | SYNONYM\n    | SYSTEM\n    | TABLERESULTS\n    | TABLOCK\n    | TABLOCKX\n    | TAKE\n    | TARGET_RECOVERY_TIME\n    | TB\n    | TEXTIMAGE_ON\n    | THROW\n    | TIES\n    | TIME\n    | TIMEOUT\n    | TIMER\n    | TINYINT\n    | TORN_PAGE_DETECTION\n    | TRACKING\n    | TRANSACTION_ID\n    | TRANSFORM_NOISE_WORDS\n    | TRANSLATE\n    | TRIM\n    | TRIPLE_DES\n    | TRIPLE_DES_3KEY\n    | TRUSTWORTHY\n    | TRY\n    | TSQL\n    | TWO_DIGIT_YEAR_CUTOFF\n    | TYPE\n    | TYPE_ID\n    | TYPE_NAME\n    | TYPE_WARNING\n    | TYPEPROPERTY\n    | UNBOUNDED\n    | UNCOMMITTED\n    | UNICODE\n    | UNKNOWN\n    | UNLIMITED\n    | UNMASK\n    | UOW\n    | UPDLOCK\n    | UPPER\n    | USER_ID\n    | USER_NAME\n    | USING\n    | VALID_XML\n    | VALIDATION\n    | VALUE\n    | VALUE_SQUARE_BRACKET\n    | VAR\n    | VARBINARY_KEYWORD\n    | VARP\n    | VERIFY_CLONEDB\n    | VERSION\n    | VIEW_METADATA\n    | VIEWS\n    | WAIT\n    | WELL_FORMED_XML\n    | WITHOUT_ARRAY_WRAPPER\n    | WORK\n    | WORKLOAD\n    | XLOCK\n    | XML\n    | XML_COMPRESSION\n    | XMLDATA\n    | XMLNAMESPACES\n    | XMLSCHEMA\n    | XSINIL\n    | ZONE\n//More keywords that can also be used as IDs\n    | ABORT_AFTER_WAIT\n    | ABSENT\n    | ADMINISTER\n    | AES\n    | ALLOW_CONNECTIONS\n    | ALLOW_MULTIPLE_EVENT_LOSS\n    | ALLOW_SINGLE_EVENT_LOSS\n    | ANONYMOUS\n    | APPEND\n    | APPLICATION\n    | ASYMMETRIC\n    | ASYNCHRONOUS_COMMIT\n    | AUTHENTICATE\n    | AUTHENTICATION\n    | AUTOMATED_BACKUP_PREFERENCE\n    | AUTOMATIC\n    | AVAILABILITY_MODE\n    | BEFORE\n    | BLOCK\n    | BLOCKERS\n    | BLOCKSIZE\n    | BLOCKING_HIERARCHY\n    | BUFFER\n    | BUFFERCOUNT\n    | CACHE\n    | CALLED\n    | CERTIFICATE\n    | CHANGETABLE\n    | CHANGES\n    | CHECK_POLICY\n    | CHECK_EXPIRATION\n    | CLASSIFIER_FUNCTION\n    | CLUSTER\n    | COMPRESS\n    | COMPRESSION\n    | CONNECT\n    | CONNECTION\n    | CONFIGURATION\n    | CONNECTIONPROPERTY\n    | CONTAINMENT\n    | CONTEXT\n    | CONTEXT_INFO\n    | CONTINUE_AFTER_ERROR\n    | CONTRACT\n    | CONTRACT_NAME\n    | CONVERSATION\n    | COPY_ONLY\n    | CURRENT_REQUEST_ID\n    | CURRENT_TRANSACTION_ID\n    | CYCLE\n    | DATA_COMPRESSION\n    | DATA_SOURCE\n    | DATABASE_MIRRORING\n    | DATASPACE\n    | DDL\n    | DECOMPRESS\n    | DEFAULT_DATABASE\n    | DEFAULT_SCHEMA\n    | DIAGNOSTICS\n    | DIFFERENTIAL\n    | DISTRIBUTION\n    | DTC_SUPPORT\n    | ENABLED\n    | ENDPOINT\n    | ERROR\n    | ERROR_LINE\n    | ERROR_MESSAGE\n    | ERROR_NUMBER\n    | ERROR_PROCEDURE\n    | ERROR_SEVERITY\n    | ERROR_STATE\n    | EVENT\n    | EVENTDATA\n    | EVENT_RETENTION_MODE\n    | EXECUTABLE_FILE\n    | EXPIREDATE\n    | EXTENSION\n    | EXTERNAL_ACCESS\n    | FAILOVER\n    | FAILURECONDITIONLEVEL\n    | FAN_IN\n    | FILE_SNAPSHOT\n    | FORCESEEK\n    | FORCE_SERVICE_ALLOW_DATA_LOSS\n    | FORMATMESSAGE\n    | GET\n    | GET_FILESTREAM_TRANSACTION_CONTEXT\n    | GETANCESTOR\n    | GETANSINULL\n    | GETDESCENDANT\n    | GETLEVEL\n    | GETREPARENTEDVALUE\n    | GETROOT\n    | GOVERNOR\n    | HASHED\n    | HEALTHCHECKTIMEOUT\n    | HEAP\n    | HIERARCHYID\n    | HOST_ID\n    | HOST_NAME\n    | IIF\n    | IO\n    | INCLUDE\n    | INCREMENT\n    | INFINITE\n    | INIT\n    | INSTEAD\n    | ISDESCENDANTOF\n    | ISNULL\n    | ISNUMERIC\n    | KERBEROS\n    | KEY_PATH\n    | KEY_STORE_PROVIDER_NAME\n    | LANGUAGE\n    | LIBRARY\n    | LIFETIME\n    | LINKED\n    | LINUX\n    | LISTENER_IP\n    | LISTENER_PORT\n    | LOCAL_SERVICE_NAME\n    | LOG\n    | MASK\n    | MATCHED\n    | MASTER\n    | MAX_MEMORY\n    | MAXTRANSFER\n    | MAXVALUE\n    | MAX_DISPATCH_LATENCY\n    | MAX_DURATION\n    | MAX_EVENT_SIZE\n    | MAX_SIZE\n    | MAX_OUTSTANDING_IO_PER_VOLUME\n    | MEDIADESCRIPTION\n    | MEDIANAME\n    | MEMBER\n    | MEMORY_PARTITION_MODE\n    | MESSAGE_FORWARDING\n    | MESSAGE_FORWARD_SIZE\n    | MINVALUE\n    | MIRROR\n    | MUST_CHANGE\n    | NEWID\n    | NEWSEQUENTIALID\n    | NOFORMAT\n    | NOINIT\n    | NONE\n    | NOREWIND\n    | NOSKIP\n    | NOUNLOAD\n    | NO_CHECKSUM\n    | NO_COMPRESSION\n    | NO_EVENT_LOSS\n    | NOTIFICATION\n    | NTLM\n    | OLD_PASSWORD\n    | ON_FAILURE\n    | OPERATIONS\n    | PAGE\n    | PARAM_NODE\n    | PARTIAL\n    | PASSWORD\n    | PERMISSION_SET\n    | PER_CPU\n    | PER_DB\n    | PER_NODE\n    | PERSISTED\n    | PLATFORM\n    | POLICY\n    | PREDICATE\n    | PROCESS\n    | PROFILE\n    | PYTHON\n    | R\n    | READ_WRITE_FILEGROUPS\n    | REGENERATE\n    | RELATED_CONVERSATION\n    | RELATED_CONVERSATION_GROUP\n    | REQUIRED\n    | RESET\n    | RESOURCES\n    | RESTART\n    | RESUME\n    | RETAINDAYS\n    | RETURNS\n    | REWIND\n    | ROLE\n    | ROUND_ROBIN\n    | ROWCOUNT_BIG\n    | RSA_512\n    | RSA_1024\n    | RSA_2048\n    | RSA_3072\n    | RSA_4096\n    | SAFETY\n    | SAFE\n    | SCHEDULER\n    | SCHEME\n    | SCRIPT\n    | SERVER\n    | SERVICE\n    | SERVICE_BROKER\n    | SERVICE_NAME\n    | SESSION\n    | SESSION_CONTEXT\n    | SETTINGS\n    | SHRINKLOG\n    | SID\n    | SKIP_KEYWORD\n    | SOFTNUMA\n    | SOURCE\n    | SPECIFICATION\n    | SPLIT\n    | SQL\n    | SQLDUMPERFLAGS\n    | SQLDUMPERPATH\n    | SQLDUMPERTIMEOUT\n    | STATE\n    | STATS\n    | START\n    | STARTED\n    | STARTUP_STATE\n    | STOP\n    | STOPPED\n    | STOP_ON_ERROR\n    | SUPPORTED\n    | SWITCH\n    | TAPE\n    | TARGET\n    | TCP\n    | TOSTRING\n    | TRACE\n    | TRACK_CAUSALITY\n    | TRANSFER\n    | UNCHECKED\n    | UNLOCK\n    | UNSAFE\n    | URL\n    | USED\n    | VERBOSELOGGING\n    | VISIBILITY\n    | WAIT_AT_LOW_PRIORITY\n    | WINDOWS\n    | WITHOUT\n    | WITNESS\n    | XACT_ABORT\n    | XACT_STATE\n    //\n    | ABS\n    | ACOS\n    | ASIN\n    | ATAN\n    | ATN2\n    | CEILING\n    | COS\n    | COT\n    | DEGREES\n    | EXP\n    | FLOOR\n    | LOG10\n    | PI\n    | POWER\n    | RADIANS\n    | RAND\n    | ROUND\n    | SIGN\n    | SIN\n    | SQRT\n    | SQUARE\n    | TAN\n    //\n    | CURRENT_TIMEZONE\n    | CURRENT_TIMEZONE_ID\n    | DATE_BUCKET\n    | DATEDIFF_BIG\n    | DATEFROMPARTS\n    | DATETIME2FROMPARTS\n    | DATETIMEFROMPARTS\n    | DATETIMEOFFSETFROMPARTS\n    | DATETRUNC\n    | DAY\n    | EOMONTH\n    | ISDATE\n    | MONTH\n    | SMALLDATETIMEFROMPARTS\n    | SWITCHOFFSET\n    | SYSDATETIME\n    | SYSDATETIMEOFFSET\n    | SYSUTCDATETIME\n    | TIMEFROMPARTS\n    | TODATETIMEOFFSET\n    | YEAR\n    //\n    | QUARTER\n    | DAYOFYEAR\n    | WEEK\n    | HOUR\n    | MINUTE\n    | SECOND\n    | MILLISECOND\n    | MICROSECOND\n    | NANOSECOND\n    | TZOFFSET\n    | ISO_WEEK\n    | WEEKDAY\n    //\n    | YEAR_ABBR\n    | QUARTER_ABBR\n    | MONTH_ABBR\n    | DAYOFYEAR_ABBR\n    | DAY_ABBR\n    | WEEK_ABBR\n    | HOUR_ABBR\n    | MINUTE_ABBR\n    | SECOND_ABBR\n    | MILLISECOND_ABBR\n    | MICROSECOND_ABBR\n    | NANOSECOND_ABBR\n    | TZOFFSET_ABBR\n    | ISO_WEEK_ABBR\n    | WEEKDAY_ABBR\n    //\n    | SP_EXECUTESQL\n    //Build-ins:\n    | VARCHAR\n    | NVARCHAR\n    | PRECISION //For some reason this is possible to use as ID\n    | FILESTREAM_ON\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms175874.aspx\nid_\n    : ID\n    | TEMP_ID\n    | DOUBLE_QUOTE_ID\n    | DOUBLE_QUOTE_BLANK\n    | SQUARE_BRACKET_ID\n    | keyword\n    | RAW\n    ;\n\nsimple_id\n    : ID\n    ;\n\nid_or_string\n    : id_\n    | STRING\n    ;\n\n// https://msdn.microsoft.com/en-us/library/ms188074.aspx\n// Spaces are allowed for comparison operators.\ncomparison_operator\n    : '=' | '>' | '<' | '<' '=' | '>' '=' | '<' '>' | '!' '=' | '!' '>' | '!' '<'\n    ;\n\nassignment_operator\n    : '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '^=' | '|='\n    ;\n\nfile_size\n    : DECIMAL( KB | MB | GB | TB | '%' )?\n    ;"
  },
  {
    "path": "superior-sqlserver-parser/src/main/kotlin/io/github/melin/superior/parser/sqlserver/AbstractSqlParser.kt",
    "content": "package io.github.melin.superior.parser.sqlserver\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.sqlserver.antlr4.SqlServerParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(SqlServerParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: SqlServerParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(SqlServerParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-sqlserver-parser/src/main/kotlin/io/github/melin/superior/parser/sqlserver/SqlServerAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.sqlserver\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.DefaultStatement\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.common.ShowStatement\nimport io.github.melin.superior.common.relational.common.UseDatabase\nimport io.github.melin.superior.common.relational.create.CreateDatabase\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.drop.DropDatabase\nimport io.github.melin.superior.parser.sqlserver.antlr4.SqlServerParser\nimport io.github.melin.superior.parser.sqlserver.antlr4.SqlServerParserBaseVisitor\nimport org.antlr.v4.runtime.tree.RuleNode\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2020/6/30 9:59 上午 */\nclass SqlServerAntlr4Visitor(val splitSql: Boolean = false, val command: String?) :\n    SqlServerParserBaseVisitor<Statement>() {\n\n    private var currentOptType: StatementType = StatementType.UNKOWN\n\n    private var limit: Int? = null\n    private var offset: Int? = null\n    private var inputTables: ArrayList<TableId> = arrayListOf()\n    private var outputTables: ArrayList<TableId> = arrayListOf()\n    private var cteTempTables: ArrayList<TableId> = arrayListOf()\n\n    private var statements: ArrayList<Statement> = arrayListOf()\n    private val sqls: ArrayList<String> = arrayListOf()\n\n    fun getSqlStatements(): List<Statement> {\n        return statements\n    }\n\n    fun getSplitSqls(): List<String> {\n        return sqls\n    }\n\n    override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {\n        return if (currentResult == null) true else false\n    }\n\n    override fun visitTsql_file(ctx: SqlServerParser.Tsql_fileContext): Statement? {\n        ctx.batch().forEach { this.visitBatch(it) }\n        return null\n    }\n\n    override fun visitBatch(ctx: SqlServerParser.BatchContext): Statement? {\n        ctx.sql_clauses().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else {\n                        var statement = this.visitSql_clauses(it)\n                        if (statement == null) {\n                            statement = DefaultStatement(StatementType.UNKOWN)\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n\n                clean()\n            }\n        }\n        return null\n    }\n\n    private fun clean() {\n        currentOptType = StatementType.UNKOWN\n\n        limit = null\n        offset = null\n        inputTables = arrayListOf()\n        outputTables = arrayListOf()\n        cteTempTables = arrayListOf()\n    }\n\n    override fun visitCreate_database(ctx: SqlServerParser.Create_databaseContext): Statement {\n        val databaseName = CommonUtils.cleanQuote(ctx.database.text)\n        return CreateDatabase(databaseName)\n    }\n\n    override fun visitDrop_database(ctx: SqlServerParser.Drop_databaseContext): Statement {\n        val ifExists = ctx.IF() != null\n        val databases = ctx.id_().map { it.text }\n        val dropDatabase = DropDatabase(databases.first(), ifExists)\n        dropDatabase.databaseNames.addAll(databases)\n        return dropDatabase\n    }\n\n    override fun visitSelect_statement_standalone(ctx: SqlServerParser.Select_statement_standaloneContext): Statement {\n        currentOptType = StatementType.SELECT\n        if (ctx.with_expression() != null) {\n            this.visitWith_expression(ctx.with_expression())\n        }\n        super.visitSelect_statement(ctx.select_statement())\n\n        val queryStmt = QueryStmt(inputTables, limit, offset)\n        queryStmt.inputTables = inputTables\n        return queryStmt\n    }\n\n    override fun visitDelete_statement(ctx: SqlServerParser.Delete_statementContext): Statement {\n        currentOptType = StatementType.DELETE\n        val tableId = parseTableName(ctx.delete_statement_from().ddl_object().full_table_name())\n        if (ctx.with_expression() != null) {\n            this.visitWith_expression(ctx.with_expression())\n        }\n        if (ctx.search_condition() != null) {\n            super.visitSearch_condition(ctx.search_condition())\n        }\n\n        return DeleteTable(tableId, inputTables)\n    }\n\n    override fun visitInsert_statement(ctx: SqlServerParser.Insert_statementContext): Statement {\n        currentOptType = StatementType.INSERT\n        val tableId = parseTableName(ctx.ddl_object().full_table_name())\n        if (ctx.with_expression() != null) {\n            this.visitWith_expression(ctx.with_expression())\n        }\n\n        this.visitInsert_statement_value(ctx.insert_statement_value())\n\n        val queryStmt = QueryStmt(inputTables)\n        val insertTable =\n            if (ctx.INTO() != null) InsertTable(InsertMode.INTO, queryStmt, tableId)\n            else InsertTable(InsertMode.OVERWRITE, queryStmt, tableId)\n\n        return insertTable\n    }\n\n    override fun visitUpdate_statement(ctx: SqlServerParser.Update_statementContext): Statement {\n        currentOptType = StatementType.UPDATE\n        val tableId = parseTableName(ctx.ddl_object().full_table_name())\n        if (ctx.with_expression() != null) {\n            this.visitWith_expression(ctx.with_expression())\n        }\n\n        if (ctx.table_sources() != null) {\n            super.visitTable_sources(ctx.table_sources())\n        }\n\n        if (ctx.search_condition() != null) {\n            super.visitSearch_condition(ctx.search_condition())\n        }\n\n        return UpdateTable(tableId, inputTables)\n    }\n\n    override fun visitMerge_statement(ctx: SqlServerParser.Merge_statementContext): Statement {\n        currentOptType = StatementType.MERGE\n\n        val tableId = parseTableName(ctx.ddl_object().full_table_name())\n        val mergeTable = MergeTable(tableId)\n        if (ctx.with_expression() != null) {\n            this.visitWith_expression(ctx.with_expression())\n        }\n\n        if (ctx.table_sources() != null) {\n            super.visitTable_sources(ctx.table_sources())\n        }\n\n        mergeTable.inputTables = inputTables\n        return mergeTable\n    }\n\n    override fun visitWith_expression(ctx: SqlServerParser.With_expressionContext): Statement? {\n        ctx.common_table_expression().forEach { cteTempTables.add(TableId(it.id_().text)) }\n        return super.visitWith_expression(ctx)\n    }\n\n    override fun visitSelect_order_by_clause(ctx: SqlServerParser.Select_order_by_clauseContext): Statement? {\n        if (ctx.OFFSET() != null) {\n            offset = ctx.offset_exp.text.toInt()\n        }\n\n        if (ctx.OFFSET() != null) {\n            limit = ctx.fetch_exp.text.toInt()\n        }\n\n        return super.visitSelect_order_by_clause(ctx)\n    }\n\n    override fun visitTable_source_item(ctx: SqlServerParser.Table_source_itemContext): Statement? {\n        if (\n            currentOptType == StatementType.SELECT ||\n                currentOptType == StatementType.CREATE_VIEW ||\n                currentOptType == StatementType.CREATE_MATERIALIZED_VIEW ||\n                currentOptType == StatementType.UPDATE ||\n                currentOptType == StatementType.DELETE ||\n                currentOptType == StatementType.MERGE ||\n                currentOptType == StatementType.INSERT ||\n                currentOptType == StatementType.CREATE_FUNCTION\n        ) {\n\n            if (ctx.full_table_name() != null) {\n                val tableId = parseTableName(ctx.full_table_name())\n\n                if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {\n                    inputTables.add(tableId)\n                }\n            } else {\n                super.visitTable_source_item(ctx)\n            }\n        }\n        return null\n    }\n\n    override fun visitUse_statement(ctx: SqlServerParser.Use_statementContext): Statement {\n        return UseDatabase(ctx.database.text)\n    }\n\n    fun parseTableName(ctx: SqlServerParser.Full_table_nameContext): TableId {\n        if (ctx.database != null) {\n            return TableId(ctx.database.text, ctx.schema.text, ctx.table.text)\n        } else if (ctx.schema != null) {\n            return TableId(null, ctx.schema.text, ctx.table.text)\n        } else {\n            return TableId(null, null, ctx.table.text)\n        }\n    }\n}\n"
  },
  {
    "path": "superior-sqlserver-parser/src/main/kotlin/io/github/melin/superior/parser/sqlserver/SqlServerHelper.kt",
    "content": "package io.github.melin.superior.parser.sqlserver\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.sqlserver.antlr4.SqlServerLexer\nimport io.github.melin.superior.parser.sqlserver.antlr4.SqlServerParser\nimport io.github.melin.superior.parser.sqlserver.antlr4.SqlServerParserBaseVisitor\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2020/6/30 10:01 上午 */\nobject SqlServerHelper {\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until SqlServerLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = SqlServerLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement {\n        val statements = this.parseMultiStatement(command)\n        if (statements.size != 1) {\n            throw IllegalStateException(\"only parser one sql, sql count: \" + statements.size)\n        } else {\n            return statements.get(0)\n        }\n    }\n\n    @JvmStatic\n    fun parseMultiStatement(command: String): List<Statement> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = SqlServerAntlr4Visitor(false, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSqlStatements()\n    }\n\n    @JvmStatic\n    fun splitSql(command: String): List<String> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = SqlServerAntlr4Visitor(true, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSplitSqls()\n    }\n\n    @JvmStatic\n    fun checkSqlSyntax(command: String) {\n        val sqlVisitor = SqlServerParserBaseVisitor<Statement>()\n        innerParseStatement(command, sqlVisitor)\n    }\n\n    private fun innerParseStatement(command: String, sqlVisitor: SqlServerParserBaseVisitor<Statement>) {\n        val charStream = UpperCaseCharStream(CharStreams.fromString(command))\n        val lexer = SqlServerLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = SqlServerParser(tokenStream)\n        AbstractSqlParser.installCaches(parser)\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visit(parser.tsql_file())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                sqlVisitor.visit(parser.tsql_file())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(command)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-sqlserver-parser/src/test/kotlin/io/github/melin/superior/parser/sqlserver/SqlServerParserDdlTest.kt",
    "content": "package io.github.melin.superior.parser.sqlserver\n\nimport io.github.melin.superior.common.relational.create.CreateDatabase\nimport io.github.melin.superior.common.relational.drop.DropDatabase\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2020/6/30 11:05 上午 */\nclass SqlServerParserDdlTest {\n    @Test\n    fun createDatabaseTest() {\n        val sql =\n            \"\"\"\n            USE master;\n            GO\n                CREATE DATABASE Sales\n                ON\n                ( NAME = Sales_dat,\n                    FILENAME = 'C:\\Program Files\\Microsoft SQL Server\\MSSQL13.MSSQLSERVER\\MSSQL\\DATA\\saledat.mdf',\n                    SIZE = 10,\n                    MAXSIZE = 50,\n                    FILEGROWTH = 5 )\n                LOG ON\n                ( NAME = Sales_log,\n                    FILENAME = 'C:\\Program Files\\Microsoft SQL Server\\MSSQL13.MSSQLSERVER\\MSSQL\\DATA\\salelog.ldf',\n                    SIZE = 5MB,\n                    MAXSIZE = 25MB,\n                    FILEGROWTH = 5MB ) ;\n            GO\n                DROP DATABASE Sales, demos;  \n            GO \n        \"\"\"\n                .trimIndent()\n\n        val statements = SqlServerHelper.parseMultiStatement(sql)\n\n        val createDatabse = statements.get(1)\n        val dropDatabase = statements.get(2)\n        if (createDatabse is CreateDatabase) {\n            Assert.assertEquals(\"Sales\", createDatabse.databaseName)\n        } else {\n            Assert.fail()\n        }\n\n        if (dropDatabase is DropDatabase) {\n            Assert.assertEquals(\"Sales\", dropDatabase.databaseNames.get(0))\n            Assert.assertEquals(2, dropDatabase.databaseNames.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-sqlserver-parser/src/test/kotlin/io/github/melin/superior/parser/sqlserver/SqlServerParserDmlTest.kt",
    "content": "package io.github.melin.superior.parser.sqlserver\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.dml.*\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2020/6/30 11:05 上午 */\nclass SqlServerParserDmlTest {\n\n    @Test\n    fun queryTest0() {\n        val sql =\n            \"\"\"\n            SELECT product_name, list_price\n            FROM production.products\n            ORDER BY list_price, product_name \n            OFFSET 20 ROWS \n            FETCH NEXT 10 ROWS ONLY;\n        \"\"\"\n                .trimIndent()\n\n        val statement = SqlServerHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(20, statement.offset)\n            Assert.assertEquals(10, statement.limit)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest1() {\n        val sql =\n            \"\"\"\n            WITH Sales_CTE (SalesPersonID, TotalSales, SalesYear)\n            AS (\n                SELECT SalesPersonID, SUM(TotalDue) AS TotalSales, YEAR(OrderDate) AS SalesYear\n                FROM Sales.SalesOrderHeader\n                WHERE SalesPersonID IS NOT NULL\n                   GROUP BY SalesPersonID, YEAR(OrderDate)\n            ),\n            Sales_Quota_CTE (BusinessEntityID, SalesQuota, SalesQuotaYear)\n            AS (\n               SELECT BusinessEntityID, SUM(SalesQuota)AS SalesQuota, YEAR(QuotaDate) AS SalesQuotaYear\n               FROM Sales.SalesPersonQuotaHistory\n               GROUP BY BusinessEntityID, YEAR(QuotaDate)\n            )\n            SELECT SalesPersonID\n              , SalesYear\n              , FORMAT(TotalSales,'C','en-us') AS TotalSales\n              , SalesQuotaYear\n              , FORMAT (SalesQuota,'C','en-us') AS SalesQuota\n              , FORMAT (TotalSales -SalesQuota, 'C','en-us') AS Amt_Above_or_Below_Quota\n            FROM Sales_CTE\n            JOIN Sales_Quota_CTE ON Sales_Quota_CTE.BusinessEntityID = Sales_CTE.SalesPersonID\n                AND Sales_CTE.SalesYear = Sales_Quota_CTE.SalesQuotaYear\n            ORDER BY SalesPersonID, SalesYear\n        \"\"\"\n                .trimIndent()\n\n        val statement = SqlServerHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(2, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    // @Test\n    fun queryTest2() {\n        val sql =\n            \"\"\"\n            DECLARE @NAME VARCHAR(20)\n            SET @NAME='kkk'\n            SELECT * FROM demos.dbo.tab1 WHERsE name=@NAME\n            SELECT name FROM demos.dbo.tab1 WHERE name=@NAME\n        \"\"\"\n                .trimIndent()\n\n        val statement = SqlServerHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(2, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest0() {\n        val sql =\n            \"\"\"\n            DELETE Production.ProductCostHistory  \n            WHERE StandardCost BETWEEN 12.00 AND 14.00 AND EndDate IS NULL;  \n        \"\"\"\n                .trimIndent()\n\n        val statement = SqlServerHelper.parseStatement(sql)\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(TableId(\"Production\", \"ProductCostHistory\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest1() {\n        val sql =\n            \"\"\"\n            DELETE TOP (20)\n            FROM Purchasing.PurchaseOrderDetail\n            WHERE DueDate < '20020701';\n        \"\"\"\n                .trimIndent()\n\n        val statement = SqlServerHelper.parseStatement(sql)\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(TableId(\"Purchasing\", \"PurchaseOrderDetail\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest2() {\n        val sql =\n            \"\"\"\n            DELETE FROM dbo.FactInternetSales  \n            WHERE ProductKey IN (   \n                SELECT T1.ProductKey FROM dbo.DimProduct T1   \n                JOIN dbo.DimProductSubcategory T2  \n                ON T1.ProductSubcategoryKey = T2.ProductSubcategoryKey  \n                WHERE T2.EnglishProductSubcategoryName = 'Road Bikes') \n        \"\"\"\n                .trimIndent()\n\n        val statement = SqlServerHelper.parseStatement(sql)\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(TableId(\"dbo\", \"FactInternetSales\"), statement.tableId)\n            Assert.assertEquals(2, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest0() {\n        val sql =\n            \"\"\"\n            INSERT INTO Production.UnitMeasure  \n            VALUES (N'FT2', N'Square Feet ', '20080923'), (N'Y', N'Yards', '20080923')\n                , (N'Y3', N'Cubic Yards', '20080923');  \n        \"\"\"\n                .trimIndent()\n\n        val statement = SqlServerHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(TableId(\"Production\", \"UnitMeasure\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest0() {\n        val sql =\n            \"\"\"\n            UPDATE Cities  \n            SET Location = CONVERT(Point, '12.3:46.2')  \n            WHERE Name = 'Anchorage';  \n        \"\"\"\n                .trimIndent()\n\n        val statement = SqlServerHelper.parseStatement(sql)\n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(TableId(\"Cities\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest1() {\n        val sql =\n            \"\"\"\n            UPDATE HumanResources.Employee  \n            SET VacationHours = VacationHours + 8\n            FROM (SELECT TOP 10 BusinessEntityID FROM HumanResources.Employee1  \n                 ORDER BY HireDate ASC) AS th  \n            WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID;\n        \"\"\"\n                .trimIndent()\n\n        val statement = SqlServerHelper.parseStatement(sql)\n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(TableId(\"HumanResources\", \"Employee\"), statement.tableId)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(TableId(\"HumanResources\", \"Employee1\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun mergeTest0() {\n        val sql =\n            \"\"\"\n            MERGE TargetProducts AS Target\n            USING SourceProducts\tAS Source\n            ON Source.ProductID = Target.ProductID\n            WHEN NOT MATCHED BY Target THEN\n                INSERT (ProductID,ProductName, Price) \n                VALUES (Source.ProductID,Source.ProductName, Source.Price)\n            WHEN MATCHED THEN UPDATE SET\n                Target.ProductName\t= Source.ProductName,\n                Target.Price\t\t= Source.Price\n            WHEN NOT MATCHED BY Source THEN\n                DELETE;\n        \"\"\"\n                .trimIndent()\n\n        val statement = SqlServerHelper.parseStatement(sql)\n\n        if (statement is MergeTable) {\n            Assert.assertEquals(StatementType.MERGE, statement.statementType)\n            Assert.assertEquals(\"TargetProducts\", statement.targetTable.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(TableId(\"SourceProducts\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest() {\n        val sql =\n            \"\"\"\n            insert into dbo.spt_fallback_dev\n            select *\n            from dbo.spt_fallback_usg;\n        \"\"\"\n                .trimIndent()\n\n        val statement = SqlServerHelper.parseStatement(sql)\n\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"spt_fallback_dev\", statement.outputTables.get(0).tableName)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(TableId(\"dbo\", \"spt_fallback_usg\"), statement.queryStmt.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-sqlserver-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-starrocks-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-starrocks-parser</artifactId>\n    <name>superior-starrocks-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n\n</project>\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/antlr4/io/github/melin/superior/parser/starrocks/antlr4/StarRocksLexer.g4",
    "content": "// Copyright 2021-present StarRocks, Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     https://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\nlexer grammar StarRocksLexer;\n@members {\nprivate long sqlMode = io.github.melin.superior.parser.starrocks.SqlModeHelper.MODE_DEFAULT;\npublic void setSqlMode(long newSqlMode) {\n    sqlMode = newSqlMode;\n}\n}\ntokens {\n    CONCAT\n}\n\nACCESS: 'ACCESS';\nACTIVE: 'ACTIVE';\nADD: 'ADD';\nADMIN: 'ADMIN';\nADVISOR: 'ADVISOR';\nAFTER: 'AFTER';\nAGGREGATE: 'AGGREGATE';\nALL: 'ALL';\nALTER: 'ALTER';\nANALYZE: 'ANALYZE';\nAND: 'AND';\nANTI: 'ANTI';\nAPPLY: 'APPLY';\nARRAY: 'ARRAY';\nARRAY_AGG: 'ARRAY_AGG';\nARRAY_AGG_DISTINCT: 'ARRAY_AGG_DISTINCT';\nAS: 'AS';\nASC: 'ASC';\nASYNC: 'ASYNC';\nASSERT_ROWS: 'ASSERT_ROWS';\nAUTHORS: 'AUTHORS';\nAUTHENTICATION: 'AUTHENTICATION';\nAUTOMATED: 'AUTOMATED';\nAUTO_INCREMENT: 'AUTO_INCREMENT';\nAVG: 'AVG';\nAWARE: 'AWARE';\nBACKEND: 'BACKEND';\nBACKENDS: 'BACKENDS';\nBACKUP: 'BACKUP';\nBASE: 'BASE';\nBASELINE: 'BASELINE';\nBEGIN: 'BEGIN';\nBETWEEN: 'BETWEEN';\nBIGINT: 'BIGINT';\nBINARY: 'BINARY';\nBITMAP: 'BITMAP';\nBITMAP_UNION: 'BITMAP_UNION';\nBLACKHOLE: 'BLACKHOLE';\nBLACKLIST: 'BLACKLIST';\nBODY: 'BODY';\nBOOLEAN: 'BOOLEAN';\nBOTH: 'BOTH';\nBRANCH: 'BRANCH';\nBROKER: 'BROKER';\nBUCKETS: 'BUCKETS';\nBUILTIN: 'BUILTIN';\nBY: 'BY';\nCACHE: 'CACHE';\nCANCEL: 'CANCEL';\nCASE: 'CASE';\nCAST: 'CAST';\nCATALOG: 'CATALOG';\nCATALOGS: 'CATALOGS';\nCEIL: 'CEIL';\nCHAIN: 'CHAIN';\nCHAR: 'CHAR';\nCHARACTER: 'CHARACTER';\nCHARSET: 'CHARSET';\nCHECK: 'CHECK';\nCLEAN: 'CLEAN';\nCLEAR: 'CLEAR';\nCLUSTER : 'CLUSTER';\nCLUSTERS : 'CLUSTERS';\nCNGROUP : 'CNGROUP';\nCNGROUPS : 'CNGROUPS';\nCOLLATE: 'COLLATE';\nCOLLATION: 'COLLATION';\nCOLUMN: 'COLUMN';\nCOLUMNS: 'COLUMNS';\nCOMMENT: 'COMMENT';\nCOMMIT: 'COMMIT';\nCOMMITTED: 'COMMITTED';\nCOMPACT: 'COMPACT';\nCOMPACTION: 'COMPACTION';\nCOMPUTE: 'COMPUTE';\nCONFIG: 'CONFIG';\nCONNECTION: 'CONNECTION';\nCONSISTENT: 'CONSISTENT';\nCONVERT: 'CONVERT';\nCOSTS: 'COSTS';\nCOUNT: 'COUNT';\nCREATE: 'CREATE';\nCROSS: 'CROSS';\nCUBE: 'CUBE';\nCUME_DIST: 'CUME_DIST';\nCUMULATIVE: 'CUMULATIVE';\nCURRENT: 'CURRENT';\nCURRENT_DATE: 'CURRENT_DATE';\nCURRENT_GROUP: 'CURRENT_GROUP';\nCURRENT_ROLE: 'CURRENT_ROLE';\nCURRENT_TIME: 'CURRENT_TIME';\nCURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP';\nCURRENT_USER: 'CURRENT_USER';\nDATA: 'DATA';\nDATACACHE: 'DATACACHE';\nDATABASE: 'DATABASE';\nDATABASES: 'DATABASES';\nDATE: 'DATE';\nDATETIME: 'DATETIME';\nDAY: 'DAY';\nDAYS: 'DAYS';\nDEALLOCATE : 'DEALLOCATE';\nDECIMAL: 'DECIMAL';\nDECIMALV2: 'DECIMALV2';\nDECIMAL32: 'DECIMAL32';\nDECIMAL64: 'DECIMAL64';\nDECIMAL128: 'DECIMAL128';\nDECOMMISSION: 'DECOMMISSION';\nDEFAULT: 'DEFAULT';\nDELETE: 'DELETE';\nDENSE_RANK: 'DENSE_RANK';\nDEFERRED: 'DEFERRED';\nDIALECT: 'DIALECT';\nDICTIONARY: 'DICTIONARY';\nDICTIONARY_GET: 'DICTIONARY_GET';\nNTILE: 'NTILE';\nDESC: 'DESC';\nDESCRIBE: 'DESCRIBE';\nDISABLE: 'DISABLE';\nDISTINCT: 'DISTINCT';\nDISTRIBUTED: 'DISTRIBUTED';\nDISTRIBUTION: 'DISTRIBUTION';\nDOUBLE: 'DOUBLE';\nDROP: 'DROP';\nDUAL: 'DUAL';\nDUPLICATE: 'DUPLICATE';\nDYNAMIC: 'DYNAMIC';\nELSE: 'ELSE';\nENABLE: 'ENABLE';\nENCLOSE: 'ENCLOSE';\nEND: 'END';\nENGINE: 'ENGINE';\nENGINES: 'ENGINES';\nERRORS: 'ERRORS';\nESCAPE: 'ESCAPE';\nEVENTS: 'EVENTS';\nEXCEPT: 'EXCEPT';\nEXCLUDE: 'EXCLUDE';\nEXECUTE: 'EXECUTE';\nEXISTS: 'EXISTS';\nEXPLAIN: 'EXPLAIN';\nEXPORT: 'EXPORT';\nEXTERNAL: 'EXTERNAL';\nEXTRACT: 'EXTRACT';\nEVERY: 'EVERY';\nFAILPOINT: 'FAILPOINT';\nFAILPOINTS: 'FAILPOINTS';\nFALSE: 'FALSE';\nFIELDS: 'FIELDS';\nFILE: 'FILE';\nFILES: 'FILES';\nFILTER: 'FILTER';\nFIRST: 'FIRST';\nFIRST_VALUE: 'FIRST_VALUE';\nFLOAT: 'FLOAT';\nFLOOR: 'FLOOR';\nFN: 'FN';\nFOLLOWING: 'FOLLOWING';\nFOLLOWER: 'FOLLOWER';\nFOR: 'FOR';\nFORCE: 'FORCE';\nFORMAT: 'FORMAT';\nFREE: 'FREE';\nFROM: 'FROM';\nFRONTEND: 'FRONTEND';\nFRONTENDS: 'FRONTENDS';\nFULL: 'FULL';\nFUNCTION: 'FUNCTION';\nFUNCTIONS: 'FUNCTIONS';\nGLOBAL: 'GLOBAL';\nGRANT: 'GRANT';\nGRANTS: 'GRANTS';\nGROUP: 'GROUP';\nGROUPS: 'GROUPS';\nGROUPING: 'GROUPING';\nGROUPING_ID: 'GROUPING_ID';\nGROUP_CONCAT: 'GROUP_CONCAT';\nHASH: 'HASH';\nHAVING: 'HAVING';\nHELP: 'HELP';\nHISTOGRAM: 'HISTOGRAM';\nHLL: 'HLL';\nHLL_UNION: 'HLL_UNION';\nHOST: 'HOST';\nHOUR: 'HOUR';\nHOURS: 'HOURS';\nHUB: 'HUB';\nIDENTIFIED: 'IDENTIFIED';\nIF: 'IF';\nIMPERSONATE: 'IMPERSONATE';\nIMMEDIATE: 'IMMEDIATE';\nIGNORE: 'IGNORE';\nIMAGE: 'IMAGE';\nIN: 'IN';\nINACTIVE: 'INACTIVE';\nINCREMENTAL: 'INCREMENTAL';\nINDEX: 'INDEX';\nINDEXES: 'INDEXES';\nINFILE: 'INFILE';\nINNER: 'INNER';\nINSTALL: 'INSTALL';\nINSERT: 'INSERT';\nINT: 'INT';\nINTEGER: 'INTEGER';\nINTEGRATION: 'INTEGRATION';\nINTEGRATIONS: 'INTEGRATIONS';\nINTERMEDIATE: 'INTERMEDIATE';\nINTERSECT: 'INTERSECT';\nINTERVAL: 'INTERVAL';\nINTO: 'INTO';\nINVOKER: 'INVOKER';\nGIN: 'GIN';\nOVERWRITE: 'OVERWRITE';\nIS: 'IS';\nISOLATION: 'ISOLATION';\nJOB: 'JOB';\nJOIN: 'JOIN';\nJSON: 'JSON';\nKEY: 'KEY';\nKEYS: 'KEYS';\nKILL: 'KILL';\nLABEL: 'LABEL';\nLAG: 'LAG';\nLARGEINT: 'LARGEINT';\nLAST: 'LAST';\nLAST_VALUE: 'LAST_VALUE';\nLATERAL: 'LATERAL';\nLEAD: 'LEAD';\nLEFT: 'LEFT';\nLESS: 'LESS';\nLEVEL: 'LEVEL';\nLIKE: 'LIKE';\nLIMIT: 'LIMIT';\nLIST: 'LIST';\nLOAD: 'LOAD';\nLOCAL: 'LOCAL';\nLOCALTIME: 'LOCALTIME';\nLOCALTIMESTAMP: 'LOCALTIMESTAMP';\nLOCATION: 'LOCATION';\nLOCATIONS: 'LOCATIONS';\nLOGS: 'LOGS';\nLOGICAL: 'LOGICAL';\nMANUAL: 'MANUAL';\nMAP: 'MAP';\nMAPPING: 'MAPPING';\nMAPPINGS: 'MAPPINGS';\nMASKING: 'MASKING';\nMATCH: 'MATCH';\nMATERIALIZED: 'MATERIALIZED';\nMAX: 'MAX';\nMAXVALUE: 'MAXVALUE';\nMERGE: 'MERGE';\nMICROSECOND: 'MICROSECOND';\nMILLISECOND: 'MILLISECOND';\nMIN: 'MIN';\nMINUTE: 'MINUTE';\nMINUTES: 'MINUTES';\nMINUS: 'MINUS';\nMETA: 'META';\nMOD: 'MOD';\nMODE: 'MODE';\nMODIFY: 'MODIFY';\nMONTH: 'MONTH';\nMULTIPLE: 'MULTIPLE';\nNAME: 'NAME';\nNAMES: 'NAMES';\nNEGATIVE: 'NEGATIVE';\nNGRAMBF: 'NGRAMBF';\nNO: 'NO';\nNODE: 'NODE';\nNODES: 'NODES';\nNONE: 'NONE';\nNOT: 'NOT';\nNULL: 'NULL';\nNULLS: 'NULLS';\nNUMBER: 'NUMBER';\nNUMERIC: 'NUMERIC';\nOBSERVER: 'OBSERVER';\nOF: 'OF';\nOFF: 'OFF';\nOFFSET: 'OFFSET';\nON: 'ON';\nONLY: 'ONLY';\nOPEN: 'OPEN';\nOPERATE: 'OPERATE';\nOPTIMIZE: 'OPTIMIZE';\nOPTIMIZER: 'OPTIMIZER';\nOPTION: 'OPTION';\nOR: 'OR';\nORDER: 'ORDER';\nOUTER: 'OUTER';\nOUTFILE: 'OUTFILE';\nOVER: 'OVER';\nPARAMETER: '?';\nPARTITION: 'PARTITION';\nPARTITIONS: 'PARTITIONS';\nPASSWORD: 'PASSWORD';\nPATH: 'PATH';\nPAUSE: 'PAUSE';\nPENDING: 'PENDING';\nPERCENT_RANK: 'PERCENT_RANK';\nPERCENTILE: 'PERCENTILE';\nPERCENTILE_UNION: 'PERCENTILE_UNION';\nPLAN: 'PLAN';\nPLUGIN: 'PLUGIN';\nPLUGINS: 'PLUGINS';\nPIPE: 'PIPE';\nPIPES: 'PIPES';\nPIVOT: 'PIVOT';\nPOLICY: 'POLICY';\nPOLICIES: 'POLICIES';\nPRECEDING: 'PRECEDING';\nPREDICATE: 'PREDICATE';\nPREPARE: 'PREPARE';\nPRIMARY: 'PRIMARY';\nPRIORITY: 'PRIORITY';\nPRIVILEGES: 'PRIVILEGES';\nPROBABILITY: 'PROBABILITY';\nPROC: 'PROC';\nPROCEDURE: 'PROCEDURE';\nPROCESSLIST: 'PROCESSLIST';\nPROFILE: 'PROFILE';\nPROFILELIST: 'PROFILELIST';\nPROPERTIES: 'PROPERTIES';\nPROPERTY: 'PROPERTY';\nPROVIDER: 'PROVIDER';\nPROVIDERS: 'PROVIDERS';\nQUALIFY: 'QUALIFY';\nQUARTER: 'QUARTER';\nQUERY: 'QUERY';\nQUERIES: 'QUERIES';\nQUEUE: 'QUEUE';\nQUOTA: 'QUOTA';\nRANDOM: 'RANDOM';\nRANGE: 'RANGE';\nRANK: 'RANK';\nREAD: 'READ';\nREASON: 'REASON';\nRECOVER: 'RECOVER';\nREFRESH: 'REFRESH';\nREWRITE: 'REWRITE';\nREGEXP: 'REGEXP';\nRELEASE: 'RELEASE';\nREMOVE: 'REMOVE';\nRENAME: 'RENAME';\nREPAIR: 'REPAIR';\nREPEATABLE: 'REPEATABLE';\nREPLACE: 'REPLACE';\nREPLACE_IF_NOT_NULL: 'REPLACE_IF_NOT_NULL';\nREPLICA: 'REPLICA';\nREPOSITORY: 'REPOSITORY';\nREPOSITORIES: 'REPOSITORIES';\nRESOURCE: 'RESOURCE';\nRESOURCES: 'RESOURCES';\nRESTORE: 'RESTORE';\nRESUME: 'RESUME';\nRETAIN: 'RETAIN';\nRETENTION: 'RETENTION';\nRETURNS: 'RETURNS';\nRETRY: 'RETRY';\nREVOKE: 'REVOKE';\nREVERT: 'REVERT';\nRIGHT: 'RIGHT';\nRLIKE: 'RLIKE';\nROLE: 'ROLE';\nROLES: 'ROLES';\nROLLBACK: 'ROLLBACK';\nROLLUP: 'ROLLUP';\nROUTINE: 'ROUTINE';\nROW: 'ROW';\nROWS: 'ROWS';\nROW_NUMBER: 'ROW_NUMBER';\nRULE: 'RULE';\nRULES: 'RULES';\nRUNNING: 'RUNNING';\nSAMPLE: 'SAMPLE';\nSCHEDULE: 'SCHEDULE';\nSCHEDULER: 'SCHEDULER';\nSCHEMA: 'SCHEMA';\nSCHEMAS: 'SCHEMAS';\nSECOND: 'SECOND';\nSECURITY: 'SECURITY';\nSELECT: 'SELECT';\nSEMI: 'SEMI';\nSEPARATOR: 'SEPARATOR';\nSERIALIZABLE: 'SERIALIZABLE';\nSESSION: 'SESSION';\nSET: 'SET';\nSETS: 'SETS';\nSET_VAR: 'SET_VAR';\nSIGNED: 'SIGNED';\nSKIP_HEADER: 'SKIP_HEADER';\nSHOW: 'SHOW';\nSMALLINT: 'SMALLINT';\nSNAPSHOT: 'SNAPSHOT';\nSNAPSHOTS: 'SNAPSHOTS';\nSQLBLACKLIST: 'SQLBLACKLIST';\nSTARROCKS: 'STARROCKS';\nSTART: 'START';\nSTATS: 'STATS';\nSTATUS: 'STATUS';\nSTOP: 'STOP';\nSTORAGE: 'STORAGE';\nSTREAM: 'STREAM';\nSTRING: 'STRING';\nTEXT: 'TEXT';\nSUBMIT: 'SUBMIT';\nSUM: 'SUM';\nSUSPEND: 'SUSPEND';\nSYNC: 'SYNC';\nSYSTEM: 'SYSTEM';\nSYSTEM_TIME: 'SYSTEM_TIME';\nSWAP: 'SWAP';\nSTRUCT: 'STRUCT';\nTABLE: 'TABLE';\nTABLES: 'TABLES';\nTABLET: 'TABLET';\nTABLETS: 'TABLETS';\nTAG: 'TAG';\nTASK: 'TASK';\nTEMPORARY: 'TEMPORARY';\nTERMINATED: 'TERMINATED';\nTHAN: 'THAN';\nTHEN: 'THEN';\nTIME: 'TIME';\nTIMES: 'TIMES';\nTIMESTAMP: 'TIMESTAMP';\nTIMESTAMPADD: 'TIMESTAMPADD';\nTIMESTAMPDIFF: 'TIMESTAMPDIFF';\nTINYINT: 'TINYINT';\nTRANSACTION: 'TRANSACTION';\nTRANSLATE: 'TRANSLATE';\nTO: 'TO';\nTRACE: 'TRACE';\nTRIGGERS: 'TRIGGERS';\nTRIM_SPACE: 'TRIM_SPACE';\nTRUE: 'TRUE';\nTRUNCATE: 'TRUNCATE';\nTYPE: 'TYPE';\nTYPES: 'TYPES';\nUNBOUNDED: 'UNBOUNDED';\nUNCOMMITTED: 'UNCOMMITTED';\nUNION: 'UNION';\nUNIQUE: 'UNIQUE';\nUNINSTALL: 'UNINSTALL';\nUNSET: 'UNSET';\nUNSIGNED: 'UNSIGNED';\nUPDATE: 'UPDATE';\nUSAGE: 'USAGE';\nUSE: 'USE';\nUSER: 'USER';\nUSERS: 'USERS';\nUSING: 'USING';\nVALUE: 'VALUE';\nVALUES: 'VALUES';\nVARBINARY: 'VARBINARY';\nVARCHAR: 'VARCHAR';\nVARIABLES: 'VARIABLES';\nVECTOR: 'VECTOR';\nVERBOSE: 'VERBOSE';\nVERSION: 'VERSION';\nVIEW: 'VIEW';\nVIEWS: 'VIEWS';\nVOLUME: 'VOLUME';\nVOLUMES: 'VOLUMES';\nWAREHOUSE: 'WAREHOUSE';\nWAREHOUSES: 'WAREHOUSES';\nWARNINGS: 'WARNINGS';\nWEEK: 'WEEK';\nWHEN: 'WHEN';\nWHERE: 'WHERE';\nWHITELIST: 'WHITELIST';\nWITH: 'WITH';\nWORK: 'WORK';\nWRITE: 'WRITE';\nYEAR: 'YEAR';\nLOCK: 'LOCK';\nUNLOCK: 'UNLOCK';\nLOW_PRIORITY: 'LOW_PRIORITY';\nDISK: 'DISK';\nBEFORE: 'BEFORE';\nDOUBLE_DOLLAR: '$$';\nFIELD: 'FIELD';\nPERSISTENT: 'PERSISTENT';\n\nEQ  : '=';\nNEQ : '<>' | '!=';\nLT  : '<';\nLTE : '<=';\nGT  : '>';\nGTE : '>=';\nEQ_FOR_NULL: '<=>';\nARRAY_ELEMENT: '[*]';\n\nPLUS_SYMBOL: '+';\nMINUS_SYMBOL: '-';\nASTERISK_SYMBOL: '*';\nSLASH_SYMBOL: '/';\nPERCENT_SYMBOL: '%';\n\nLOGICAL_OR: '||' {setType((sqlMode & io.github.melin.superior.parser.starrocks.SqlModeHelper.MODE_PIPES_AS_CONCAT) == 0 ? LOGICAL_OR : StarRocksParser.CONCAT);};\nLOGICAL_AND: '&&';\nLOGICAL_NOT: '!';\n\nINT_DIV: 'DIV';\nBITAND: '&';\nBITOR: '|';\nBITXOR: '^';\nBITNOT: '~';\nBIT_SHIFT_LEFT: 'BITSHIFTLEFT';\nBIT_SHIFT_RIGHT: 'BITSHIFTRIGHT';\nBIT_SHIFT_RIGHT_LOGICAL: 'BITSHIFTRIGHTLOGICAL';\n\nARROW: '->';\nFAT_ARROW : '=>';\nAT: '@';\n\nINTEGER_VALUE\n    : DIGIT+\n    ;\n\nDECIMAL_VALUE\n    : DIGIT+ '.' DIGIT*\n    | '.' DIGIT+\n    ;\n\nDOUBLE_VALUE\n    : DIGIT+ ('.' DIGIT*)? EXPONENT\n    | '.' DIGIT+ EXPONENT\n    ;\n\nSINGLE_QUOTED_TEXT\n    : '\\'' ('\\\\'. | '\\'\\'' | ~('\\'' | '\\\\'))* '\\''\n    ;\n\nDOUBLE_QUOTED_TEXT\n    : '\"' ('\\\\'. | '\"\"' | ~('\"'| '\\\\'))* '\"'\n    ;\n\nBINARY_SINGLE_QUOTED_TEXT\n    : 'X\\'' (~('\\'' | '\\\\'))* '\\''\n    ;\n\nBINARY_DOUBLE_QUOTED_TEXT\n    : 'X\"' (~('\"'| '\\\\'))* '\"'\n    ;\n\nLETTER_IDENTIFIER\n    : (LETTER | '_') (LETTER | DIGIT | '_')*\n    ;\n\nDIGIT_IDENTIFIER\n    : DIGIT (LETTER | DIGIT | '_')+\n    ;\n\nBACKQUOTED_IDENTIFIER\n    : '`' ( ~'`' | '``' )* '`'\n    ;\n\n// Prevent recognize string:         .123somelatin AS ((.123), DECIMAL_LITERAL), ((somelatin), IDENTIFIER)\n// it must recoginze:                .123somelatin AS ((.), DOT), (123somelatin, IDENTIFIER)\nDOT_IDENTIFIER\n    : '.' DIGIT_IDENTIFIER\n    ;\n\nfragment EXPONENT\n    : 'E' [+-]? DIGIT+\n    ;\n\nfragment DIGIT\n    : [0-9]\n    ;\n\nfragment LETTER\n    : [a-zA-Z_$\\u0080-\\uffff]\n    ;\n\nSIMPLE_COMMENT\n    : '--' ~[\\r\\n]* '\\r'? '\\n'? -> channel(HIDDEN)\n    ;\n\nBRACKETED_COMMENT\n    : '/*'([ \\r\\n\\t\\u3000]* | ~'+' .*?) '*/' -> channel(HIDDEN)\n    ;\n\nOPTIMIZER_HINT\n    : '/*+' .*? '*/' -> channel(2)\n    ;\n\nSEMICOLON: ';';\nCOLON: ':';\n\nLEFT_PAREN: '(';\nRIGHT_PAREN: ')';\nCOMMA: ',';\nDOT: '.';\nLEFT_BRACKET: '[';\nRIGHT_BRACKET: ']';\nLEFT_BRACE: '{';\nRIGHT_BRACE: '}';\n\nDOTDOTDOT: '...';\n\nWS\n    : [ \\r\\n\\t\\u3000]+ -> channel(HIDDEN)\n    ;\n\nATTACHMENT\n    : DOUBLE_DOLLAR .*? DOUBLE_DOLLAR\n    ;"
  },
  {
    "path": "superior-starrocks-parser/src/main/antlr4/io/github/melin/superior/parser/starrocks/antlr4/StarRocksParser.g4",
    "content": "// Copyright 2021-present StarRocks, Inc. All rights reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     https://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nparser grammar StarRocksParser;\noptions { tokenVocab = StarRocksLexer; }\n\nsqlStatements\n    : singleStatement* EOF\n    ;\n\nsingleStatement\n    : statement SEMICOLON?\n    ;\n\nstatement\n    // Query Statement\n    : queryStatement\n\n    // Database Statement\n    | useDatabaseStatement\n    | useCatalogStatement\n    | setCatalogStatement\n    | showDatabasesStatement\n    | alterDbQuotaStatement\n    | createDbStatement\n    | dropDbStatement\n    | showCreateDbStatement\n    | alterDatabaseRenameStatement\n    | recoverDbStmt\n    | showDataStmt\n    | showDataDistributionStmt\n\n    // Table Statement\n    | createTableStatement\n    | createTableAsSelectStatement\n    | createTableLikeStatement\n    | showCreateTableStatement\n    | dropTableStatement\n    | cleanTemporaryTableStatement\n    | recoverTableStatement\n    | truncateTableStatement\n    | showTableStatement\n    | descTableStatement\n    | showTableStatusStatement\n    | showColumnStatement\n    | refreshTableStatement\n    | alterTableStatement\n    | cancelAlterTableStatement\n    | showAlterStatement\n    | showTemporaryTablesStatement\n\n    // View Statement\n    | createViewStatement\n    | alterViewStatement\n    | dropViewStatement\n\n    // Partition Statement\n    | showPartitionsStatement\n    | recoverPartitionStatement\n\n    // Index Statement\n    | createIndexStatement\n    | dropIndexStatement\n    | showIndexStatement\n\n    // Task Statement\n    | submitTaskStatement\n    | dropTaskStatement\n\n    // Materialized View Statement\n    | createMaterializedViewStatement\n    | showMaterializedViewsStatement\n    | dropMaterializedViewStatement\n    | alterMaterializedViewStatement\n    | refreshMaterializedViewStatement\n    | cancelRefreshMaterializedViewStatement\n\n    // Catalog Statement\n    | createExternalCatalogStatement\n    | dropExternalCatalogStatement\n    | showCatalogsStatement\n    | showCreateExternalCatalogStatement\n    | alterCatalogStatement\n\n    // DML Statement\n    | insertStatement\n    | updateStatement\n    | deleteStatement\n\n    // Routine Statement\n    | createRoutineLoadStatement\n    | alterRoutineLoadStatement\n    | stopRoutineLoadStatement\n    | resumeRoutineLoadStatement\n    | pauseRoutineLoadStatement\n    | showRoutineLoadStatement\n    | showRoutineLoadTaskStatement\n    | showCreateRoutineLoadStatement\n\n    // StreamLoad Statement\n    | showStreamLoadStatement\n\n    // Admin Statement\n    | adminSetConfigStatement\n    | adminSetReplicaStatusStatement\n    | adminShowConfigStatement\n    | adminShowReplicaDistributionStatement\n    | adminShowReplicaStatusStatement\n    | adminRepairTableStatement\n    | adminCancelRepairTableStatement\n    | adminCheckTabletsStatement\n    | adminSetPartitionVersion\n    | killStatement\n    | syncStatement\n    | executeScriptStatement\n    | adminSetAutomatedSnapshotOnStatement\n    | adminSetAutomatedSnapshotOffStatement\n\n    // Cluster Management Statement\n    | alterSystemStatement\n    | cancelAlterSystemStatement\n    | showComputeNodesStatement\n\n    // Analyze Statement\n    | analyzeStatement\n    | dropStatsStatement\n    | createAnalyzeStatement\n    | dropAnalyzeJobStatement\n    | analyzeHistogramStatement\n    | dropHistogramStatement\n    | showAnalyzeStatement\n    | showStatsMetaStatement\n    | showHistogramMetaStatement\n    | killAnalyzeStatement\n\n    // Profile Statement\n    | analyzeProfileStatement\n\n    // Resource Group Statement\n    | createResourceGroupStatement\n    | dropResourceGroupStatement\n    | alterResourceGroupStatement\n    | showResourceGroupStatement\n    | showResourceGroupUsageStatement\n\n    // External Resource Statement\n    | createResourceStatement\n    | alterResourceStatement\n    | dropResourceStatement\n    | showResourceStatement\n\n    // UDF Statement\n    | showFunctionsStatement\n    | dropFunctionStatement\n    | createFunctionStatement\n\n    // Load Statement\n    | loadStatement\n    | showLoadStatement\n    | showLoadWarningsStatement\n    | cancelLoadStatement\n    | alterLoadStatement\n\n    // Show Statement\n    | showAuthorStatement\n    | showBackendsStatement\n    | showBrokerStatement\n    | showCharsetStatement\n    | showCollationStatement\n    | showDeleteStatement\n    | showDynamicPartitionStatement\n    | showEventsStatement\n    | showEnginesStatement\n    | showFrontendsStatement\n    | showPluginsStatement\n    | showRepositoriesStatement\n    | showOpenTableStatement\n    | showPrivilegesStatement\n    | showProcedureStatement\n    | showProcStatement\n    | showProcesslistStatement\n    | showProfilelistStatement\n    | showRunningQueriesStatement\n    | showStatusStatement\n    | showTabletStatement\n    | showTransactionStatement\n    | showTriggersStatement\n    | showUserPropertyStatement\n    | showVariablesStatement\n    | showWarningStatement\n    | helpStatement\n\n    // authz Statement\n    | createUserStatement\n    | dropUserStatement\n    | alterUserStatement\n    | showUserStatement\n    | showAuthenticationStatement\n    | executeAsStatement\n    | createRoleStatement\n    | alterRoleStatement\n    | dropRoleStatement\n    | showRolesStatement\n    | grantRoleStatement\n    | revokeRoleStatement\n    | setRoleStatement\n    | setDefaultRoleStatement\n    | grantPrivilegeStatement\n    | revokePrivilegeStatement\n    | showGrantsStatement\n\n    // Security Integration Statement\n    | createSecurityIntegrationStatement\n    | alterSecurityIntegrationStatement\n    | dropSecurityIntegrationStatement\n    | showSecurityIntegrationStatement\n    | showCreateSecurityIntegrationStatement\n\n    // Group Provider Statement\n    | createGroupProviderStatement\n    | dropGroupProviderStatement\n    | showGroupProvidersStatement\n    | showCreateGroupProviderStatement\n\n    // Backup Restore Statement\n    | backupStatement\n    | cancelBackupStatement\n    | showBackupStatement\n    | restoreStatement\n    | cancelRestoreStatement\n    | showRestoreStatement\n    | showSnapshotStatement\n    | createRepositoryStatement\n    | dropRepositoryStatement\n\n    // Sql BlackList And WhiteList Statement\n    | addSqlBlackListStatement\n    | delSqlBlackListStatement\n    | showSqlBlackListStatement\n    | showWhiteListStatement\n\n    // Backend BlackList\n    | addBackendBlackListStatement\n    | delBackendBlackListStatement\n    | showBackendBlackListStatement\n\n    // Data Cache management statement\n    | createDataCacheRuleStatement\n    | showDataCacheRulesStatement\n    | dropDataCacheRuleStatement\n    | clearDataCacheRulesStatement\n    | dataCacheSelectStatement\n\n    // Export Statement\n    | exportStatement\n    | cancelExportStatement\n    | showExportStatement\n\n    // Plugin Statement\n    | installPluginStatement\n    | uninstallPluginStatement\n\n    // File Statement\n    | createFileStatement\n    | dropFileStatement\n    | showSmallFilesStatement\n\n    // Set Statement\n    | setStatement\n    | setUserPropertyStatement\n\n    // Storage Volume Statement\n    | createStorageVolumeStatement\n    | alterStorageVolumeStatement\n    | dropStorageVolumeStatement\n    | showStorageVolumesStatement\n    | descStorageVolumeStatement\n    | setDefaultStorageVolumeStatement\n\n    // Pipe Statement\n    | createPipeStatement\n    | dropPipeStatement\n    | alterPipeStatement\n    | showPipeStatement\n    | descPipeStatement\n\n    // Compaction Statement\n    | cancelCompactionStatement\n\n    // FailPoint Statement\n    | updateFailPointStatusStatement\n    | showFailPointStatement\n\n    // prepare_stmt\n    | prepareStatement\n    | executeStatement\n    | deallocateStatement\n\n    // Dictionary Statement\n    | createDictionaryStatement\n    | dropDictionaryStatement\n    | refreshDictionaryStatement\n    | showDictionaryStatement\n    | cancelRefreshDictionaryStatement\n\n    // Plan advisor statement\n    | alterPlanAdvisorAddStatement\n    | truncatePlanAdvisorStatement\n    | alterPlanAdvisorDropStatement\n    | showPlanAdvisorStatement\n\n    // Warehouse Statement\n    | createWarehouseStatement\n    | dropWarehouseStatement\n    | suspendWarehouseStatement\n    | resumeWarehouseStatement\n    | setWarehouseStatement\n    | showWarehousesStatement\n    | showClustersStatement\n    | showNodesStatement\n    | alterWarehouseStatement\n\n    // CNGroup Statement\n    | createCNGroupStatement\n    | dropCNGroupStatement\n    | enableCNGroupStatement\n    | disableCNGroupStatement\n    | alterCNGroupStatement\n\n    // Transaction Statement\n    | beginStatement\n    | commitStatement\n    | rollbackStatement\n\n    // Translate Statement\n    | translateStatement\n\n    // SQL Plan Management Statement\n    | createBaselinePlanStatement\n    | dropBaselinePlanStatement\n    | showBaselinePlanStatement\n    | disableBaselinePlanStatement\n    | enableBaselinePlanStatement\n\n    // Unsupported Statement\n    | unsupportedStatement\n    ;\n\n// ---------------------------------------- DataBase Statement ---------------------------------------------------------\n\nuseDatabaseStatement\n    : USE qualifiedName\n    ;\n\nuseCatalogStatement\n    : USE string\n    ;\n\nsetCatalogStatement\n    : SET CATALOG identifierOrString\n    ;\n\nshowDatabasesStatement\n    : SHOW DATABASES ((FROM | IN) catalog=qualifiedName)? ((LIKE pattern=string) | (WHERE expression))?\n    | SHOW SCHEMAS ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nalterDbQuotaStatement\n    : ALTER DATABASE identifier SET DATA QUOTA identifier\n    | ALTER DATABASE identifier SET REPLICA QUOTA INTEGER_VALUE\n    ;\n\ncreateDbStatement\n    : CREATE (DATABASE | SCHEMA) (IF NOT EXISTS)? (catalog=identifier DOT)? database=qualifiedName charsetDesc? collateDesc? properties?\n    ;\n\ndropDbStatement\n    : DROP (DATABASE | SCHEMA) (IF EXISTS)? (catalog=identifier DOT)? database=qualifiedName FORCE?\n    ;\n\nshowCreateDbStatement\n    : SHOW CREATE (DATABASE | SCHEMA) identifier\n    ;\n\nalterDatabaseRenameStatement\n    : ALTER DATABASE identifier RENAME identifier\n    ;\n\nrecoverDbStmt\n    : RECOVER (DATABASE | SCHEMA) identifier\n    ;\n\nshowDataStmt\n    : SHOW DATA\n    | SHOW DATA FROM qualifiedName\n    ;\n\nshowDataDistributionStmt\n    : SHOW DATA DISTRIBUTION FROM qualifiedName partitionNames?\n    ;\n\n// ------------------------------------------- Table Statement ---------------------------------------------------------\n\ncreateTableStatement\n    : CREATE (TEMPORARY | EXTERNAL)? TABLE (IF NOT EXISTS)? qualifiedName\n          LEFT_PAREN columnDesc (COMMA columnDesc)* (COMMA indexDesc)* RIGHT_PAREN\n          engineDesc?\n          charsetDesc?\n          keyDesc?\n          comment?\n          partitionDesc?\n          distributionDesc?\n          orderByDesc?\n          rollupDesc?\n          properties?\n          extProperties?\n     ;\n\n\ncolumnDesc\n    : identifier type? charsetName? KEY? aggDesc? columnNullable?\n    (defaultDesc | AUTO_INCREMENT | generatedColumnDesc)?\n    comment?\n    ;\n\ncharsetName\n    : CHAR SET identifier\n    | CHARSET identifier\n    | CHARACTER SET identifier\n    ;\n\ndefaultDesc\n    : DEFAULT (string | NULL | CURRENT_TIMESTAMP (LEFT_PAREN (INTEGER_VALUE)? RIGHT_PAREN)? | LEFT_PAREN qualifiedName LEFT_PAREN RIGHT_PAREN RIGHT_PAREN)\n    ;\n\ngeneratedColumnDesc\n    : AS expression\n    ;\n\nindexDesc\n    : INDEX indexName=identifier identifierList (indexType propertyList?)? comment?\n    ;\n\nengineDesc\n    : ENGINE EQ identifier\n    ;\n\ncharsetDesc\n    : DEFAULT? (CHAR SET | CHARSET | CHARACTER SET) EQ? identifierOrString\n    ;\n\ncollateDesc\n    : DEFAULT? COLLATE EQ? identifierOrString\n    ;\n\nkeyDesc\n    : (AGGREGATE | UNIQUE | PRIMARY | DUPLICATE) KEY identifierList\n    ;\n\norderByDesc\n    : ORDER BY identifierList\n    ;\n\ncolumnNullable\n    : NULL\n    | NOT NULL\n    ;\n\ntypeWithNullable\n    : type columnNullable?\n    ;\n\naggStateDesc\n    : identifier LEFT_PAREN typeWithNullable (COMMA typeWithNullable)* RIGHT_PAREN\n    ;\n\naggDesc\n    : SUM\n    | MAX\n    | MIN\n    | REPLACE\n    | HLL_UNION\n    | BITMAP_UNION\n    | PERCENTILE_UNION\n    | REPLACE_IF_NOT_NULL\n    | aggStateDesc\n    ;\n\nrollupDesc\n    : ROLLUP LEFT_PAREN rollupItem (COMMA rollupItem)* RIGHT_PAREN\n    ;\n\nrollupItem\n    : rollupName=identifier identifierList (dupKeys)? (fromRollup)? properties?\n    ;\n\ndupKeys\n    : DUPLICATE KEY identifierList\n    ;\n\nfromRollup\n    : FROM identifier\n    ;\n\norReplace:\n    (OR REPLACE)?\n    ;\nifNotExists:\n    (IF NOT EXISTS)?\n    ;\n\ncreateTableAsSelectStatement\n    : CREATE TEMPORARY? TABLE (IF NOT EXISTS)? qualifiedName\n        (LEFT_PAREN (identifier (COMMA identifier)*  (COMMA indexDesc)* | indexDesc (COMMA indexDesc)*) RIGHT_PAREN)?\n        keyDesc?\n        comment?\n        partitionDesc?\n        distributionDesc?\n        orderByDesc?\n        properties?\n        AS queryStatement\n    ;\n\n\ndropTableStatement\n    : DROP TEMPORARY? TABLE (IF EXISTS)? qualifiedName FORCE?\n    ;\n\ncleanTemporaryTableStatement\n    : CLEAN TEMPORARY TABLE ON SESSION string\n    ;\n\nalterTableStatement\n    : ALTER TABLE qualifiedName alterClause (COMMA alterClause)*\n    | ALTER TABLE qualifiedName ADD ROLLUP rollupItem (COMMA rollupItem)*\n    | ALTER TABLE qualifiedName DROP ROLLUP identifier (COMMA identifier)*\n    ;\n\ncreateIndexStatement\n    : CREATE INDEX indexName=identifier\n        ON qualifiedName identifierList (indexType propertyList?)?\n        comment?\n    ;\n\ndropIndexStatement\n    : DROP INDEX indexName=identifier ON qualifiedName\n    ;\n\nindexType\n    : USING (BITMAP | GIN | NGRAMBF | VECTOR)\n    ;\n\nshowTableStatement\n    : SHOW FULL? TABLES ((FROM | IN) db=qualifiedName)? ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nshowTemporaryTablesStatement\n    : SHOW TEMPORARY TABLES ((FROM | IN) db=qualifiedName)? ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nshowCreateTableStatement\n    : SHOW CREATE (TABLE | VIEW | MATERIALIZED VIEW) table=qualifiedName\n    ;\n\nshowColumnStatement\n    : SHOW FULL? (COLUMNS | FIELDS) ((FROM | IN) table=qualifiedName) ((FROM | IN) db=qualifiedName)?\n        ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nshowTableStatusStatement\n    : SHOW TABLE STATUS ((FROM | IN) db=qualifiedName)? ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nrefreshTableStatement\n    : REFRESH EXTERNAL TABLE qualifiedName (PARTITION LEFT_PAREN string (COMMA string)* RIGHT_PAREN)?\n    ;\n\nshowAlterStatement\n    : SHOW ALTER TABLE (COLUMN | ROLLUP | OPTIMIZE) ((FROM | IN) db=qualifiedName)?\n        (WHERE expression)? (ORDER BY sortItem (COMMA sortItem)*)? (limitElement)?\n    | SHOW ALTER MATERIALIZED VIEW ((FROM | IN) db=qualifiedName)?\n              (WHERE expression)? (ORDER BY sortItem (COMMA sortItem)*)? (limitElement)?\n    ;\n\ndescTableStatement\n    : (DESC | DESCRIBE) ((table=qualifiedName ALL?) | (FILES propertyList))\n    ;\n\ncreateTableLikeStatement\n    : CREATE (TEMPORARY | EXTERNAL)? TABLE (IF NOT EXISTS)? qualifiedName\n        partitionDesc?\n        distributionDesc?\n        properties?\n        LIKE qualifiedName\n    ;\n\nshowIndexStatement\n    : SHOW (INDEX | INDEXES | KEY | KEYS) ((FROM | IN) table=qualifiedName) ((FROM | IN) db=qualifiedName)?\n    ;\n\nrecoverTableStatement\n    : RECOVER TABLE qualifiedName\n    ;\n\ntruncateTableStatement\n    : TRUNCATE TABLE qualifiedName partitionNames?\n    ;\n\ncancelAlterTableStatement\n    : CANCEL ALTER TABLE (COLUMN | ROLLUP | OPTIMIZE)? FROM qualifiedName (LEFT_PAREN INTEGER_VALUE (COMMA INTEGER_VALUE)* RIGHT_PAREN)?\n    | CANCEL ALTER MATERIALIZED VIEW FROM qualifiedName\n    ;\n\nshowPartitionsStatement\n    : SHOW TEMPORARY? PARTITIONS FROM table=qualifiedName\n    (WHERE expression)?\n    (ORDER BY sortItem (COMMA sortItem)*)? limitElement?\n    ;\n\nrecoverPartitionStatement\n    : RECOVER PARTITION identifier FROM table=qualifiedName\n    ;\n\n// ------------------------------------------- View Statement ----------------------------------------------------------\n\ncreateViewStatement\n    : CREATE (OR REPLACE)? VIEW (IF NOT EXISTS)? qualifiedName\n    (LEFT_PAREN columnNameWithComment (COMMA columnNameWithComment)* RIGHT_PAREN)?\n    comment?\n    (SECURITY (NONE | INVOKER))?\n    AS queryStatement\n    ;\n\nalterViewStatement\n    : ALTER VIEW qualifiedName (LEFT_PAREN columnNameWithComment (COMMA columnNameWithComment)* RIGHT_PAREN)? AS queryStatement\n    | ALTER VIEW qualifiedName SET SECURITY (NONE | INVOKER)\n    | ALTER VIEW qualifiedName SET properties\n    | ALTER VIEW qualifiedName (ADD | MODIFY) DIALECT (STARROCKS)?  queryStatement\n    ;\n\ndropViewStatement\n    : DROP VIEW (IF EXISTS)? qualifiedName\n    ;\n\ncolumnNameWithComment\n    : columnName=identifier comment?\n    ;\n\n// ------------------------------------------- Task Statement ----------------------------------------------------------\n\nsubmitTaskStatement\n    : SUBMIT TASK qualifiedName?\n        taskClause*\n        AS (createTableAsSelectStatement | insertStatement | dataCacheSelectStatement)\n    ;\n\ntaskClause\n    : properties\n    | taskScheduleDesc\n    ;\n\ndropTaskStatement\n    : DROP TASK qualifiedName FORCE?\n    ;\n\ntaskScheduleDesc\n    : SCHEDULE (START LEFT_PAREN string RIGHT_PAREN)? EVERY LEFT_PAREN taskInterval RIGHT_PAREN\n    ;\n\n// ------------------------------------------- Materialized View Statement ---------------------------------------------\n\ncreateMaterializedViewStatement\n    : CREATE MATERIALIZED VIEW (IF NOT EXISTS)? mvName=qualifiedName\n    (LEFT_PAREN columnNameWithComment (COMMA columnNameWithComment)* (COMMA indexDesc)* RIGHT_PAREN)?\n    comment?\n    materializedViewDesc*\n    AS queryStatement\n    ;\n\nmvPartitionExprs:\n    primaryExpression\n    | LEFT_PAREN primaryExpression (COMMA primaryExpression)* RIGHT_PAREN\n    ;\n\nmaterializedViewDesc\n    : (PARTITION BY mvPartitionExprs)\n    | distributionDesc\n    | orderByDesc\n    | refreshSchemeDesc\n    | properties\n    ;\n\nshowMaterializedViewsStatement\n    : SHOW MATERIALIZED VIEWS ((FROM | IN) db=qualifiedName)? ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\ndropMaterializedViewStatement\n    : DROP MATERIALIZED VIEW (IF EXISTS)? mvName=qualifiedName\n    ;\n\nalterMaterializedViewStatement\n    : ALTER MATERIALIZED VIEW mvName=qualifiedName (\n        refreshSchemeDesc |\n        tableRenameClause |\n        modifyPropertiesClause |\n        swapTableClause )\n    | ALTER MATERIALIZED VIEW mvName=qualifiedName statusDesc\n    ;\n\nrefreshMaterializedViewStatement\n    : REFRESH MATERIALIZED VIEW mvName=qualifiedName (PARTITION (partitionRangeDesc | listPartitionValues))? FORCE? (WITH (SYNC | ASYNC) MODE)? (WITH PRIORITY priority=INTEGER_VALUE)?\n    ;\n\ncancelRefreshMaterializedViewStatement\n    : CANCEL REFRESH MATERIALIZED VIEW mvName=qualifiedName FORCE?\n    ;\n\n// ------------------------------------------- Admin Statement ---------------------------------------------------------\n\nadminSetConfigStatement\n    : ADMIN SET FRONTEND CONFIG LEFT_PAREN property RIGHT_PAREN (WITH PERSISTENT)?\n    ;\nadminSetReplicaStatusStatement\n    : ADMIN SET REPLICA STATUS properties\n    ;\nadminShowConfigStatement\n    : ADMIN SHOW FRONTEND CONFIG (LIKE pattern=string)?\n    ;\n\nadminShowReplicaDistributionStatement\n    : ADMIN SHOW REPLICA DISTRIBUTION FROM qualifiedName partitionNames?\n    ;\n\nadminShowReplicaStatusStatement\n    : ADMIN SHOW REPLICA STATUS FROM qualifiedName partitionNames? (WHERE where=expression)?\n    ;\n\nadminRepairTableStatement\n    : ADMIN REPAIR TABLE qualifiedName partitionNames?\n    ;\n\nadminCancelRepairTableStatement\n    : ADMIN CANCEL REPAIR TABLE qualifiedName partitionNames?\n    ;\n\nadminCheckTabletsStatement\n    : ADMIN CHECK tabletList PROPERTIES LEFT_PARENpropertyRIGHT_PAREN\n    ;\n\nadminSetPartitionVersion\n    : ADMIN SET TABLE qualifiedName PARTITION LEFT_PAREN(partitionName=identifierOrString | partitionId=INTEGER_VALUE)RIGHT_PAREN VERSION TO version=INTEGER_VALUE\n    ;\n\nkillStatement\n    : KILL (CONNECTION? | QUERY) (connId=INTEGER_VALUE | queryId=string)\n    ;\n\nsyncStatement\n    : SYNC\n    ;\n\nadminSetAutomatedSnapshotOnStatement\n    : ADMIN SET AUTOMATED CLUSTER SNAPSHOT ON (STORAGE VOLUME svName=identifier)?\n    ;\n\nadminSetAutomatedSnapshotOffStatement\n    : ADMIN SET AUTOMATED CLUSTER SNAPSHOT OFF\n    ;\n\n// ------------------------------------------- Cluster Management Statement ---------------------------------------------\n\nalterSystemStatement\n    : ALTER SYSTEM alterClause\n    ;\n\ncancelAlterSystemStatement\n    : CANCEL DECOMMISSION BACKEND string (COMMA string)*\n    ;\n\nshowComputeNodesStatement\n    : SHOW COMPUTE NODES\n    ;\n\n// ------------------------------------------- Catalog Statement -------------------------------------------------------\n\ncreateExternalCatalogStatement\n    : CREATE EXTERNAL CATALOG (IF NOT EXISTS)? catalogName=identifierOrString comment? properties\n    ;\n\nshowCreateExternalCatalogStatement\n    : SHOW CREATE CATALOG catalogName=identifierOrString\n    ;\n\ndropExternalCatalogStatement\n    : DROP CATALOG (IF EXISTS)? catalogName=identifierOrString\n    ;\n\nshowCatalogsStatement\n    : SHOW CATALOGS (LIKE pattern=string)?\n    ;\n\nalterCatalogStatement\n    : ALTER CATALOG catalogName=identifierOrString modifyPropertiesClause\n    ;\n\n// ---------------------------------------- Storage Volume Statement ---------------------------------------------------\n\ncreateStorageVolumeStatement\n    : CREATE STORAGE VOLUME (IF NOT EXISTS)? storageVolumeName=identifierOrString typeDesc locationsDesc\n          comment? properties?\n    ;\n\ntypeDesc\n    : TYPE EQ identifier\n    ;\n\nlocationsDesc\n    : LOCATIONS EQ stringList\n    ;\n\nshowStorageVolumesStatement\n    : SHOW STORAGE VOLUMES (LIKE pattern=string)?\n    ;\n\ndropStorageVolumeStatement\n    : DROP STORAGE VOLUME (IF EXISTS)? storageVolumeName=identifierOrString\n    ;\n\nalterStorageVolumeStatement\n    : ALTER STORAGE VOLUME identifierOrString alterStorageVolumeClause (COMMA alterStorageVolumeClause)*\n    ;\n\nalterStorageVolumeClause\n    : modifyStorageVolumeCommentClause\n    | modifyStorageVolumePropertiesClause\n    ;\n\nmodifyStorageVolumePropertiesClause\n    : SET propertyList\n    ;\n\nmodifyStorageVolumeCommentClause\n    : COMMENT '=' string\n    ;\n\ndescStorageVolumeStatement\n    : (DESC | DESCRIBE) STORAGE VOLUME identifierOrString\n    ;\n\nsetDefaultStorageVolumeStatement\n    : SET identifierOrString AS DEFAULT STORAGE VOLUME\n    ;\n\n// ------------------------------------------- FailPoint Statement -----------------------------------------------------\n\nupdateFailPointStatusStatement\n    : ADMIN (DISABLE | ENABLE) FAILPOINT string\n      (WITH (times=INTEGER_VALUE TIMES | prob=DECIMAL_VALUE PROBABILITY))?\n      (ON (BACKEND string | FRONTEND))?\n    ;\n\nshowFailPointStatement\n    : SHOW FAILPOINTS ((LIKE pattern=string))? (ON BACKEND string)?\n    ;\n\n// ------------------------------------------- Dictionary Statement -----------------------------------------------------\n\ncreateDictionaryStatement\n    : CREATE DICTIONARY dictionaryName USING qualifiedName\n        LEFT_PAREN dictionaryColumnDesc (COMMA dictionaryColumnDesc)* RIGHT_PAREN\n        properties?\n    ;\n\ndropDictionaryStatement\n    : DROP DICTIONARY qualifiedName CACHE?\n    ;\n\nrefreshDictionaryStatement\n    : REFRESH DICTIONARY qualifiedName\n    ;\n\nshowDictionaryStatement\n    : SHOW DICTIONARY qualifiedName?\n    ;\n\ncancelRefreshDictionaryStatement\n    : CANCEL REFRESH DICTIONARY qualifiedName;\n\ndictionaryColumnDesc\n    : qualifiedName KEY\n    | qualifiedName VALUE\n    ;\n\ndictionaryName\n    : qualifiedName\n    ;\n\n// ------------------------------------------- Alter Clause ------------------------------------------------------------\n\nalterClause\n    //Alter system clause\n    : addFrontendClause\n    | dropFrontendClause\n    | modifyFrontendHostClause\n    | addBackendClause\n    | dropBackendClause\n    | decommissionBackendClause\n    | modifyBackendClause\n    | addComputeNodeClause\n    | dropComputeNodeClause\n    | modifyBrokerClause\n    | alterLoadErrorUrlClause\n    | createImageClause\n    | cleanTabletSchedQClause\n    | decommissionDiskClause\n    | cancelDecommissionDiskClause\n    | disableDiskClause\n    | cancelDisableDiskClause\n\n    //Alter table clause\n    | createIndexClause\n    | dropIndexClause\n    | tableRenameClause\n    | swapTableClause\n    | modifyPropertiesClause\n    | addColumnClause\n    | addColumnsClause\n    | dropColumnClause\n    | modifyColumnCommentClause\n    | modifyColumnClause\n    | columnRenameClause\n    | reorderColumnsClause\n    | rollupRenameClause\n    | compactionClause\n    | modifyCommentClause\n    | optimizeClause\n    | addFieldClause\n    | dropFieldClause\n    | createOrReplaceBranchClause\n    | createOrReplaceTagClause\n    | dropBranchClause\n    | dropTagClause\n    | tableOperationClause\n    | dropPersistentIndexClause\n\n    //Alter partition clause\n    | addPartitionClause\n    | dropPartitionClause\n    | distributionClause\n    | truncatePartitionClause\n    | modifyPartitionClause\n    | replacePartitionClause\n    | partitionRenameClause\n    ;\n\n// ---------Alter system clause---------\n\naddFrontendClause\n   : ADD (FOLLOWER | OBSERVER) string\n   ;\n\ndropFrontendClause\n   : DROP (FOLLOWER | OBSERVER) string\n   ;\n\nmodifyFrontendHostClause\n  : MODIFY FRONTEND HOST string TO string\n  ;\n\naddBackendClause\n   : ADD BACKEND string (COMMA string)* (INTO WAREHOUSE warehouseName=identifierOrString (CNGROUP cngroupName=identifierOrString)?)?\n   ;\n\ndropBackendClause\n   : DROP BACKEND string (COMMA string)* (FROM WAREHOUSE warehouseName=identifierOrString (CNGROUP cngroupName=identifierOrString)?)? FORCE?\n   ;\n\ndecommissionBackendClause\n   : DECOMMISSION BACKEND string (COMMA string)*\n   ;\n\nmodifyBackendClause\n   : MODIFY BACKEND HOST string TO string\n   | MODIFY BACKEND string SET propertyList\n   ;\n\naddComputeNodeClause\n   : ADD COMPUTE NODE string (COMMA string)* (INTO WAREHOUSE warehouseName=identifierOrString (CNGROUP cngroupName=identifierOrString)?)?\n   ;\n\ndropComputeNodeClause\n   : DROP COMPUTE NODE string (COMMA string)* (FROM WAREHOUSE warehouseName=identifierOrString (CNGROUP cngroupName=identifierOrString)?)?\n   ;\n\nmodifyBrokerClause\n    : ADD BROKER identifierOrString string (COMMA string)*\n    | DROP BROKER identifierOrString string (COMMA string)*\n    | DROP ALL BROKER identifierOrString\n    ;\n\nalterLoadErrorUrlClause\n    : SET LOAD ERRORS HUB properties?\n    ;\n\ncreateImageClause\n    : CREATE IMAGE\n    ;\n\ncleanTabletSchedQClause\n    : CLEAN TABLET SCHEDULER QUEUE\n    ;\n\ndecommissionDiskClause\n    : DECOMMISSION DISK string (COMMA string)* ON BACKEND string\n    ;\n\ncancelDecommissionDiskClause\n    : CANCEL DECOMMISSION DISK string (COMMA string)* ON BACKEND string\n    ;\n\ndisableDiskClause\n    : DISABLE DISK string (COMMA string)* ON BACKEND string\n    ;\n\ncancelDisableDiskClause\n    : CANCEL DISABLE DISK string (COMMA string)* ON BACKEND string\n    ;\n\n// ---------Alter table clause---------\n\ncreateIndexClause\n    : ADD INDEX indexName=identifier identifierList (indexType propertyList?)? comment?\n    ;\n\ndropIndexClause\n    : DROP INDEX indexName=identifier\n    ;\n\ntableRenameClause\n    : RENAME identifier\n    ;\n\nswapTableClause\n    : SWAP WITH identifier\n    ;\n\nmodifyPropertiesClause\n    : SET propertyList\n    ;\n\nmodifyCommentClause\n    : COMMENT '=' string\n    ;\n\noptimizeRange\n    : BETWEEN start=string AND end=string\n    ;\n\noptimizeClause\n    : partitionNames?\n      keyDesc?\n      partitionDesc?\n      orderByDesc?\n      distributionDesc?\n      optimizeRange?\n     ;\n\naddColumnClause\n    : ADD COLUMN columnDesc (FIRST | AFTER identifier)? ((TO | IN) rollupName=identifier)? properties?\n    ;\n\naddColumnsClause\n    : ADD COLUMN LEFT_PAREN columnDesc (COMMA columnDesc)* RIGHT_PAREN ((TO | IN) rollupName=identifier)? properties?\n    ;\n\ndropColumnClause\n    : DROP COLUMN identifier (FROM rollupName=identifier)? properties?\n    ;\n\nmodifyColumnClause\n    : MODIFY COLUMN columnDesc (FIRST | AFTER identifier)? (FROM rollupName=identifier)? properties?\n    ;\n\nmodifyColumnCommentClause\n    : MODIFY COLUMN identifier comment\n    ;\n\ncolumnRenameClause\n    : RENAME COLUMN oldColumn=identifier TO newColumn=identifier\n    ;\n\nreorderColumnsClause\n    : ORDER BY identifierList (FROM rollupName=identifier)? properties?\n    ;\n\nrollupRenameClause\n    : RENAME ROLLUP rollupName=identifier newRollupName=identifier\n    ;\n\ncompactionClause\n    : (BASE | CUMULATIVE)? COMPACT (identifier | identifierList)?\n    ;\n\nsubfieldName\n    : identifier | ARRAY_ELEMENT\n    ;\n\nnestedFieldName\n    : subfieldName (DOT_IDENTIFIER | DOT subfieldName)*\n    ;\n\naddFieldClause\n    : MODIFY COLUMN identifier ADD FIELD subfieldDesc (FIRST | AFTER identifier)? properties?\n    ;\n\ndropFieldClause\n    : MODIFY COLUMN identifier DROP FIELD nestedFieldName properties?\n    ;\n\ncreateOrReplaceTagClause\n    : (CREATE OR)? REPLACE TAG identifier tagOptions\n    | CREATE TAG (IF NOT EXISTS)? identifier tagOptions\n    ;\n\ncreateOrReplaceBranchClause\n    : (CREATE OR)? REPLACE BRANCH identifier branchOptions\n    | CREATE BRANCH (IF NOT EXISTS)? identifier branchOptions\n    ;\n\ndropBranchClause\n    : DROP BRANCH (IF EXISTS)? identifier\n    ;\n\ndropTagClause\n    : DROP TAG (IF EXISTS)? identifier\n    ;\n\ntableOperationClause\n    : EXECUTE functionCall\n    ;\n\ntagOptions\n    : (AS OF VERSION snapshotId)? (refRetain)?\n    ;\n\nbranchOptions\n    : (AS OF VERSION snapshotId)? (refRetain)? (snapshotRetention)?\n    ;\n\nsnapshotRetention\n    : WITH SNAPSHOT RETENTION minSnapshotsToKeep\n    | WITH SNAPSHOT RETENTION maxSnapshotAge\n    | WITH SNAPSHOT RETENTION minSnapshotsToKeep maxSnapshotAge\n    ;\n\nrefRetain\n    : RETAIN number timeUnit\n    ;\n\nmaxSnapshotAge\n    : number timeUnit\n    ;\n\nminSnapshotsToKeep\n    : number SNAPSHOTS\n    ;\n\nsnapshotId\n    : number\n    ;\n\ntimeUnit\n    : DAYS\n    | HOURS\n    | MINUTES\n    ;\n\ninteger_list\n    : LEFT_PAREN INTEGER_VALUE (COMMA INTEGER_VALUE)* RIGHT_PAREN\n    ;\n\ndropPersistentIndexClause\n    : DROP PERSISTENT INDEX ON TABLETS integer_list\n    ;\n\n// ---------Alter partition clause---------\n\naddPartitionClause\n    : ADD TEMPORARY? (singleRangePartition | PARTITIONS multiRangePartition) distributionDesc? properties?\n    | ADD TEMPORARY? (singleItemListPartitionDesc | multiItemListPartitionDesc) distributionDesc? properties?\n    ;\n\ndropPartitionClause\n    : DROP TEMPORARY? (PARTITION (IF EXISTS)? identifier | PARTITIONS (IF EXISTS)? identifierList) FORCE?\n    | DROP TEMPORARY? PARTITIONS (IF EXISTS)? multiRangePartition FORCE?\n    | DROP TEMPORARY? PARTITIONS (IF EXISTS)? WHERE where=expression FORCE?\n    | DROP ALL TEMPORARY PARTITIONS FORCE?\n    ;\n\ntruncatePartitionClause\n    : TRUNCATE partitionNames\n    ;\n\nmodifyPartitionClause\n    : MODIFY PARTITION (identifier | identifierList | LEFT_PAREN ASTERISK_SYMBOL RIGHT_PAREN) SET propertyList\n    | MODIFY PARTITION distributionDesc\n    ;\n\nreplacePartitionClause\n    : REPLACE parName=partitionNames WITH tempParName=partitionNames properties?\n    ;\n\npartitionRenameClause\n    : RENAME PARTITION parName=identifier newParName=identifier\n    ;\n\n// ------------------------------------------- DML Statement -----------------------------------------------------------\n\ninsertStatement\n    : explainDesc? INSERT (INTO | OVERWRITE) (qualifiedName writeBranch? partitionNames? | (FILES propertyList) | (BLACKHOLE LEFT_PAREN RIGHT_PAREN))\n        insertLabelOrColumnAliases* properties?\n        (queryStatement | (VALUES expressionsWithDefault (COMMA expressionsWithDefault)*))\n    ;\n\n// for compatibility with the case 'LABEL before columnAliases'\ninsertLabelOrColumnAliases\n    : columnAliasesOrByName\n    | WITH LABEL label=identifier\n    ;\n\ncolumnAliasesOrByName\n    : columnAliases\n    | BY NAME\n    ;\n\nupdateStatement\n    : explainDesc? withClause? UPDATE qualifiedName SET assignmentList fromClause (WHERE where=expression)?\n    ;\n\ndeleteStatement\n    : explainDesc? withClause? DELETE FROM qualifiedName partitionNames? (USING using=relations)? (WHERE where=expression)?\n    ;\n\n// ------------------------------------------- Routine Statement -----------------------------------------------------------\ncreateRoutineLoadStatement\n    : CREATE ROUTINE LOAD (db=qualifiedName DOT)? name=identifier ON table=qualifiedName\n        loadPropertiesExpr\n        jobProperties?\n        FROM source=identifier\n        dataSourceProperties?\n    ;\n\nalterRoutineLoadStatement\n    : ALTER ROUTINE LOAD FOR (db=qualifiedName DOT)? name=identifier\n        loadPropertiesExpr\n        jobProperties?\n        dataSource?\n    ;\n\nloadPropertiesExpr\n    : (loadProperties (COMMA loadProperties)*)?\n    ;\n\ndataSource\n    : FROM source=identifier dataSourceProperties\n    ;\n\nloadProperties\n    : colSeparatorProperty\n    | rowDelimiterProperty\n    | importColumns\n    | WHERE expression\n    | partitionNames\n    ;\n\ncolSeparatorProperty\n    : COLUMNS TERMINATED BY string\n    ;\n\nrowDelimiterProperty\n    : ROWS TERMINATED BY string\n    ;\n\nimportColumns\n    : COLUMNS columnProperties\n    ;\n\ncolumnProperties\n    : LEFT_PAREN\n        (qualifiedName | assignment) (COMMA (qualifiedName | assignment))*\n      RIGHT_PAREN\n    ;\n\njobProperties\n    : properties\n    ;\n\ndataSourceProperties\n    : propertyList\n    ;\n\nstopRoutineLoadStatement\n    : STOP ROUTINE LOAD FOR (db=qualifiedName DOT)? name=identifier\n    ;\n\nresumeRoutineLoadStatement\n    : RESUME ROUTINE LOAD FOR (db=qualifiedName DOT)? name=identifier\n    ;\n\npauseRoutineLoadStatement\n    : PAUSE ROUTINE LOAD FOR (db=qualifiedName DOT)? name=identifier\n    ;\n\nshowRoutineLoadStatement\n    : SHOW ALL? ROUTINE LOAD (FOR (db=qualifiedName DOT)? name=identifier)?\n        (FROM db=qualifiedName)?\n        (WHERE expression)? (ORDER BY sortItem (COMMA sortItem)*)? (limitElement)?\n    ;\n\nshowRoutineLoadTaskStatement\n    : SHOW ROUTINE LOAD TASK\n        (FROM db=qualifiedName)?\n        WHERE expression\n    ;\n\nshowCreateRoutineLoadStatement\n    : SHOW CREATE ROUTINE LOAD (db=qualifiedName DOT)? name=identifier\n    ;\n\nshowStreamLoadStatement\n    : SHOW ALL? STREAM LOAD (FOR (db=qualifiedName DOT)? name=identifier)?\n        (FROM db=qualifiedName)?\n        (WHERE expression)? (ORDER BY sortItem (COMMA sortItem)*)? (limitElement)?\n    ;\n// ------------------------------------------- Analyze Statement -------------------------------------------------------\n\nanalyzeStatement\n    : ANALYZE (FULL | SAMPLE)? TABLE tableName analyzeColumnClause? partitionNames?\n        (WITH (SYNC | ASYNC) MODE)?\n        properties?\n    ;\n\nanalyzeColumnClause\n    : LEFT_PAREN qualifiedName  (COMMA qualifiedName)* RIGHT_PAREN               #regularColumns\n    | qualifiedName  (COMMA qualifiedName)*                       #regularColumns\n    | ALL COLUMNS                                               #allColumns\n    | PREDICATE COLUMNS                                         #predicateColumns\n    | MULTIPLE COLUMNS LEFT_PAREN qualifiedName  (COMMA qualifiedName)* RIGHT_PAREN #multiColumnSet\n    ;\n\ndropStatsStatement\n    : DROP (MULTIPLE COLUMNS)? STATS qualifiedName\n    ;\n\nhistogramStatement:\n    ANALYZE TABLE tableName UPDATE HISTOGRAM ON analyzeColumnClause\n        (WITH bucket=INTEGER_VALUE BUCKETS)?\n        properties?\n    ;\n\nanalyzeHistogramStatement\n    : histogramStatement\n        (WITH (SYNC | ASYNC) MODE)?\n    ;\n\ndropHistogramStatement\n    : ANALYZE TABLE qualifiedName DROP HISTOGRAM ON qualifiedName (COMMA qualifiedName)*\n    ;\n\ncreateAnalyzeStatement\n    : CREATE ANALYZE (FULL | SAMPLE)? ALL properties?\n    | CREATE ANALYZE (FULL | SAMPLE)? DATABASE db=identifier properties?\n    | CREATE ANALYZE (FULL | SAMPLE)? TABLE qualifiedName (LEFT_PAREN qualifiedName (COMMA qualifiedName)* RIGHT_PAREN)? properties?\n    | CREATE histogramStatement\n    ;\n\ndropAnalyzeJobStatement\n    : DROP ANALYZE INTEGER_VALUE\n    | DROP ALL ANALYZE JOB\n    ;\n\nshowAnalyzeStatement\n    : SHOW ANALYZE (JOB | STATUS)? (WHERE expression)? (ORDER BY sortItem (COMMA sortItem)*)? limitElement?\n    ;\n\nshowStatsMetaStatement\n    : SHOW (MULTIPLE COLUMNS)? STATS META (WHERE expression)? (ORDER BY sortItem (COMMA sortItem)*)? limitElement?\n    ;\n\nshowHistogramMetaStatement\n    : SHOW HISTOGRAM META (WHERE expression)? (ORDER BY sortItem (COMMA sortItem)*)? limitElement?\n    ;\n\nkillAnalyzeStatement\n    : KILL ANALYZE INTEGER_VALUE\n    ;\n\n// ----------------------------------------- Analyze Profile Statement -------------------------------------------------\n\nanalyzeProfileStatement\n    : ANALYZE PROFILE FROM string\n    | ANALYZE PROFILE FROM string COMMA INTEGER_VALUE (COMMA INTEGER_VALUE)*\n    ;\n\n\n// ----------------------------------------- SQL Plan Manager Statement -------------------------------------------------\ncreateBaselinePlanStatement\n    : CREATE GLOBAL? BASELINE (ON queryRelation)? USING queryRelation properties?\n    ;\n\ndropBaselinePlanStatement\n    : DROP BASELINE INTEGER_VALUE (COMMA INTEGER_VALUE)*\n    ;\n\nshowBaselinePlanStatement\n    : SHOW BASELINE (WHERE expression)?\n\n    ;\n\ndisableBaselinePlanStatement\n    : DISABLE BASELINE INTEGER_VALUE (COMMA INTEGER_VALUE)*\n    ;\n\nenableBaselinePlanStatement\n    : ENABLE BASELINE INTEGER_VALUE (COMMA INTEGER_VALUE)*\n    ;\n\n// ------------------------------------------- Work Group Statement ----------------------------------------------------\n\ncreateResourceGroupStatement\n    : CREATE RESOURCE GROUP (IF NOT EXISTS)? (OR REPLACE)? identifier\n        (TO classifier (COMMA classifier)*)?  WITH LEFT_PAREN property (COMMA property)* RIGHT_PAREN\n    ;\n\ndropResourceGroupStatement\n    : DROP RESOURCE GROUP identifier\n    ;\n\nalterResourceGroupStatement\n    : ALTER RESOURCE GROUP identifier ADD classifier (COMMA classifier)*\n    | ALTER RESOURCE GROUP identifier DROP LEFT_PAREN INTEGER_VALUE (COMMA INTEGER_VALUE)* RIGHT_PAREN\n    | ALTER RESOURCE GROUP identifier DROP ALL\n    | ALTER RESOURCE GROUP identifier WITH LEFT_PAREN property (COMMA property)* RIGHT_PAREN\n    ;\n\nshowResourceGroupStatement\n    : SHOW VERBOSE? RESOURCE GROUP identifier\n    | SHOW VERBOSE? RESOURCE GROUPS ALL?\n    ;\n\nshowResourceGroupUsageStatement\n    : SHOW USAGE RESOURCE GROUP identifier\n    | SHOW USAGE RESOURCE GROUPS\n    ;\n\ncreateResourceStatement\n    : CREATE EXTERNAL? RESOURCE resourceName=identifierOrString properties?\n    ;\n\nalterResourceStatement\n    : ALTER RESOURCE resourceName=identifierOrString SET properties\n    ;\n\ndropResourceStatement\n    : DROP RESOURCE resourceName=identifierOrString\n    ;\n\nshowResourceStatement\n    : SHOW RESOURCES\n    ;\n\nclassifier\n    : LEFT_PAREN expressionList RIGHT_PAREN\n    ;\n\n// ------------------------------------------- UDF Statement ----------------------------------------------------\n\nshowFunctionsStatement\n    : SHOW FULL? (BUILTIN|GLOBAL)? FUNCTIONS ((FROM | IN) db=qualifiedName)? ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\ndropFunctionStatement\n    : DROP GLOBAL? FUNCTION (IF EXISTS)?  qualifiedName LEFT_PAREN typeList RIGHT_PAREN\n    ;\n\ncreateFunctionStatement\n    : CREATE orReplace GLOBAL? functionType=(TABLE | AGGREGATE)? FUNCTION ifNotExists qualifiedName LEFT_PAREN typeList RIGHT_PAREN RETURNS returnType=type (properties|inlineProperties)?? inlineFunction?\n    ;\ninlineFunction\n    : AS ATTACHMENT\n    ;\n\ntypeList\n    : type?  ( COMMA type)* (COMMA DOTDOTDOT) ?\n    ;\n\n// ------------------------------------------- Load Statement ----------------------------------------------------------\n\nloadStatement\n    : LOAD LABEL label=labelName\n        data=dataDescList?\n        broker=brokerDesc?\n        (BY system=identifierOrString)?\n        (PROPERTIES props=propertyList)?\n    | LOAD LABEL label=labelName\n        data=dataDescList?\n        resource=resourceDesc\n        (PROPERTIES props=propertyList)?\n    ;\n\nlabelName\n    : (db=identifier DOT)? label=identifier\n    ;\n\ndataDescList\n    : LEFT_PAREN dataDesc (COMMA dataDesc)* RIGHT_PAREN\n    ;\n\ndataDesc\n    : DATA INFILE srcFiles=stringList\n        NEGATIVE?\n        INTO TABLE dstTableName=identifier\n        partitions=partitionNames?\n        (COLUMNS TERMINATED BY colSep=string)?\n        (ROWS TERMINATED BY rowSep=string)?\n        format=fileFormat?\n        (formatPropsField=formatProps)?\n        colList=columnAliases?\n        (COLUMNS FROM PATH AS colFromPath=identifierList)?\n        (SET colMappingList=classifier)?\n        (WHERE where=expression)?\n    | DATA FROM TABLE srcTableName=identifier\n        NEGATIVE?\n        INTO TABLE dstTableName=identifier\n        partitions=partitionNames?\n        (SET colMappingList=classifier)?\n        (WHERE where=expression)?\n    ;\n\nformatProps\n    :  LEFT_PAREN\n            (SKIP_HEADER '=' INTEGER_VALUE)?\n            (TRIM_SPACE '=' booleanValue)?\n            (ENCLOSE '=' encloseCharacter=string)?\n            (ESCAPE '=' escapeCharacter=string)?\n        RIGHT_PAREN\n    ;\n\nbrokerDesc\n    : WITH BROKER props=propertyList?\n    | WITH BROKER name=identifierOrString props=propertyList?\n    ;\n\nresourceDesc\n    : WITH RESOURCE name=identifierOrString props=propertyList?\n    ;\n\nshowLoadStatement\n    : SHOW LOAD (ALL)? (FROM identifier)? (WHERE expression)? (ORDER BY sortItem (COMMA sortItem)*)? limitElement?\n    ;\n\nshowLoadWarningsStatement\n    : SHOW LOAD WARNINGS (FROM identifier)? (WHERE expression)? limitElement?\n    | SHOW LOAD WARNINGS ON string\n    ;\n\ncancelLoadStatement\n    : CANCEL LOAD (FROM identifier)? (WHERE expression)?\n    ;\n\nalterLoadStatement\n    : ALTER LOAD FOR (db=qualifiedName DOT)? name=identifier\n        jobProperties?\n    ;\n\n// ------------------------------------------- Compaction Statement ----------------------------------------------------------\n\ncancelCompactionStatement\n    : CANCEL COMPACTION WHERE expression\n    ;\n\n// ------------------------------------------- Show Statement ----------------------------------------------------------\n\nshowAuthorStatement\n    : SHOW AUTHORS\n    ;\n\nshowBackendsStatement\n    : SHOW BACKENDS\n    ;\n\nshowBrokerStatement\n    : SHOW BROKER\n    ;\n\nshowCharsetStatement\n    : SHOW (CHAR SET | CHARSET | CHARACTER SET) ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nshowCollationStatement\n    : SHOW COLLATION ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nshowDeleteStatement\n    : SHOW DELETE ((FROM | IN) db=qualifiedName)?\n    ;\n\nshowDynamicPartitionStatement\n    : SHOW DYNAMIC PARTITION TABLES ((FROM | IN) db=qualifiedName)?\n    ;\n\nshowEventsStatement\n    : SHOW EVENTS ((FROM | IN) catalog=qualifiedName)? ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nshowEnginesStatement\n    : SHOW ENGINES\n    ;\n\nshowFrontendsStatement\n    : SHOW FRONTENDS\n    ;\n\nshowPluginsStatement\n    : SHOW PLUGINS\n    ;\n\nshowRepositoriesStatement\n    : SHOW REPOSITORIES\n    ;\n\nshowOpenTableStatement\n    : SHOW OPEN TABLES\n    ;\nshowPrivilegesStatement\n    : SHOW PRIVILEGES\n    ;\n\nshowProcedureStatement\n    : SHOW (PROCEDURE | FUNCTION) STATUS ((LIKE pattern=string) | (WHERE where=expression))?\n    ;\n\nshowProcStatement\n    : SHOW PROC path=string\n    ;\n\nshowProcesslistStatement\n    : SHOW FULL? PROCESSLIST (FOR string)?\n    ;\n\nshowProfilelistStatement\n    : SHOW PROFILELIST (LIMIT limit =INTEGER_VALUE)?\n    ;\n\nshowRunningQueriesStatement\n    : SHOW RUNNING QUERIES (LIMIT limit =INTEGER_VALUE)?\n    ;\n\nshowStatusStatement\n    : SHOW varType? STATUS ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nshowTabletStatement\n    : SHOW TABLET INTEGER_VALUE\n    | SHOW (TABLET | TABLETS) FROM qualifiedName partitionNames? (WHERE expression)? (ORDER BY sortItem (COMMA sortItem)*)? (limitElement)?\n    ;\n\nshowTransactionStatement\n    : SHOW TRANSACTION ((FROM | IN) db=qualifiedName)? (WHERE expression)?\n    ;\n\nshowTriggersStatement\n    : SHOW FULL? TRIGGERS ((FROM | IN) catalog=qualifiedName)? ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nshowUserPropertyStatement\n    : SHOW PROPERTY (FOR string)? (LIKE string)?\n    | SHOW PROPERTIES (FOR string)? (LIKE string)?\n    ;\n\nshowVariablesStatement\n    : SHOW varType? VARIABLES ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nshowWarningStatement\n    : SHOW (WARNINGS | ERRORS) (limitElement)?\n    ;\n\nhelpStatement\n    : HELP identifierOrString\n    ;\n\n// ------------------------------------------- Authz Statement -----------------------------------------------------\n\ncreateUserStatement\n    : CREATE USER (IF NOT EXISTS)? user authOption? (DEFAULT ROLE roleList)? properties?\n    ;\n\ndropUserStatement\n    : DROP USER (IF EXISTS)? user\n    ;\n\nalterUserStatement\n    : ALTER USER (IF EXISTS)? user authOption\n    | ALTER USER (IF EXISTS)? user DEFAULT ROLE (NONE| ALL | roleList)\n    | ALTER USER (IF EXISTS)? user SET properties\n    ;\n\nshowUserStatement\n    : SHOW (USER | USERS)\n    ;\n\nshowAuthenticationStatement\n    : SHOW ALL AUTHENTICATION                                                                           #showAllAuthentication\n    | SHOW AUTHENTICATION (FOR user)?                                                                   #showAuthenticationForUser\n    ;\n\nexecuteAsStatement\n    : EXECUTE AS user (WITH NO REVERT)?\n    ;\n\ncreateRoleStatement\n    : CREATE ROLE (IF NOT EXISTS)? roleList comment?\n    ;\n\nalterRoleStatement\n    : ALTER ROLE (IF EXISTS)? roleList SET COMMENT '=' string\n    ;\n\ndropRoleStatement\n    : DROP ROLE (IF EXISTS)? roleList\n    ;\n\nshowRolesStatement\n    : SHOW ROLES\n    ;\n\ngrantRoleStatement\n    : GRANT identifierOrStringList TO USER? user                                                        #grantRoleToUser\n    | GRANT identifierOrStringList TO ROLE identifierOrString                                           #grantRoleToRole\n    ;\n\nrevokeRoleStatement\n    : REVOKE identifierOrStringList FROM USER? user                                                     #revokeRoleFromUser\n    | REVOKE identifierOrStringList FROM ROLE identifierOrString                                        #revokeRoleFromRole\n    ;\n\nsetRoleStatement\n    : SET ROLE DEFAULT\n    | SET ROLE NONE\n    | SET ROLE ALL (EXCEPT roleList)?\n    | SET ROLE roleList\n    ;\n\nsetDefaultRoleStatement\n    : SET DEFAULT ROLE (NONE | ALL | roleList) TO user;\n\ngrantRevokeClause\n    : (USER? user | ROLE identifierOrString)\n    ;\n\ngrantPrivilegeStatement\n    : GRANT IMPERSONATE ON USER user (COMMA user)* TO grantRevokeClause (WITH GRANT OPTION)?              #grantOnUser\n    | GRANT privilegeTypeList ON privObjectNameList TO grantRevokeClause (WITH GRANT OPTION)?           #grantOnTableBrief\n\n    | GRANT privilegeTypeList ON GLOBAL? FUNCTION privFunctionObjectNameList\n        TO grantRevokeClause (WITH GRANT OPTION)?                                                       #grantOnFunc\n    | GRANT privilegeTypeList ON SYSTEM TO grantRevokeClause (WITH GRANT OPTION)?                       #grantOnSystem\n    | GRANT privilegeTypeList ON privObjectType privObjectNameList\n        TO grantRevokeClause (WITH GRANT OPTION)?                                                       #grantOnPrimaryObj\n    | GRANT privilegeTypeList ON ALL privObjectTypePlural\n        (IN isAll=ALL DATABASES| IN DATABASE identifierOrString)? TO grantRevokeClause\n        (WITH GRANT OPTION)?                                                                            #grantOnAll\n    ;\n\nrevokePrivilegeStatement\n    : REVOKE IMPERSONATE ON USER user (COMMA user)* FROM grantRevokeClause                                #revokeOnUser\n    | REVOKE privilegeTypeList ON privObjectNameList FROM grantRevokeClause                             #revokeOnTableBrief\n    | REVOKE privilegeTypeList ON GLOBAL? FUNCTION privFunctionObjectNameList\n        FROM grantRevokeClause                                                                          #revokeOnFunc\n    | REVOKE privilegeTypeList ON SYSTEM FROM grantRevokeClause                                         #revokeOnSystem\n    | REVOKE privilegeTypeList ON privObjectType privObjectNameList\n        FROM grantRevokeClause                                                                          #revokeOnPrimaryObj\n    | REVOKE privilegeTypeList ON ALL privObjectTypePlural\n        (IN isAll=ALL DATABASES| IN DATABASE identifierOrString)? FROM grantRevokeClause                #revokeOnAll\n    ;\n\nshowGrantsStatement\n    : SHOW GRANTS\n    | SHOW GRANTS FOR USER? user\n    | SHOW GRANTS FOR ROLE identifierOrString\n    ;\n\nauthOption\n    : IDENTIFIED BY PASSWORD? string                                                                    #authWithoutPlugin\n    | IDENTIFIED WITH identifierOrString ((BY | AS) string)?                                            #authWithPlugin\n    ;\n\nprivObjectName\n    : identifierOrStringOrStar (DOT identifierOrStringOrStar)?\n    ;\n\nprivObjectNameList\n    : privObjectName (COMMA privObjectName)*\n    ;\n\nprivFunctionObjectNameList\n    : qualifiedName LEFT_PAREN typeList RIGHT_PAREN (COMMA qualifiedName LEFT_PAREN typeList RIGHT_PAREN)*\n    ;\n\nprivilegeTypeList\n    :  privilegeType (COMMA privilegeType)*\n    ;\n\nprivilegeType\n    : ALL PRIVILEGES?\n    | ALTER | APPLY | BLACKLIST\n    | CREATE (\n        DATABASE| TABLE| VIEW| FUNCTION| GLOBAL FUNCTION| MATERIALIZED VIEW|\n        RESOURCE| RESOURCE GROUP| EXTERNAL CATALOG | STORAGE VOLUME | WAREHOUSE | CNGROUP | PIPE )\n    | DELETE | DROP | EXPORT | FILE | IMPERSONATE | INSERT | GRANT | NODE | OPERATE\n    | PLUGIN | REPOSITORY| REFRESH | SELECT | UPDATE | USAGE\n    ;\n\nprivObjectType\n    : CATALOG | DATABASE | MATERIALIZED VIEW | RESOURCE | RESOURCE GROUP | STORAGE VOLUME | SYSTEM | TABLE | VIEW | WAREHOUSE\n    | PIPE\n    ;\n\nprivObjectTypePlural\n    : CATALOGS | DATABASES | FUNCTIONS | GLOBAL FUNCTIONS | MATERIALIZED VIEWS | POLICIES | RESOURCES | RESOURCE GROUPS\n    | STORAGE VOLUMES | TABLES | USERS | VIEWS | WAREHOUSES | PIPES\n    ;\n\n// ------------------------------------------- Security Integration Statement ----------------------------------------------------\n\ncreateSecurityIntegrationStatement\n    : CREATE SECURITY INTEGRATION identifier properties\n    ;\n\nalterSecurityIntegrationStatement\n    : ALTER SECURITY INTEGRATION identifier SET propertyList\n    ;\n\ndropSecurityIntegrationStatement\n    : DROP SECURITY INTEGRATION identifier\n    ;\n\nshowSecurityIntegrationStatement\n    : SHOW SECURITY INTEGRATIONS\n    ;\n\nshowCreateSecurityIntegrationStatement\n    : SHOW CREATE SECURITY INTEGRATION identifier\n    ;\n\n// ------------------------------------------- Group Provider Statement ------------------------------------------\n\ncreateGroupProviderStatement\n    : CREATE GROUP PROVIDER identifier properties\n    ;\n\ndropGroupProviderStatement\n    : DROP GROUP PROVIDER identifier\n    ;\n\nshowGroupProvidersStatement\n    : SHOW GROUP PROVIDERS\n    ;\n\nshowCreateGroupProviderStatement\n    : SHOW CREATE GROUP PROVIDER identifier\n    ;\n\n// ---------------------------------------- Backup Restore Statement ---------------------------------------------------\n\nbackupStatement\n    : BACKUP (ALL EXTERNAL CATALOGS | EXTERNAL (CATALOG | CATALOGS) identifierList)? (DATABASE dbName=identifier)?\n    SNAPSHOT qualifiedName TO repoName=identifier\n    (ON LEFT_PAREN backupRestoreObjectDesc (COMMA backupRestoreObjectDesc) * RIGHT_PAREN)?\n    (PROPERTIES propertyList)?\n    ;\n\ncancelBackupStatement\n    : CANCEL BACKUP ((FROM | IN) identifier | FOR EXTERNAL CATALOG)?\n    ;\n\nshowBackupStatement\n    : SHOW BACKUP ((FROM | IN) identifier)?\n    ;\n\nrestoreStatement\n    : RESTORE SNAPSHOT qualifiedName\n    FROM repoName=identifier\n    (ALL EXTERNAL CATALOGS | EXTERNAL (CATALOG | CATALOGS) identifierWithAliasList)?\n    (DATABASE dbName=identifier (AS dbAlias=identifier)?)?\n    (ON LEFT_PAREN backupRestoreObjectDesc (COMMA backupRestoreObjectDesc) * RIGHT_PAREN)?\n    (PROPERTIES propertyList)?\n    ;\n\ncancelRestoreStatement\n    : CANCEL RESTORE ((FROM | IN) identifier | FOR EXTERNAL CATALOG)?\n    ;\n\nshowRestoreStatement\n    : SHOW RESTORE ((FROM | IN) identifier)? (WHERE where=expression)?\n    ;\n\nshowSnapshotStatement\n    : SHOW SNAPSHOT ON identifier\n    (WHERE expression)?\n    ;\n\ncreateRepositoryStatement\n    : CREATE (READ ONLY)? REPOSITORY repoName=identifier\n    WITH BROKER brokerName=identifierOrString?\n    ON LOCATION location=string\n    (PROPERTIES propertyList)?\n    ;\n\ndropRepositoryStatement\n    : DROP REPOSITORY identifier\n    ;\n\n// ------------------------------------ Sql BlackList And WhiteList Statement ------------------------------------------\n\naddSqlBlackListStatement\n    : ADD SQLBLACKLIST string\n    ;\n\ndelSqlBlackListStatement\n    : DELETE SQLBLACKLIST INTEGER_VALUE (COMMA INTEGER_VALUE)*\n    ;\n\nshowSqlBlackListStatement\n    : SHOW SQLBLACKLIST\n    ;\n\nshowWhiteListStatement\n    : SHOW WHITELIST\n    ;\n\n// ------------------------------------ backend BlackList Statement ---------------------------------------------------\n\naddBackendBlackListStatement\n    : ADD BACKEND BLACKLIST INTEGER_VALUE (COMMA INTEGER_VALUE)*\n    ;\n\ndelBackendBlackListStatement\n    : DELETE BACKEND BLACKLIST INTEGER_VALUE (COMMA INTEGER_VALUE)*\n    ;\n\nshowBackendBlackListStatement\n    : SHOW BACKEND BLACKLIST\n    ;\n\n// -------------------------------------- DataCache Management Statement --------------------------------------------\n\ndataCacheTarget\n    : identifierOrStringOrStar DOT identifierOrStringOrStar DOT identifierOrStringOrStar\n    ;\n\ncreateDataCacheRuleStatement\n    : CREATE DATACACHE RULE dataCacheTarget (WHERE expression)? PRIORITY '=' MINUS_SYMBOL? INTEGER_VALUE properties?\n    ;\n\nshowDataCacheRulesStatement\n    : SHOW DATACACHE RULES\n    ;\n\ndropDataCacheRuleStatement\n    : DROP DATACACHE RULE INTEGER_VALUE\n    ;\n\nclearDataCacheRulesStatement\n    : CLEAR DATACACHE RULES\n    ;\n\ndataCacheSelectStatement\n    : CACHE SELECT selectItem (COMMA selectItem)* FROM qualifiedName (WHERE where=expression)? properties?\n    ;\n\n// ------------------------------------------- Export Statement --------------------------------------------------------\n\nexportStatement\n    : EXPORT TABLE tableDesc columnAliases? TO string (WITH (SYNC | ASYNC) MODE)? properties? brokerDesc?\n    ;\n\ncancelExportStatement\n    : CANCEL EXPORT ((FROM | IN) catalog=qualifiedName)? ((LIKE pattern=string) | (WHERE expression))?\n    ;\n\nshowExportStatement\n    : SHOW EXPORT ((FROM | IN) catalog=qualifiedName)?\n        ((LIKE pattern=string) | (WHERE expression))?\n        (ORDER BY sortItem (COMMA sortItem)*)? (limitElement)?\n    ;\n\n// ------------------------------------------- Plugin Statement --------------------------------------------------------\n\ninstallPluginStatement\n    : INSTALL PLUGIN FROM identifierOrString properties?\n    ;\n\nuninstallPluginStatement\n    : UNINSTALL PLUGIN identifierOrString\n    ;\n\n// ------------------------------------------- File Statement ----------------------------------------------------------\n\ncreateFileStatement\n    : CREATE FILE string ((FROM | IN) catalog=qualifiedName)? properties\n    ;\n\ndropFileStatement\n    : DROP FILE string ((FROM | IN) catalog=qualifiedName)? properties\n    ;\n\nshowSmallFilesStatement\n    : SHOW FILE ((FROM | IN) catalog=qualifiedName)?\n    ;\n\n// -------------------------------------------- Pipe Statement ---------------------------------------------------------\n\ncreatePipeStatement\n    : CREATE orReplace PIPE ifNotExists qualifiedName\n        properties?\n        AS insertStatement\n    ;\n\ndropPipeStatement\n    : DROP PIPE (IF EXISTS)? qualifiedName\n    ;\n\nalterPipeClause\n    : SUSPEND |\n        RESUME |\n        RETRY ALL |\n        RETRY FILE fileName=string |\n        SET propertyList\n    ;\n\nalterPipeStatement\n    : ALTER PIPE qualifiedName alterPipeClause\n    ;\n\ndescPipeStatement\n    : (DESC | DESCRIBE) PIPE qualifiedName\n    ;\n\nshowPipeStatement\n    : SHOW PIPES ((LIKE pattern=string) | (WHERE expression) | (FROM qualifiedName))?\n        (ORDER BY sortItem (COMMA sortItem)*)? limitElement?\n    ;\n\n\n// ------------------------------------------- Set Statement -----------------------------------------------------------\n\nsetStatement\n    : SET setVar (COMMA setVar)*\n    ;\n\nsetVar\n    : (CHAR SET | CHARSET | CHARACTER SET) (identifierOrString | DEFAULT)                       #setNames\n    | NAMES (charset = identifierOrString | DEFAULT)\n        (COLLATE (collate = identifierOrString | DEFAULT))?                                     #setNames\n    | PASSWORD '=' (string | PASSWORD LEFT_PAREN string RIGHT_PAREN)                                           #setPassword\n    | PASSWORD FOR user '=' (string | PASSWORD LEFT_PAREN string RIGHT_PAREN)                                  #setPassword\n    | userVariable '=' expression                                                               #setUserVar\n    | varType? identifier '=' setExprOrDefault                                                  #setSystemVar\n    | systemVariable '=' setExprOrDefault                                                       #setSystemVar\n    | varType? TRANSACTION transaction_characteristics                                          #setTransaction\n    ;\n\ntransaction_characteristics\n    : transaction_access_mode\n    | isolation_level\n    | transaction_access_mode COMMA isolation_level\n    | isolation_level COMMA transaction_access_mode\n    ;\n\ntransaction_access_mode\n    : READ ONLY\n    | READ WRITE\n    ;\n\nisolation_level\n    : ISOLATION LEVEL isolation_types\n    ;\n\nisolation_types\n    : READ UNCOMMITTED\n    | READ COMMITTED\n    | REPEATABLE READ\n    | SERIALIZABLE\n    ;\n\nsetExprOrDefault\n    : DEFAULT\n    | ON\n    | ALL\n    | expression\n    ;\n\nsetUserPropertyStatement\n    : SET PROPERTY (FOR string)? userPropertyList\n    ;\n\nroleList\n    : identifierOrString (COMMA identifierOrString)*\n    ;\n\nexecuteScriptStatement\n    : ADMIN EXECUTE ON (FRONTEND | INTEGER_VALUE) string\n    ;\n\nunsupportedStatement\n    : LOCK TABLES lock_item (COMMA lock_item)*\n    | UNLOCK TABLES\n    ;\n\nlock_item\n    : identifier (AS? alias=identifier)? lock_type\n    ;\n\nlock_type\n    : READ LOCAL?\n    | LOW_PRIORITY? WRITE\n    ;\n\n// ------------------------------------------- Plan Tuning Statement ---------------------------------------------------\nalterPlanAdvisorAddStatement\n    : ALTER PLAN ADVISOR ADD queryStatement;\n\ntruncatePlanAdvisorStatement\n    : TRUNCATE PLAN ADVISOR;\n\nalterPlanAdvisorDropStatement\n    : ALTER PLAN ADVISOR DROP string;\n\nshowPlanAdvisorStatement\n    : SHOW PLAN ADVISOR;\n\n// ---------------------------------------- Warehouse Statement ---------------------------------------------------------\n\ncreateWarehouseStatement\n    : CREATE (WAREHOUSE) (IF NOT EXISTS)? warehouseName=identifierOrString\n    comment? properties?\n    ;\n\ndropWarehouseStatement\n    : DROP WAREHOUSE (IF EXISTS)? warehouseName=identifierOrString\n    ;\n\nsuspendWarehouseStatement\n    : SUSPEND WAREHOUSE (IF EXISTS)? identifier\n    ;\n\nresumeWarehouseStatement\n    : RESUME WAREHOUSE (IF EXISTS)? identifier\n    ;\n\nsetWarehouseStatement\n    : SET SESSION? WAREHOUSE EQ? identifierOrString\n    ;\n\nshowWarehousesStatement\n    : SHOW WAREHOUSES (LIKE pattern=string)?\n    ;\n\nshowClustersStatement\n    : SHOW (CLUSTERS | CNGROUPS) FROM WAREHOUSE identifier\n    ;\n\nshowNodesStatement\n    : SHOW NODES FROM WAREHOUSES (LIKE pattern=string)?\n    | SHOW NODES FROM WAREHOUSE identifier (CNGROUP cngroupName=identifierOrString)?\n    ;\n\nalterWarehouseStatement\n    : ALTER WAREHOUSE warehouseName=identifierOrString modifyPropertiesClause\n    ;\n\ncreateCNGroupStatement\n    : ALTER WAREHOUSE warehouseName=identifierOrString ADD CNGROUP (IF NOT EXISTS)? cngroupName=identifierOrString\n    comment? properties?\n    ;\n\ndropCNGroupStatement\n    : ALTER WAREHOUSE warehouseName=identifierOrString DROP CNGROUP (IF EXISTS)? cngroupName=identifierOrString FORCE?\n    ;\n\nenableCNGroupStatement\n    : ALTER WAREHOUSE warehouseName=identifierOrString ENABLE CNGROUP cngroupName=identifierOrString\n    ;\n\ndisableCNGroupStatement\n    : ALTER WAREHOUSE warehouseName=identifierOrString DISABLE CNGROUP cngroupName=identifierOrString\n    ;\n\nalterCNGroupStatement\n    : ALTER WAREHOUSE warehouseName=identifierOrString MODIFY CNGROUP cngroupName=identifierOrString modifyPropertiesClause\n    ;\n\n// ------------------------------------------- Transaction Statement ---------------------------------------------------\n\nbeginStatement\n    : START TRANSACTION (WITH CONSISTENT SNAPSHOT)?\n    | BEGIN WORK?\n    ;\n\ncommitStatement\n    : COMMIT WORK? (AND NO? CHAIN)? (NO? RELEASE)?\n    ;\n\nrollbackStatement\n    : ROLLBACK WORK? (AND NO? CHAIN)? (NO? RELEASE)?\n    ;\n\n\n// ------------------------------------------- Translate Statement -----------------------------------------------------\ntranslateStatement\n    : TRANSLATE dialect translateSQL\n    ;\n\ndialect\n    : identifier\n    ;\n\ntranslateSQL\n    : .+\n    ;\n\n// ------------------------------------------- Query Statement ---------------------------------------------------------\n\nqueryStatement\n    : (explainDesc | optimizerTrace) ? queryRelation outfile?;\n\nqueryRelation\n    : withClause? queryNoWith\n    ;\n\nwithClause\n    : WITH commonTableExpression (COMMA commonTableExpression)*\n    ;\n\nqueryNoWith\n    : queryPrimary (ORDER BY sortItem (COMMA sortItem)*)? (limitElement)?\n    ;\n\nqueryPeriod\n    : FOR? periodType BETWEEN expression AND expression\n    | FOR? periodType FROM expression TO expression\n    | FOR? periodType ALL\n    | FOR? periodType AS OF end=expression\n    ;\n\nperiodType\n    : SYSTEM_TIME\n    | TIMESTAMP\n    | VERSION\n    ;\n\nqueryPrimary\n    : querySpecification                                                                    #queryPrimaryDefault\n    | subquery                                                                              #queryWithParentheses\n    | left=queryPrimary operator=INTERSECT setQuantifier? right=queryPrimary                #setOperation\n    | left=queryPrimary operator=(UNION | EXCEPT | MINUS)\n        setQuantifier? right=queryPrimary                                                   #setOperation\n    ;\n\nsubquery\n    : LEFT_PAREN queryRelation RIGHT_PAREN\n    ;\n\nrowConstructor\n     :LEFT_PAREN expressionList RIGHT_PAREN\n     ;\n\nsortItem\n    : expression ordering = (ASC | DESC)? (NULLS nullOrdering=(FIRST | LAST))?\n    ;\n\nlimitConstExpr\n    : INTEGER_VALUE\n    | PARAMETER\n    | userVariable\n    ;\n\nlimitElement\n    : LIMIT limit=limitConstExpr (OFFSET offset=limitConstExpr)?\n    | LIMIT offset=limitConstExpr COMMA limit=limitConstExpr\n    ;\n\nquerySpecification\n    : SELECT setQuantifier? selectItem (COMMA selectItem)*\n      fromClause\n      ((WHERE where=expression)? (GROUP BY groupingElement)? (HAVING having=expression)?\n       (QUALIFY qualifyFunction=selectItem comparisonOperator limit=INTEGER_VALUE)?)\n    ;\n\nfromClause\n    : (FROM relations pivotClause?)?                                                    #from\n    | FROM DUAL                                                                         #dual\n    ;\n\ngroupingElement\n    : ROLLUP LEFT_PAREN (expressionList)? RIGHT_PAREN                                                  #rollup\n    | CUBE LEFT_PAREN (expressionList)? RIGHT_PAREN                                                    #cube\n    | GROUPING SETS LEFT_PAREN groupingSet (COMMA groupingSet)* RIGHT_PAREN                              #multipleGroupingSets\n    | expressionList                                                                    #singleGroupingSet\n    ;\n\ngroupingSet\n    : LEFT_PAREN expression? (COMMA expression)* RIGHT_PAREN\n    ;\n\ncommonTableExpression\n    : name=identifier (columnAliases)? AS LEFT_PAREN queryRelation RIGHT_PAREN\n    ;\n\nsetQuantifier\n    : DISTINCT\n    | ALL\n    ;\n\nselectItem\n    : expression (AS? (identifier | string))?                                            #selectSingle\n    | qualifiedName DOT ASTERISK_SYMBOL excludeClause?                                   #selectAll\n    | ASTERISK_SYMBOL excludeClause?                                                     #selectAll\n    ;\n\nexcludeClause\n    : ( EXCEPT | EXCLUDE ) LEFT_PAREN identifier (COMMA identifier)* RIGHT_PAREN\n    ;\n\nrelations\n    : relation (COMMA LATERAL? relation)*\n    ;\n\nrelation\n    : relationPrimary joinRelation*\n    | LEFT_PAREN relationPrimary joinRelation* RIGHT_PAREN\n    ;\n\nrelationPrimary\n    : qualifiedName queryPeriod? partitionNames? tabletList? replicaList? sampleClause? (\n        AS? alias=identifier)? bracketHint? (BEFORE ts=string)?                          #tableAtom\n    | LEFT_PAREN VALUES rowConstructor (COMMA rowConstructor)* RIGHT_PAREN\n        (AS? alias=identifier columnAliases?)?                                          #inlineTable\n    | ASSERT_ROWS? subquery (AS? alias=identifier columnAliases?)?                      #subqueryWithAlias\n    | qualifiedName LEFT_PAREN expressionList RIGHT_PAREN\n        (AS? alias=identifier columnAliases?)?                                          #tableFunction\n    | TABLE LEFT_PAREN qualifiedName LEFT_PAREN argumentList RIGHT_PAREN RIGHT_PAREN\n        (AS? alias=identifier columnAliases?)?                                          #normalizedTableFunction\n    | FILES propertyList\n        (AS? alias=identifier columnAliases?)?                                          #fileTableFunction\n    | LEFT_PAREN relations RIGHT_PAREN                                                                 #parenthesizedRelation\n    ;\n\npivotClause\n    : PIVOT LEFT_PAREN pivotAggregationExpression (COMMA pivotAggregationExpression)*\n        FOR (identifier | identifierList) IN LEFT_PAREN pivotValue (COMMA pivotValue)* RIGHT_PAREN RIGHT_PAREN\n    ;\n\npivotAggregationExpression\n    : functionCall (AS? (identifier | string))?\n    ;\n\n\npivotValue\n    : (literalExpression | literalExpressionList) (AS? (identifier | string))?\n    ;\n\nsampleClause\n    : SAMPLE propertyList?\n    ;\n\nargumentList\n    : expressionList\n    | namedArgumentList\n    ;\n\nnamedArgumentList\n    : namedArgument (COMMA namedArgument)*\n    ;\n\nnamedArgument\n    : identifier FAT_ARROW expression                                                        #namedArguments\n    ;\n\njoinRelation\n    : crossOrInnerJoinType bracketHint?\n            LATERAL? rightRelation=relationPrimary joinCriteria?\n    | outerAndSemiJoinType bracketHint?\n            LATERAL? rightRelation=relationPrimary joinCriteria\n    ;\n\ncrossOrInnerJoinType\n    : JOIN | INNER JOIN\n    | CROSS | CROSS JOIN\n    ;\n\nouterAndSemiJoinType\n    : LEFT JOIN | RIGHT JOIN | FULL JOIN\n    | LEFT OUTER JOIN | RIGHT OUTER JOIN\n    | FULL OUTER JOIN\n    | LEFT SEMI JOIN | RIGHT SEMI JOIN\n    | LEFT ANTI JOIN | RIGHT ANTI JOIN\n    | NULL AWARE LEFT ANTI JOIN\n    ;\n\nbracketHint\n    : LEFT_BRACKET identifier (COMMA identifier)* RIGHT_BRACKET\n    | LEFT_BRACKET identifier '|' primaryExpression literalExpressionList RIGHT_BRACKET\n    ;\n\nhintMap\n    : k=identifierOrString '=' v=literalExpression\n    ;\n\njoinCriteria\n    : ON expression\n    | USING LEFT_PAREN identifier (COMMA identifier)* LEFT_PAREN\n    ;\n\ncolumnAliases\n    : LEFT_PAREN identifier (COMMA identifier)* RIGHT_PAREN\n    ;\n\n// partitionNames should not support string, it should be identifier here only for compatibility with historical bugs\npartitionNames\n    : TEMPORARY? (PARTITION | PARTITIONS) LEFT_PAREN identifierOrString (COMMA identifierOrString)* RIGHT_PAREN\n    | TEMPORARY? (PARTITION | PARTITIONS) identifierOrString\n    | keyPartitions\n    ;\n\nkeyPartitions\n    : PARTITION LEFT_PAREN keyPartition (COMMA keyPartition)* RIGHT_PAREN                              #keyPartitionList\n    ;\n\ntabletList\n    : TABLET LEFT_PAREN INTEGER_VALUE (COMMA INTEGER_VALUE)* RIGHT_PAREN\n    ;\n\nprepareStatement\n    : PREPARE identifier FROM prepareSql\n    ;\n\nprepareSql\n    : statement\n    | SINGLE_QUOTED_TEXT\n    ;\n\nexecuteStatement\n    : EXECUTE identifier (USING  '@'identifierOrString (COMMA '@'identifierOrString)*)?\n    ;\n\ndeallocateStatement\n    : (DEALLOCATE | DROP) PREPARE identifier\n    ;\n\nreplicaList\n    : REPLICA LEFT_PAREN INTEGER_VALUE (COMMA INTEGER_VALUE)* RIGHT_PAREN\n    ;\n\n// ------------------------------------------- Expression --------------------------------------------------------------\n\n/**\n * Operator precedences are shown in the following list, from highest precedence to the lowest.\n *\n * !\n * - (unary minus), ~ (unary bit inversion)\n * ^\n * *, /, DIV, %, MOD\n * -, +\n * &\n * |\n * = (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP\n * BETWEEN, CASE WHEN\n * NOT\n * AND, &&\n * XOR\n * OR, ||\n * = (assignment)\n */\n\nexpressionsWithDefault\n    : LEFT_PAREN expressionOrDefault (COMMA expressionOrDefault)* RIGHT_PAREN\n    ;\n\nexpressionOrDefault\n    : expression | DEFAULT\n    ;\n\nmapExpressionList\n    : mapExpression (COMMA mapExpression)*\n    ;\n\nmapExpression\n    : key=expression COLON value=expression\n    ;\n\nexpressionSingleton\n    : expression EOF\n    ;\n\nexpression\n    : (BINARY)? booleanExpression                                                         #expressionDefault\n    | NOT expression                                                                      #logicalNot\n    | left=expression operator=(AND|LOGICAL_AND) right=expression                         #logicalBinary\n    | left=expression operator=(OR|LOGICAL_OR) right=expression                           #logicalBinary\n    ;\n\nexpressionList\n    : expression (COMMA expression)*\n    ;\n\nbooleanExpression\n    : predicate                                                                           #booleanExpressionDefault\n    | booleanExpression IS NOT? NULL                                                      #isNull\n    | left = booleanExpression comparisonOperator right = predicate                       #comparison\n    | booleanExpression comparisonOperator LEFT_PAREN queryRelation RIGHT_PAREN                          #scalarSubquery\n    ;\n\npredicate\n    : valueExpression (predicateOperations[$valueExpression.ctx])?\n    | tupleInSubquery\n    ;\n\ntupleInSubquery\n    : LEFT_PAREN expression (COMMA expression)+ RIGHT_PAREN NOT? IN LEFT_PAREN queryRelation RIGHT_PAREN\n    ;\n\npredicateOperations [ParserRuleContext value]\n    : NOT? IN LEFT_PAREN queryRelation RIGHT_PAREN                                                       #inSubquery\n    | NOT? IN LEFT_PAREN expressionList RIGHT_PAREN                                                      #inList\n    | NOT? BETWEEN lower = valueExpression AND upper = predicate                          #between\n    | NOT? (LIKE | RLIKE | REGEXP) pattern=valueExpression                                #like\n    ;\n\nvalueExpression\n    : primaryExpression                                                                   #valueExpressionDefault\n    | left = valueExpression operator = BITXOR right = valueExpression                    #arithmeticBinary\n    | left = valueExpression operator = (\n              ASTERISK_SYMBOL\n            | SLASH_SYMBOL\n            | PERCENT_SYMBOL\n            | INT_DIV\n            | MOD)\n      right = valueExpression                                                             #arithmeticBinary\n    | left = valueExpression operator = (PLUS_SYMBOL | MINUS_SYMBOL)\n        right = valueExpression                                                           #arithmeticBinary\n    | left = valueExpression operator = BITAND right = valueExpression                    #arithmeticBinary\n    | left = valueExpression operator = BITOR right = valueExpression                     #arithmeticBinary\n    | left = valueExpression operator = BIT_SHIFT_LEFT right = valueExpression              #arithmeticBinary\n    | left = valueExpression operator = BIT_SHIFT_RIGHT right = valueExpression             #arithmeticBinary\n    | left = valueExpression operator = BIT_SHIFT_RIGHT_LOGICAL right = valueExpression     #arithmeticBinary\n    ;\n\nprimaryExpression\n    : userVariable                                                                        #userVariableExpression\n    | systemVariable                                                                      #systemVariableExpression\n    | DICTIONARY_GET LEFT_PAREN expressionList RIGHT_PAREN                                               #dictionaryGetExpr\n    | functionCall                                                                        #functionCallExpression\n    | LEFT_BRACE FN functionCall RIGHT_BRACE                                                             #odbcFunctionCallExpression\n    | primaryExpression COLLATE (identifier | string)                                     #collate\n    | literalExpression                                                                   #literal\n    | columnReference                                                                     #columnRef\n    | base = primaryExpression (DOT_IDENTIFIER | DOT fieldName = identifier )             #dereference\n    | left = primaryExpression CONCAT right = primaryExpression                           #concat\n    | operator = (MINUS_SYMBOL | PLUS_SYMBOL | BITNOT) primaryExpression                  #arithmeticUnary\n    | operator = LOGICAL_NOT primaryExpression                                            #arithmeticUnary\n    | LEFT_PAREN expression RIGHT_PAREN                                                                  #parenthesizedExpression\n    | EXISTS LEFT_PAREN queryRelation RIGHT_PAREN                                                        #exists\n    | subquery                                                                            #subqueryExpression\n    | CAST LEFT_PAREN expression AS type RIGHT_PAREN                                                     #cast\n    | CONVERT LEFT_PAREN expression COMMA type RIGHT_PAREN                                                 #convert\n    | CASE caseExpr=expression whenClause+ (ELSE elseExpression=expression)? END          #simpleCase\n    | CASE whenClause+ (ELSE elseExpression=expression)? END                              #searchedCase\n    | arrayType? LEFT_BRACKET (expressionList)? RIGHT_BRACKET                                                #arrayConstructor\n    | mapType LEFT_BRACE (mapExpressionList)? RIGHT_BRACE                                                #mapConstructor\n    | MAP LEFT_BRACE (mapExpressionList)? RIGHT_BRACE                                                    #mapConstructor\n    | value=primaryExpression LEFT_BRACKET index=valueExpression RIGHT_BRACKET                               #collectionSubscript\n    | primaryExpression LEFT_BRACKET start=INTEGER_VALUE? COLON end=INTEGER_VALUE? RIGHT_BRACKET               #arraySlice\n    | primaryExpression ARROW string                                                      #arrowExpression\n    | (identifier | identifierList) LEFT_PAREN expression                                       #lambdaFunctionExpr\n    | identifierList ARROW LEFT_PAREN(expressionList)?RIGHT_PAREN                                         #lambdaFunctionExpr\n    | left = primaryExpression NOT? MATCH right = primaryExpression                       #matchExpr\n    ;\n\nliteralExpression\n    : NULL                                                                                #nullLiteral\n    | booleanValue                                                                        #booleanLiteral\n    | number                                                                              #numericLiteral\n    | (DATE | DATETIME) string                                                            #dateLiteral\n    | string                                                                              #stringLiteral\n    | interval                                                                            #intervalLiteral\n    | unitBoundary                                                                        #unitBoundaryLiteral\n    | binary                                                                              #binaryLiteral\n    | PARAMETER                                                                           #Parameter\n    ;\n\nfunctionCall\n    : EXTRACT LEFT_PAREN identifier FROM valueExpression RIGHT_PAREN                                     #extract\n    | GROUPING LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN                                    #groupingOperation\n    | GROUPING_ID LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN                                 #groupingOperation\n    | informationFunctionExpression                                                       #informationFunction\n    | specialDateTimeExpression                                                           #specialDateTime\n    | specialFunctionExpression                                                           #specialFunction\n    | aggregationFunction filter? over?                                                   #aggregationFunctionCall\n    | windowFunction over                                                                 #windowFunctionCall\n    | TRANSLATE LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN                                   #translateFunctionCall\n    | qualifiedName LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN  over?                        #simpleFunctionCall\n    ;\n\naggregationFunction\n    : AVG LEFT_PAREN setQuantifier? expression RIGHT_PAREN\n    | COUNT LEFT_PAREN ASTERISK_SYMBOL? RIGHT_PAREN\n    | COUNT LEFT_PAREN (setQuantifier bracketHint?)? (expression (COMMA expression)*)? RIGHT_PAREN\n    | MAX LEFT_PAREN setQuantifier? expression RIGHT_PAREN\n    | MIN LEFT_PAREN setQuantifier? expression RIGHT_PAREN\n    | SUM LEFT_PAREN setQuantifier? expression RIGHT_PAREN\n    | ARRAY_AGG LEFT_PAREN setQuantifier? expression (ORDER BY sortItem (COMMA sortItem)*)? RIGHT_PAREN\n    | ARRAY_AGG_DISTINCT LEFT_PAREN expression (ORDER BY sortItem (COMMA sortItem)*)? RIGHT_PAREN\n    | GROUP_CONCAT LEFT_PAREN setQuantifier? expression (COMMA expression)* (ORDER BY sortItem (COMMA sortItem)*)? (SEPARATOR expression)? RIGHT_PAREN\n    ;\n\nuserVariable\n    : AT identifierOrString\n    ;\n\nsystemVariable\n    : AT AT (varType DOT)? identifier\n    ;\n\ncolumnReference\n    : identifier\n    ;\n\ninformationFunctionExpression\n    : name = CATALOG LEFT_PAREN RIGHT_PAREN\n    | name = DATABASE LEFT_PAREN RIGHT_PAREN\n    | name = SCHEMA LEFT_PAREN RIGHT_PAREN\n    | name = USER LEFT_PAREN RIGHT_PAREN\n    | name = CURRENT_USER (LEFT_PAREN RIGHT_PAREN)?\n    | name = CURRENT_ROLE (LEFT_PAREN RIGHT_PAREN)?\n    | name = CURRENT_GROUP (LEFT_PAREN RIGHT_PAREN)?\n    ;\n\nspecialDateTimeExpression\n    : name = CURRENT_DATE (LEFT_PAREN RIGHT_PAREN)?\n    | name = CURRENT_TIME (LEFT_PAREN RIGHT_PAREN)?\n    | name = CURRENT_TIMESTAMP (LEFT_PAREN (INTEGER_VALUE)? RIGHT_PAREN)?\n    | name = LOCALTIME (LEFT_PAREN RIGHT_PAREN)?\n    | name = LOCALTIMESTAMP (LEFT_PAREN RIGHT_PAREN)?\n    ;\n\nspecialFunctionExpression\n    : CHAR LEFT_PAREN expression RIGHT_PAREN\n    | DAY LEFT_PAREN expression RIGHT_PAREN\n    | HOUR LEFT_PAREN expression RIGHT_PAREN\n    | IF LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN\n    | LEFT LEFT_PAREN expression COMMA expression RIGHT_PAREN\n    | LIKE LEFT_PAREN expression COMMA expression RIGHT_PAREN\n    | MINUTE LEFT_PAREN expression RIGHT_PAREN\n    | MOD LEFT_PAREN expression COMMA expression RIGHT_PAREN\n    | MONTH LEFT_PAREN expression RIGHT_PAREN\n    | QUARTER LEFT_PAREN expression RIGHT_PAREN\n    | REGEXP LEFT_PAREN expression COMMA expression RIGHT_PAREN\n    | REPLACE LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN\n    | RIGHT LEFT_PAREN expression COMMA expression RIGHT_PAREN\n    | RLIKE LEFT_PAREN expression COMMA expression RIGHT_PAREN\n    | SECOND LEFT_PAREN expression RIGHT_PAREN\n    | TIMESTAMPADD LEFT_PAREN unitIdentifier COMMA expression COMMA expression RIGHT_PAREN\n    | TIMESTAMPDIFF LEFT_PAREN unitIdentifier COMMA expression COMMA expression RIGHT_PAREN\n    //| WEEK LEFT_PAREN expression RIGHT_PAREN TODO: Support week(expr) function\n    | YEAR LEFT_PAREN expression RIGHT_PAREN\n    | PASSWORD LEFT_PAREN string RIGHT_PAREN\n    | FLOOR LEFT_PAREN expression RIGHT_PAREN\n    | CEIL LEFT_PAREN expression RIGHT_PAREN\n    ;\n\nwindowFunction\n    : name = ROW_NUMBER LEFT_PAREN RIGHT_PAREN\n    | name = RANK LEFT_PAREN RIGHT_PAREN\n    | name = DENSE_RANK LEFT_PAREN RIGHT_PAREN\n    | name = CUME_DIST LEFT_PAREN RIGHT_PAREN\n    | name = PERCENT_RANK LEFT_PAREN RIGHT_PAREN\n    | name = NTILE  LEFT_PAREN expression? RIGHT_PAREN\n    | name = LEAD  LEFT_PAREN (expression ignoreNulls? (COMMA expression)*)? RIGHT_PAREN ignoreNulls?\n    | name = LAG LEFT_PAREN (expression ignoreNulls? (COMMA expression)*)? RIGHT_PAREN ignoreNulls?\n    | name = FIRST_VALUE LEFT_PAREN (expression ignoreNulls? (COMMA expression)*)? RIGHT_PAREN ignoreNulls?\n    | name = LAST_VALUE LEFT_PAREN (expression ignoreNulls? (COMMA expression)*)? RIGHT_PAREN ignoreNulls?\n    ;\n\nwhenClause\n    : WHEN condition=expression THEN result=expression\n    ;\n\nfilter\n    : FILTER LEFT_PAREN WHERE booleanExpression RIGHT_PAREN\n    ;\n\nover\n    : OVER LEFT_PAREN\n        (bracketHint? PARTITION BY partition+=expression (COMMA partition+=expression)*)?\n        (ORDER BY sortItem (COMMA sortItem)*)?\n        windowFrame?\n      RIGHT_PAREN\n    ;\n\nignoreNulls\n    : IGNORE NULLS\n    ;\n\nwindowFrame\n    : frameType=RANGE start=frameBound\n    | frameType=ROWS start=frameBound\n    | frameType=RANGE BETWEEN start=frameBound AND end=frameBound\n    | frameType=ROWS BETWEEN start=frameBound AND end=frameBound\n    ;\n\nframeBound\n    : UNBOUNDED boundType=PRECEDING                 #unboundedFrame\n    | UNBOUNDED boundType=FOLLOWING                 #unboundedFrame\n    | CURRENT ROW                                   #currentRowBound\n    | expression boundType=(PRECEDING | FOLLOWING)  #boundedFrame\n    ;\n\n// ------------------------------------------- COMMON AST --------------------------------------------------------------\n\nbackupRestoreObjectDesc\n    : backupRestoreTableDesc\n    | (ALL (FUNCTION | FUNCTIONS) | (FUNCTION | FUNCTIONS) qualifiedName (AS identifier)?)\n    | (ALL (TABLE | TABLES) | (TABLE | TABLES) backupRestoreTableDesc)\n    | (ALL MATERIALIZED (VIEW | VIEWS) | MATERIALIZED (VIEW | VIEWS) qualifiedName (AS identifier)?)\n    | (ALL (VIEW | VIEWS) | (VIEW | VIEWS) qualifiedName (AS identifier)?)\n    ;\n\ntableDesc\n    : qualifiedName partitionNames?\n    ;\n\nbackupRestoreTableDesc\n    : qualifiedName partitionNames? (AS identifier)?\n    ;\n\nexplainDesc\n    : (DESC | DESCRIBE | EXPLAIN) (LOGICAL | ANALYZE | VERBOSE | COSTS | SCHEDULER)?\n    ;\n\noptimizerTrace\n    : TRACE (ALL | LOGS | TIMES | VALUES | REASON) identifier?\n    ;\n\npartitionExpr\n    : identifier\n    | functionCall\n    ;\n\npartitionDesc\n    : PARTITION BY RANGE identifierList LEFT_PAREN (rangePartitionDesc (COMMA rangePartitionDesc)*)? RIGHT_PAREN\n    | PARTITION BY RANGE primaryExpression LEFT_PAREN (rangePartitionDesc (COMMA rangePartitionDesc)*)? RIGHT_PAREN\n    | PARTITION BY LIST? identifierList LEFT_PAREN (listPartitionDesc (COMMA listPartitionDesc)*)? RIGHT_PAREN\n    | PARTITION BY LIST? identifierList\n    | PARTITION BY functionCall LEFT_PAREN (rangePartitionDesc (COMMA rangePartitionDesc)*)? RIGHT_PAREN\n    | PARTITION BY functionCall\n    | PARTITION BY partitionExpr (COMMA partitionExpr)*\n    ;\n\nlistPartitionDesc\n    : singleItemListPartitionDesc\n    | multiItemListPartitionDesc\n    ;\n\nsingleItemListPartitionDesc\n    : PARTITION (IF NOT EXISTS)? identifier VALUES IN singleListPartitionValues propertyList?\n    ;\n\nmultiItemListPartitionDesc\n    : PARTITION (IF NOT EXISTS)? identifier VALUES IN  multiListPartitionValues propertyList?\n    ;\n\nmultiListPartitionValues\n    :LEFT_PAREN singleListPartitionValues (COMMA singleListPartitionValues)* RIGHT_PAREN // list partition values with multi partition columns: ('a, 'b', 'c'), ('d', 'e', 'f')\n    ;\n\nsingleListPartitionValues\n    : LEFT_PAREN listPartitionValue (COMMA listPartitionValue)* RIGHT_PAREN // list partition value: ('a, 'b', 'c')\n    ;\n\nlistPartitionValues // list partition values which can be with single or multi partition columns\n    : singleListPartitionValues\n    | multiListPartitionValues\n    ;\n\nlistPartitionValue\n    : NULL | string\n    ;\n\nstringList\n    : LEFT_PAREN string (COMMA string)* RIGHT_PAREN\n    ;\n\nliteralExpressionList\n    : LEFT_PAREN literalExpression (COMMA literalExpression)* RIGHT_PAREN\n    ;\n\nrangePartitionDesc\n    : singleRangePartition\n    | multiRangePartition\n    ;\n\nsingleRangePartition\n    : PARTITION (IF NOT EXISTS)? identifier VALUES partitionKeyDesc propertyList?\n    ;\n\nmultiRangePartition\n    : START LEFT_PAREN string RIGHT_PAREN END LEFT_PAREN string RIGHT_PAREN EVERY LEFT_PAREN interval RIGHT_PAREN\n    | START LEFT_PAREN string RIGHT_PAREN END LEFT_PAREN string RIGHT_PAREN EVERY LEFT_PAREN INTEGER_VALUE RIGHT_PAREN\n    ;\n\npartitionRangeDesc\n    : START LEFT_PAREN string RIGHT_PAREN END LEFT_PAREN string RIGHT_PAREN\n    ;\n\npartitionKeyDesc\n    : LESS THAN (MAXVALUE | partitionValueList)\n    | LEFT_BRACKET partitionValueList COMMA partitionValueList RIGHT_PAREN\n    ;\n\npartitionValueList\n    : LEFT_PAREN partitionValue (COMMA partitionValue)* RIGHT_PAREN\n    ;\n\nkeyPartition\n    : partitionColName=identifier '=' partitionColValue=literalExpression\n    ;\n\npartitionValue\n    : MAXVALUE | string\n    ;\n\ndistributionClause\n    : DISTRIBUTED BY HASH identifierList (BUCKETS INTEGER_VALUE)?\n    | DISTRIBUTED BY HASH identifierList\n    ;\n\ndistributionDesc\n    : DISTRIBUTED BY HASH identifierList (BUCKETS INTEGER_VALUE)?\n    | DISTRIBUTED BY HASH identifierList\n    | DISTRIBUTED BY RANDOM (BUCKETS INTEGER_VALUE)?\n    ;\n\nrefreshSchemeDesc\n    : REFRESH (IMMEDIATE | DEFERRED)? (ASYNC\n    | ASYNC (START LEFT_PAREN string RIGHT_PAREN)? EVERY LEFT_PAREN interval RIGHT_PAREN\n    | INCREMENTAL\n    | MANUAL)\n    ;\n\nstatusDesc\n    : ACTIVE\n    | INACTIVE\n    ;\n\nproperties\n    : PROPERTIES LEFT_PAREN property (COMMA property)* RIGHT_PAREN\n    ;\n\nextProperties\n    : BROKER properties\n    ;\n\npropertyList\n    : LEFT_PAREN property (COMMA property)* RIGHT_PAREN\n    ;\n\nuserPropertyList\n    : property (COMMA property)*\n    ;\n\nproperty\n    : key=string '=' value=string\n    ;\n\ninlineProperties\n    : inlineProperty ( inlineProperty)*\n    ;\n\ninlineProperty\n    : key=identifier '=' value=string\n    ;\n\nvarType\n    : GLOBAL\n    | LOCAL\n    | SESSION\n    | VERBOSE\n    ;\n\ncomment\n    : COMMENT string\n    ;\n\noutfile\n    : INTO OUTFILE file=string fileFormat? properties?\n    ;\n\nfileFormat\n    : FORMAT AS (identifier | string)\n    ;\n\nstring\n    : SINGLE_QUOTED_TEXT\n    | DOUBLE_QUOTED_TEXT\n    ;\n\nbinary\n    : BINARY_SINGLE_QUOTED_TEXT\n    | BINARY_DOUBLE_QUOTED_TEXT\n    ;\n\ncomparisonOperator\n    : EQ | NEQ | LT | LTE | GT | GTE | EQ_FOR_NULL\n    ;\n\nbooleanValue\n    : TRUE | FALSE\n    ;\n\ninterval\n    : INTERVAL value=expression from=unitIdentifier\n    ;\n\ntaskInterval\n    : INTERVAL value=expression from=taskUnitIdentifier\n    ;\n\ntaskUnitIdentifier\n    : DAY | HOUR | MINUTE | SECOND\n    ;\n\nunitIdentifier\n    : YEAR | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND | QUARTER | MILLISECOND | MICROSECOND\n    ;\n\nunitBoundary\n    : FLOOR | CEIL\n    ;\n\ntype\n    : baseType\n    | decimalType\n    | arrayType\n    | structType\n    | mapType\n    ;\n\narrayType\n    : ARRAY '<' type '>'\n    ;\n\nmapType\n    : MAP '<' type COMMA type '>'\n    ;\n\nsubfieldDesc\n    : (identifier | nestedFieldName) type\n    ;\n\nsubfieldDescs\n    : subfieldDesc (COMMA subfieldDesc)*\n    ;\n\nstructType\n    : STRUCT '<' subfieldDescs '>'\n    ;\n\ntypeParameter\n    : LEFT_PAREN INTEGER_VALUE RIGHT_PAREN\n    ;\n\nbaseType\n    : BOOLEAN\n    | TINYINT typeParameter?\n    | SMALLINT typeParameter?\n    | SIGNED INT?\n    | SIGNED INTEGER?\n    | UNSIGNED INT?\n    | UNSIGNED INTEGER?\n    | INT typeParameter?\n    | INTEGER typeParameter?\n    | BIGINT typeParameter?\n    | LARGEINT typeParameter?\n    | FLOAT\n    | DOUBLE\n    | DATE\n    | DATETIME\n    | TIME\n    | CHAR typeParameter?\n    | VARCHAR typeParameter?\n    | STRING\n    | TEXT\n    | BITMAP\n    | HLL\n    | PERCENTILE\n    | JSON\n    | VARBINARY typeParameter?\n    | BINARY typeParameter?\n    ;\n\ndecimalType\n    : (DECIMAL | DECIMALV2 | DECIMAL32 | DECIMAL64 | DECIMAL128 | NUMERIC | NUMBER )\n        (LEFT_PAREN precision=INTEGER_VALUE (COMMA scale=INTEGER_VALUE)? RIGHT_PAREN)?\n    ;\n\nqualifiedName\n    : identifier (DOT_IDENTIFIER | DOT identifier)*\n    ;\n\ntableName\n    : qualifiedName\n    ;\n\nwriteBranch\n    : FOR? VERSION AS OF identifier\n    ;\n\nidentifier\n    : LETTER_IDENTIFIER      #unquotedIdentifier\n    | nonReserved            #unquotedIdentifier\n    | DIGIT_IDENTIFIER       #digitIdentifier\n    | BACKQUOTED_IDENTIFIER  #backQuotedIdentifier\n    ;\n\nidentifierWithAlias\n    : originalName=identifier (AS alias=identifier)?\n    ;\n\nidentifierWithAliasList\n    : LEFT_PAREN identifierWithAlias (COMMA identifierWithAlias)* RIGHT_PAREN\n    ;\n\nidentifierList\n    : LEFT_PAREN identifier (COMMA identifier)* RIGHT_PAREN\n    ;\n\nidentifierOrString\n    : identifier\n    | string\n    ;\n\nidentifierOrStringList\n    : identifierOrString (COMMA identifierOrString)*\n    ;\n\nidentifierOrStringOrStar\n    : ASTERISK_SYMBOL\n    | identifier\n    | string\n    ;\n\nuser\n    : identifierOrString                                     # userWithoutHost\n    | identifierOrString '@' identifierOrString              # userWithHost\n    | identifierOrString '@' LEFT_BRACKET identifierOrString RIGHT_BRACKET      # userWithHostAndBlanket\n    ;\n\nassignment\n    : identifier EQ expressionOrDefault\n    ;\n\nassignmentList\n    : assignment (COMMA assignment)*\n    ;\n\nnumber\n    : DECIMAL_VALUE  #decimalValue\n    | DOUBLE_VALUE   #doubleValue\n    | INTEGER_VALUE  #integerValue\n    ;\n\nnonReserved\n    : ACCESS | ACTIVE | ADVISOR | AFTER | AGGREGATE | APPLY | ASYNC | AUTHORS | AVG | ADMIN | ANTI | AUTHENTICATION | AUTO_INCREMENT | AUTOMATED\n    | ARRAY_AGG | ARRAY_AGG_DISTINCT | ASSERT_ROWS | AWARE\n    | BACKEND | BACKENDS | BACKUP | BEGIN | BITMAP_UNION | BLACKLIST | BLACKHOLE | BINARY | BODY | BOOLEAN | BRANCH | BROKER | BUCKETS\n    | BUILTIN | BASE | BEFORE | BASELINE\n    | CACHE | CAST | CANCEL | CATALOG | CATALOGS | CEIL | CHAIN | CHARSET | CLEAN | CLEAR | CLUSTER | CLUSTERS | CNGROUP | CNGROUPS | CURRENT | COLLATION | COLUMNS\n    | CUME_DIST | CUMULATIVE | COMMENT | COMMIT | COMMITTED | COMPUTE | CONNECTION | CONSISTENT | COSTS | COUNT\n    | CONFIG | COMPACT\n    | DATA | DATE | DATACACHE | DATETIME | DAY | DAYS | DECOMMISSION | DIALECT | DISABLE | DISK | DISTRIBUTION | DUPLICATE | DYNAMIC | DISTRIBUTED | DICTIONARY | DICTIONARY_GET | DEALLOCATE\n    | ENABLE | END | ENGINE | ENGINES | ERRORS | EVENTS | EXECUTE | EXTERNAL | EXTRACT | EVERY | ENCLOSE | ESCAPE | EXPORT\n    | FAILPOINT | FAILPOINTS | FIELDS | FILE | FILTER | FIRST | FLOOR | FOLLOWING | FORMAT | FN | FRONTEND | FRONTENDS | FOLLOWER | FREE\n    | FUNCTIONS\n    | GLOBAL | GRANTS | GROUP_CONCAT\n    | HASH | HISTOGRAM | HELP | HLL_UNION | HOST | HOUR | HOURS | HUB\n    | IDENTIFIED | IMAGE | IMPERSONATE | INACTIVE | INCREMENTAL | INDEXES | INSTALL | INTEGRATION | INTEGRATIONS | INTERMEDIATE\n    | INTERVAL | ISOLATION\n    | JOB\n    | LABEL | LAST | LESS | LEVEL | LIST | LOCAL | LOCATION | LOGS | LOGICAL | LOW_PRIORITY | LOCK | LOCATIONS\n    | MANUAL | MAP | MAPPING | MAPPINGS | MASKING | MATCH | MAPPINGS | MATERIALIZED | MAX | META | MIN | MINUTE | MINUTES | MODE | MODIFY | MONTH | MERGE | MINUS | MULTIPLE\n    | NAME | NAMES | NEGATIVE | NO | NODE | NODES | NONE | NULLS | NUMBER | NUMERIC\n    | OBSERVER | OF | OFFSET | ONLY | OPTIMIZER | OPEN | OPERATE | OPTION | OVERWRITE | OFF\n    | PARTITIONS | PASSWORD | PATH | PAUSE | PENDING | PERCENTILE_UNION | PIVOT | PLAN | PLUGIN | PLUGINS | POLICY | POLICIES\n    | PERCENT_RANK | PREDICATE | PRECEDING | PRIORITY | PROC | PROCESSLIST | PROFILE | PROFILELIST | PROVIDER | PROVIDERS | PRIVILEGES | PROBABILITY | PROPERTIES | PROPERTY | PIPE | PIPES\n    | QUARTER | QUERY | QUERIES | QUEUE | QUOTA | QUALIFY\n    | REASON | REMOVE | REWRITE | RANDOM | RANK | RECOVER | REFRESH | REPAIR | REPEATABLE | REPLACE_IF_NOT_NULL | REPLICA | REPOSITORY\n    | REPOSITORIES\n    | RESOURCE | RESOURCES | RESTORE | RESUME | RETAIN | RETENTION | RETURNS | RETRY | REVERT | ROLE | ROLES | ROLLUP | ROLLBACK | ROUTINE | ROW | RUNNING | RULE | RULES\n    | SAMPLE | SCHEDULE | SCHEDULER | SECOND | SECURITY | SEPARATOR | SERIALIZABLE |SEMI | SESSION | SETS | SIGNED | SNAPSHOT | SNAPSHOTS | SQLBLACKLIST | START | STARROCKS\n    | STREAM | SUM | STATUS | STOP | SKIP_HEADER | SWAP\n    | STORAGE| STRING | STRUCT | STATS | SUBMIT | SUSPEND | SYNC | SYSTEM_TIME\n    | TABLES | TABLET | TABLETS | TAG | TASK | TEMPORARY | TIMESTAMP | TIMESTAMPADD | TIMESTAMPDIFF | THAN | TIME | TIMES | TRANSACTION | TRACE | TRANSLATE\n    | TRIM_SPACE\n    | TRIGGERS | TRUNCATE | TYPE | TYPES\n    | UNBOUNDED | UNCOMMITTED | UNSET | UNINSTALL | USAGE | USER | USERS | UNLOCK\n    | VALUE | VARBINARY | VARIABLES | VIEW | VIEWS | VERBOSE | VERSION | VOLUME | VOLUMES\n    | WARNINGS | WEEK | WHITELIST | WORK | WRITE  | WAREHOUSE | WAREHOUSES\n    | YEAR\n    | DOTDOTDOT | NGRAMBF | VECTOR\n    | FIELD\n    | ARRAY_ELEMENT\n    | PERSISTENT\n    | EXCLUDE | EXCEPT\n    ;\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/java/io/github/melin/superior/parser/starrocks/NodePosition.java",
    "content": "package io.github.melin.superior.parser.starrocks;\n\nimport java.io.Serializable;\nimport org.antlr.v4.runtime.Token;\nimport org.antlr.v4.runtime.tree.TerminalNode;\n\n// Used to record element position in the sql. ParserRuleContext records the input start and end token,\n// and we can transform their line and col info to NodePosition.\npublic class NodePosition implements Serializable {\n\n    public static final NodePosition ZERO = new NodePosition(0, 0);\n\n    private static final long serialVersionUID = 5619050719810060066L;\n\n    private final int line;\n\n    private final int col;\n\n    private final int endLine;\n\n    private final int endCol;\n\n    public NodePosition(TerminalNode node) {\n        this(node.getSymbol().getLine(), node.getSymbol().getCharPositionInLine());\n    }\n\n    public NodePosition(Token token) {\n        this(token.getLine(), token.getLine());\n    }\n\n    public NodePosition(Token start, Token end) {\n        this(start.getLine(), start.getCharPositionInLine(), end.getLine(), end.getCharPositionInLine());\n    }\n\n    public NodePosition(int line, int col) {\n        this(line, col, line, col);\n    }\n\n    public NodePosition(int line, int col, int endLine, int endCol) {\n        this.line = line;\n        this.col = col;\n        this.endLine = endLine;\n        this.endCol = endCol;\n    }\n\n    public int getLine() {\n        return line;\n    }\n\n    public int getCol() {\n        return col;\n    }\n\n    public int getEndLine() {\n        return endLine;\n    }\n\n    public int getEndCol() {\n        return endCol;\n    }\n\n    public boolean isZero() {\n        return line == 0 && col == 0 && endLine == 0 && endCol == 0;\n    }\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/java/io/github/melin/superior/parser/starrocks/ParsingException.java",
    "content": "package io.github.melin.superior.parser.starrocks;\n\nimport static java.lang.String.format;\n\nimport org.apache.commons.lang3.StringUtils;\n\npublic class ParsingException extends RuntimeException {\n\n    private final String detailMsg;\n\n    private final NodePosition pos;\n\n    public ParsingException(String detailMsg, NodePosition pos) {\n        super(detailMsg);\n        this.detailMsg = detailMsg;\n        this.pos = pos;\n    }\n\n    // error message should contain position info. This method will be removed in the future.\n    public ParsingException(String formatString, Object... args) {\n        this(format(formatString, args), NodePosition.ZERO);\n    }\n\n    @Override\n    public String getMessage() {\n        StringBuilder builder = new StringBuilder(\"Getting syntax error\");\n        if (pos == null || pos.isZero()) {\n            // no position info. do nothing.\n\n        } else if (pos.getLine() == pos.getEndLine() && pos.getCol() == pos.getEndCol()) {\n            builder.append(\" \");\n            builder.append(String.format(\"at line %s, column %s\", pos.getLine(), pos.getCol()));\n        } else {\n            builder.append(\" \");\n            builder.append(String.format(\n                    \"from line %s, column %s to line %s, column %s\",\n                    pos.getLine(), pos.getCol(), pos.getEndLine(), pos.getEndCol()));\n        }\n\n        if (StringUtils.isNotEmpty(detailMsg)) {\n            builder.append(\". Detail message: \");\n            builder.append(detailMsg);\n            builder.append(\".\");\n        }\n        return builder.toString();\n    }\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/java/io/github/melin/superior/parser/starrocks/PostProcessListener.java",
    "content": "package io.github.melin.superior.parser.starrocks;\n\nimport io.github.melin.superior.parser.starrocks.antlr4.StarRocksParser;\nimport io.github.melin.superior.parser.starrocks.antlr4.StarRocksParserBaseListener;\nimport org.antlr.v4.runtime.Token;\nimport org.antlr.v4.runtime.tree.TerminalNode;\n\npublic class PostProcessListener extends StarRocksParserBaseListener {\n\n    private final int maxTokensNum;\n    private final int maxExprChildCount;\n\n    public PostProcessListener(int maxTokensNum, int maxExprChildCount) {\n        this.maxTokensNum = maxTokensNum;\n        this.maxExprChildCount = maxExprChildCount;\n    }\n\n    @Override\n    public void visitTerminal(TerminalNode node) {\n        Token token = node.getSymbol();\n        int index = token.getTokenIndex();\n        if (index >= maxTokensNum) {\n            throw new ParsingException(\n                    \"Statement exceeds maximum length limit, please consider modify ''parse_tokens_limit'' session variable\");\n        }\n    }\n\n    @Override\n    public void exitExpressionList(StarRocksParser.ExpressionListContext ctx) {\n        long childCount = ctx.children.stream()\n                .filter(child -> child instanceof StarRocksParser.ExpressionContext)\n                .count();\n        if (childCount > maxExprChildCount) {\n            NodePosition pos = new NodePosition(ctx.start, ctx.stop);\n            String msg = String.format(\n                    \"The number of exprs are %s exceeded the maximum limit %s, please consider modify \"\n                            + \"''expr_children_limit'' in BE conf\",\n                    childCount, maxExprChildCount);\n            throw new ParsingException(msg, pos);\n        }\n    }\n\n    @Override\n    public void exitExpressionsWithDefault(StarRocksParser.ExpressionsWithDefaultContext ctx) {\n        long childCount = ctx.expressionOrDefault().size();\n        if (childCount > maxExprChildCount) {\n            NodePosition pos = new NodePosition(ctx.start, ctx.stop);\n            String msg = String.format(\n                    \"The number of children in expr are %s exceeded the maximum limit %s, please consider modify \"\n                            + \"''expr_children_limit'' in BE conf\",\n                    childCount, maxExprChildCount);\n            throw new ParsingException(msg, pos);\n        }\n    }\n\n    @Override\n    public void exitInsertStatement(StarRocksParser.InsertStatementContext ctx) {\n        long childCount = ctx.expressionsWithDefault().size();\n        if (childCount > maxExprChildCount) {\n            NodePosition pos = new NodePosition(ctx.start, ctx.stop);\n            String msg = String.format(\n                    \"The inserted rows are {0} exceeded the maximum limit {1}, please consider modify \"\n                            + \"''expr_children_limit'' in BE conf\",\n                    childCount, maxExprChildCount);\n            throw new ParsingException(msg, pos);\n        }\n    }\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/java/io/github/melin/superior/parser/starrocks/SqlModeHelper.java",
    "content": "package io.github.melin.superior.parser.starrocks;\n\npublic class SqlModeHelper {\n    public static final long MODE_DEFAULT = 32L;\n\n    public static final long MODE_PIPES_AS_CONCAT = 1L << 1;\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/kotlin/io/github/melin/superior/parser/starrocks/AbstractSqlParser.kt",
    "content": "package io.github.melin.superior.parser.starrocks\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.starrocks.antlr4.StarRocksParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(StarRocksParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: StarRocksParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(StarRocksParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/kotlin/io/github/melin/superior/parser/starrocks/StarRocksAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.starrocks\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.*\nimport io.github.melin.superior.common.relational.alter.*\nimport io.github.melin.superior.common.relational.common.*\nimport io.github.melin.superior.common.relational.create.*\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.drop.*\nimport io.github.melin.superior.common.relational.io.AlterLoadTable\nimport io.github.melin.superior.common.relational.io.CancelLoadTable\nimport io.github.melin.superior.common.relational.io.ExportTable\nimport io.github.melin.superior.common.relational.io.LoadTable\nimport io.github.melin.superior.common.relational.table.ColumnRel\nimport io.github.melin.superior.parser.starrocks.antlr4.StarRocksParser.*\nimport io.github.melin.superior.parser.starrocks.antlr4.StarRocksParserBaseVisitor\nimport io.github.melin.superior.parser.starrocks.relational.*\nimport org.antlr.v4.runtime.tree.RuleNode\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2020/6/30 9:59 上午 */\nclass StarRocksAntlr4Visitor(val splitSql: Boolean = false) :\n    StarRocksParserBaseVisitor<Statement>() {\n\n    private var currentOptType: StatementType = StatementType.UNKOWN\n    private var limit: Int? = null\n    private var offset: Int? = null\n\n    private var queryStmts: ArrayList<QueryStmt> = arrayListOf()\n    private var inputTables: ArrayList<TableId> = arrayListOf()\n    private var outputTables: ArrayList<TableId> = arrayListOf()\n    private var cteTempTables: ArrayList<TableId> = arrayListOf()\n    private var functionNames: HashSet<FunctionId> = hashSetOf()\n\n    private var statements: ArrayList<Statement> = arrayListOf()\n    private val sqls: ArrayList<String> = arrayListOf()\n    private var mvRefreshType: String = \"Sync\"\n\n    fun getSqlStatements(): List<Statement> {\n        return statements\n    }\n\n    fun getSplitSqls(): List<String> {\n        return sqls\n    }\n\n    override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {\n        return if (currentResult == null) true else false\n    }\n\n    override fun visitSqlStatements(ctx: SqlStatementsContext): Statement? {\n        ctx.singleStatement().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else if (\n                        StringUtils.equalsIgnoreCase(\"DESC\", startNode) ||\n                            StringUtils.equalsIgnoreCase(\"DESCRIBE\", startNode)\n                    ) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        DescStatement(*keyWords.toTypedArray())\n                    } else {\n                        val statement = this.visitSingleStatement(it)\n                        if (statement == null) {\n                            throw SQLParserException(\"not support sql\")\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n\n                clean()\n            }\n        }\n        return null\n    }\n\n    private fun clean() {\n        currentOptType = StatementType.UNKOWN\n\n        limit = null\n        offset = null\n        inputTables = arrayListOf()\n        outputTables = arrayListOf()\n        cteTempTables = arrayListOf()\n        functionNames = hashSetOf()\n    }\n\n    override fun visitCreateExternalCatalogStatement(ctx: CreateExternalCatalogStatementContext): Statement {\n        val catalogName: String = CommonUtils.cleanQuote(ctx.catalogName.text)\n        val properties = parseOptions(ctx.properties())\n        return CreateCatalog(catalogName, properties)\n    }\n\n    override fun visitDropExternalCatalogStatement(ctx: DropExternalCatalogStatementContext): Statement {\n        val catalogName: String = CommonUtils.cleanQuote(ctx.catalogName.text)\n        return DropCatalog(catalogName)\n    }\n\n    override fun visitCreateDbStatement(ctx: CreateDbStatementContext): Statement {\n        val catalogName: String? = if (ctx.catalog != null) CommonUtils.cleanQuote(ctx.catalog.text) else null\n        val databaseName: String = CommonUtils.cleanQuote(ctx.database.text)\n        val properties = parseOptions(ctx.properties())\n        val ifNotExists = ctx.NOT() != null\n\n        return CreateDatabase(catalogName, databaseName, properties, ifNotExists)\n    }\n\n    override fun visitDropDbStatement(ctx: DropDbStatementContext): Statement {\n        val catalogName: String? = if (ctx.catalog != null) CommonUtils.cleanQuote(ctx.catalog.text) else null\n        val databaseName: String = CommonUtils.cleanQuote(ctx.database.text)\n        val ifExists = ctx.EXISTS() != null\n        return DropDatabase(catalogName, databaseName, ifExists)\n    }\n\n    override fun visitAlterDbQuotaStatement(ctx: AlterDbQuotaStatementContext): Statement {\n        val databaseName: String = CommonUtils.cleanQuote(ctx.identifier().get(0).text)\n        val quota = CommonUtils.cleanQuote(ctx.identifier().get(1).text)\n\n        val action = AlterDbPropsAction()\n        action.properties.put(\"quota\", quota)\n        return AlterDatabase(AlterActionType.SET_PROPS, databaseName, action)\n    }\n\n    override fun visitAlterDatabaseRenameStatement(ctx: AlterDatabaseRenameStatementContext): Statement {\n        val databaseName: String = CommonUtils.cleanQuote(ctx.identifier().get(0).text)\n        val newDatabaseName = CommonUtils.cleanQuote(ctx.identifier().get(1).text)\n        val action = RenameDbAction(newDatabaseName)\n        return AlterDatabase(AlterActionType.RENAME, databaseName, action)\n    }\n\n    override fun visitAlterMaterializedViewStatement(ctx: AlterMaterializedViewStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        if (ctx.refreshSchemeDesc() != null) {\n            return AlterMaterializedView(tableId, AlterTableAction(AlterActionType.REFRESH_MV))\n        } else if (ctx.tableRenameClause() != null) {\n            val newName = ctx.tableRenameClause().identifier().text\n            return AlterMaterializedView(tableId, RenameAction(TableId(newName)))\n        } else {\n            val properties = parseOptions(ctx.modifyPropertiesClause().propertyList())\n            val action = AlterPropsAction()\n            action.properties.putAll(properties)\n            return AlterMaterializedView(tableId, action)\n        }\n    }\n\n    override fun visitCreateTableStatement(ctx: CreateTableStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val comment = if (ctx.comment() != null) CommonUtils.cleanQuote(ctx.comment().text) else null\n        val columnRels: List<ColumnRel> =\n            ctx.columnDesc().map { column ->\n                val columnName = column.identifier().text\n                val dataType = column.type().text\n                val colComment =\n                    if (column.comment() != null) CommonUtils.cleanQuote(column.comment().string().text) else null\n                ColumnRel(columnName, dataType, colComment)\n            }\n\n        val keyDesc = ctx.keyDesc()\n        var modelType = \"\"\n        if (keyDesc != null) {\n            if (keyDesc.DUPLICATE() != null) {\n                modelType = \"duplicate\"\n            } else if (keyDesc.AGGREGATE() != null) {\n                modelType = \"aggregate\"\n            } else if (keyDesc.UNIQUE() != null) {\n                modelType = \"unique\"\n            } else if (keyDesc.PRIMARY() != null) {\n                modelType = \"primary\"\n            }\n        }\n\n        var partitionType: PartitionType? = null\n        if (ctx.partitionDesc() != null) {\n            if (ctx.partitionDesc().RANGE() != null) {\n                partitionType = PartitionType.RANGE\n            } else if (ctx.partitionDesc().functionCall() != null) {\n                partitionType = PartitionType.EXPRESSION\n            } else {\n                partitionType = PartitionType.LIST\n            }\n        }\n\n        val table = CreateTable(tableId, TableType.STARROCKS, comment, columnRels)\n        table.modelType = modelType\n        table.partitionType = partitionType\n        return table\n    }\n\n    override fun visitCreateTableAsSelectStatement(ctx: CreateTableAsSelectStatementContext): Statement? {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val comment = if (ctx.comment() != null) CommonUtils.cleanQuote(ctx.comment().text) else null\n        val ifNotExists = ctx.EXISTS() != null\n\n        val queryStmt = this.visitQueryStatement(ctx.queryStatement()) as QueryStmt\n        val createTable = CreateTableAsSelect(tableId, queryStmt, comment)\n        createTable.ifNotExists = ifNotExists\n        val properties = parseOptions(ctx.properties())\n        createTable.properties = properties\n        return createTable\n    }\n\n    override fun visitCreateViewStatement(ctx: CreateViewStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val comment: String? = if (ctx.comment() != null) CommonUtils.cleanQuote(ctx.comment().string().text) else null\n        val columns = parseColumnNameWithComment(ctx.columnNameWithComment())\n        val ifNotExists = ctx.NOT() != null\n        val queryStmt = this.visitQueryStatement(ctx.queryStatement()) as QueryStmt\n        val createView = CreateView(tableId, queryStmt, comment, ifNotExists, columns)\n\n        this.visitQueryStatement(ctx.queryStatement())\n        return createView\n    }\n\n    override fun visitCreateMaterializedViewStatement(ctx: CreateMaterializedViewStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val comment: String? = if (ctx.comment() != null) CommonUtils.cleanQuote(ctx.comment().string().text) else null\n        val columns = parseColumnNameWithComment(ctx.columnNameWithComment())\n        val ifNotExists = ctx.NOT() != null\n\n        val queryStmt = this.visitQueryStatement(ctx.queryStatement()) as QueryStmt\n        val createView = CreateMaterializedView(tableId, queryStmt, comment, ifNotExists, columns)\n\n        ctx.materializedViewDesc().forEach { this.visitMaterializedViewDesc(it) }\n        createView.modelType = mvRefreshType\n\n        this.visitQueryStatement(ctx.queryStatement())\n        return createView\n    }\n\n    override fun visitRefreshSchemeDesc(ctx: RefreshSchemeDescContext): Statement? {\n        if (ctx.ASYNC() != null) {\n            mvRefreshType = \"Async\"\n        } else if (ctx.MANUAL() != null) {\n            mvRefreshType = \"Manual\"\n        } else if (ctx.INCREMENTAL() != null) {\n            mvRefreshType = \"Incremental\"\n        }\n\n        return null\n    }\n\n    override fun visitRefreshMaterializedViewStatement(ctx: RefreshMaterializedViewStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val force: Boolean = ctx.FORCE() != null\n        val mode: String = if (ctx.SYNC() != null) \"Sync\" else \"Async\"\n        var partitionStart: String? = null\n        var partitionEnd: String? = null\n\n        if (ctx.partitionRangeDesc() != null) {\n            val values = ctx.partitionRangeDesc().string()\n            partitionStart = CommonUtils.cleanQuote(values.get(0).text)\n            partitionEnd = CommonUtils.cleanQuote(values.get(1).text)\n        }\n\n        return RefreshMaterializedView(tableId, force, mode, partitionStart, partitionEnd)\n    }\n\n    override fun visitCancelRefreshMaterializedViewStatement(\n        ctx: CancelRefreshMaterializedViewStatementContext\n    ): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        return CancelRefreshMaterializedView(tableId)\n    }\n\n    override fun visitDropTableStatement(ctx: DropTableStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val ifExists = ctx.EXISTS() != null\n        val dropTable = DropTable(tableId, ifExists)\n        dropTable.force = ctx.FORCE() != null\n        return dropTable\n    }\n\n    override fun visitDropViewStatement(ctx: DropViewStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val ifExists = ctx.EXISTS() != null\n        return DropView(tableId, ifExists)\n    }\n\n    override fun visitDropMaterializedViewStatement(ctx: DropMaterializedViewStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val ifExists = ctx.EXISTS() != null\n        return DropMaterializedView(tableId, ifExists)\n    }\n\n    override fun visitCreateIndexStatement(ctx: CreateIndexStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val indexName = ctx.indexName.text\n        val comment = if (ctx.comment() != null) CommonUtils.cleanQuote(ctx.comment().text) else null\n\n        val columns = ctx.identifierList().identifier().map { identifier -> IndexColumnName(identifier.text) }\n\n        val createIndex = CreateIndex(indexName)\n        createIndex.comment = comment\n        createIndex.indexColumnNames.addAll(columns)\n        return AlterTable(tableId, createIndex)\n    }\n\n    override fun visitDropIndexStatement(ctx: DropIndexStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val indexName = ctx.indexName.text\n        val dropIndex = DropIndex(indexName)\n        return AlterTable(tableId, dropIndex)\n    }\n\n    override fun visitAlterTableStatement(ctx: AlterTableStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        return AlterTable(tableId)\n    }\n\n    override fun visitAlterViewStatement(ctx: AlterViewStatementContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val queryStmt = this.visitQueryStatement(ctx.queryStatement()) as QueryStmt\n        val action = AlterViewAction(queryStmt)\n        return AlterTable(tableId, action)\n    }\n\n    override fun visitQueryStatement(ctx: QueryStatementContext): Statement {\n        currentOptType = StatementType.SELECT\n        super.visitQueryRelation(ctx.queryRelation())\n        val queryStmt = QueryStmt(inputTables, limit, offset)\n        queryStmt.functionNames.addAll(functionNames)\n\n        val querySql = source(ctx)\n        queryStmt.setSql(querySql)\n\n        queryStmts.add(queryStmt)\n        return queryStmt\n    }\n\n    override fun visitDeleteStatement(ctx: DeleteStatementContext): Statement {\n        currentOptType = StatementType.DELETE\n        val tableId = parseTableName(ctx.qualifiedName())\n        if (ctx.withClause() != null) {\n            visitWithClause(ctx.withClause())\n        }\n        visit(ctx.where)\n        if (ctx.relations() != null) {\n            visit(ctx.relations())\n        }\n\n        return DeleteTable(tableId, inputTables)\n    }\n\n    override fun visitUpdateStatement(ctx: UpdateStatementContext): Statement {\n        currentOptType = StatementType.UPDATE\n        val tableId = parseTableName(ctx.qualifiedName())\n        if (ctx.withClause() != null) {\n            visitWithClause(ctx.withClause())\n        }\n        visit(ctx.where)\n        visit(ctx.fromClause())\n\n        return UpdateTable(tableId, inputTables)\n    }\n\n    override fun visitInsertStatement(ctx: InsertStatementContext): Statement {\n        val queryStmt =\n            if (ctx.queryStatement() != null) {\n                this.visitQueryStatement(ctx.queryStatement()) as QueryStmt\n            } else {\n                QueryStmt()\n            }\n\n        if (ctx.FILES() == null) {\n            val tableId = parseTableName(ctx.qualifiedName())\n            currentOptType = StatementType.INSERT\n            val insertTable =\n                if (ctx.INTO() != null) InsertTable(InsertMode.INTO, queryStmt, tableId)\n                else InsertTable(InsertMode.OVERWRITE, queryStmt, tableId)\n\n            if (ctx.expressionsWithDefault().size > 0) {\n                val rows: ArrayList<List<String>> = ArrayList()\n                ctx.expressionsWithDefault().forEach {\n                    var text = it.text\n                    text = StringUtils.substringBetween(text, \"(\", \")\").trim()\n                    text = CommonUtils.cleanQuote(text)\n                    rows.add(listOf(text))\n                }\n                insertTable.rows = rows\n            }\n            return insertTable\n        } else {\n            val filesProperties = parseOptions(ctx.propertyList())\n            currentOptType = StatementType.INSERT\n            return if (ctx.INTO() != null) InsertFiles(InsertMode.INTO, queryStmt, filesProperties)\n            else InsertFiles(InsertMode.OVERWRITE, queryStmt, filesProperties)\n        }\n    }\n\n    override fun visitSubmitTaskStatement(ctx: SubmitTaskStatementContext): Statement {\n        val taskName: String? = if (ctx.qualifiedName() != null) ctx.qualifiedName().text else null\n        if (ctx.insertStatement() != null) {\n            val taskExecSql = source(ctx.insertStatement())\n            return SubmitTask(taskName, taskExecSql)\n        } else if (ctx.insertStatement() != null) {\n            val taskExecSql = source(ctx.insertStatement())\n            return SubmitTask(taskName, taskExecSql)\n        } else {\n            val taskExecSql = source(ctx.dataCacheSelectStatement())\n            return SubmitTask(taskName, taskExecSql)\n        }\n    }\n\n    override fun visitDropTaskStatement(ctx: DropTaskStatementContext): Statement {\n        val taskName = ctx.qualifiedName().text\n        return DropTask(taskName)\n    }\n\n    override fun visitCreateRoutineLoadStatement(ctx: CreateRoutineLoadStatementContext): Statement {\n        val catalogName: String? =\n            if (ctx.db != null && ctx.db.identifier().size == 2) CommonUtils.cleanQuote(ctx.db.identifier().get(1).text)\n            else null\n        val schemaName: String? =\n            if (ctx.db != null && ctx.db.identifier().size > 0) CommonUtils.cleanQuote(ctx.db.identifier().get(0).text)\n            else null\n\n        val jobName = ctx.name.text\n        val tableId = parseTableName(ctx.table)\n        val jobProperties = if (ctx.jobProperties() != null) parseOptions(ctx.jobProperties().properties()) else null\n        val loadPropertiesExpr = source(ctx.loadPropertiesExpr())\n        val source = ctx.source.text\n        val sourceProperties =\n            if (ctx.dataSourceProperties() != null) parseOptions(ctx.dataSourceProperties().propertyList()) else null\n\n        return CreateRoutineLoad(\n            catalogName,\n            schemaName,\n            jobName,\n            tableId,\n            loadPropertiesExpr,\n            jobProperties,\n            source,\n            sourceProperties\n        )\n    }\n\n    override fun visitAlterRoutineLoadStatement(ctx: AlterRoutineLoadStatementContext): Statement {\n        val catalogName: String? =\n            if (ctx.db != null && ctx.db.identifier().size == 2) CommonUtils.cleanQuote(ctx.db.identifier().get(1).text)\n            else null\n        val schemaName: String? =\n            if (ctx.db != null && ctx.db.identifier().size > 0) CommonUtils.cleanQuote(ctx.db.identifier().get(0).text)\n            else null\n\n        val jobName = ctx.name.text\n        val jobProperties = if (ctx.jobProperties() != null) parseOptions(ctx.jobProperties().properties()) else null\n        val loadPropertiesExpr = source(ctx.loadPropertiesExpr())\n        var source: String? = null\n        var sourceProperties: Map<String, String>? = null\n        if (ctx.dataSource() != null) {\n            source = ctx.dataSource().source.text\n            sourceProperties = parseOptions(ctx.dataSource().dataSourceProperties().propertyList())\n        }\n\n        return AlterRoutineLoad(\n            catalogName,\n            schemaName,\n            jobName,\n            loadPropertiesExpr,\n            jobProperties,\n            source,\n            sourceProperties\n        )\n    }\n\n    override fun visitPauseRoutineLoadStatement(ctx: PauseRoutineLoadStatementContext): Statement {\n        val catalogName: String? =\n            if (ctx.db != null && ctx.db.identifier().size == 2) CommonUtils.cleanQuote(ctx.db.identifier().get(1).text)\n            else null\n        val schemaName: String? =\n            if (ctx.db != null && ctx.db.identifier().size > 0) CommonUtils.cleanQuote(ctx.db.identifier().get(0).text)\n            else null\n\n        val jobName = ctx.name.text\n        return PauseRoutineLoad(catalogName, schemaName, jobName)\n    }\n\n    override fun visitResumeRoutineLoadStatement(ctx: ResumeRoutineLoadStatementContext): Statement {\n        val catalogName: String? =\n            if (ctx.db != null && ctx.db.identifier().size == 2) CommonUtils.cleanQuote(ctx.db.identifier().get(1).text)\n            else null\n        val schemaName: String? =\n            if (ctx.db != null && ctx.db.identifier().size > 0) CommonUtils.cleanQuote(ctx.db.identifier().get(0).text)\n            else null\n\n        val jobName = ctx.name.text\n        return ResumeRoutineLoad(catalogName, schemaName, jobName)\n    }\n\n    override fun visitStopRoutineLoadStatement(ctx: StopRoutineLoadStatementContext): Statement {\n        val catalogName: String? =\n            if (ctx.db != null && ctx.db.identifier().size == 2) CommonUtils.cleanQuote(ctx.db.identifier().get(1).text)\n            else null\n        val schemaName: String? =\n            if (ctx.db != null && ctx.db.identifier().size > 0) CommonUtils.cleanQuote(ctx.db.identifier().get(0).text)\n            else null\n\n        val jobName = ctx.name.text\n        return StopRoutineLoad(catalogName, schemaName, jobName)\n    }\n\n    override fun visitLoadStatement(ctx: LoadStatementContext): Statement {\n        val schemaName: String? = if (ctx.label.db != null) CommonUtils.cleanQuote(ctx.label.db.text) else null\n\n        val labelName = ctx.label.label.text\n        val tableNames = arrayListOf<String>()\n        ctx.dataDescList().dataDesc().forEach { it ->\n            if (it.dstTableName != null) {\n                tableNames.add(it.dstTableName.text)\n            }\n        }\n\n        return LoadTable(schemaName, labelName, tableNames)\n    }\n\n    override fun visitAlterLoadStatement(ctx: AlterLoadStatementContext): Statement {\n        val schemaName: String? = if (ctx.db != null) CommonUtils.cleanQuote(ctx.db.text) else null\n\n        val labelName = ctx.identifier().text\n\n        return AlterLoadTable(schemaName, labelName)\n    }\n\n    override fun visitCancelLoadStatement(ctx: CancelLoadStatementContext): Statement {\n        val schemaName: String? = if (ctx.FROM() != null) ctx.identifier().text else null\n        val expression: String = ctx.expression().text\n        var labelName: String = StringUtils.substringAfter(expression, \"=\")\n        labelName = CommonUtils.cleanQuote(labelName.trim())\n        return CancelLoadTable(schemaName, labelName)\n    }\n\n    override fun visitExportStatement(ctx: ExportStatementContext): Statement {\n        val tableId = parseTableName(ctx.tableDesc().qualifiedName())\n        val filePath = CommonUtils.cleanQuote(ctx.string().text)\n        val properties = parseOptions(ctx.properties())\n        return ExportTable(tableId, filePath, properties)\n    }\n\n    override fun visitCancelExportStatement(ctx: CancelExportStatementContext): Statement {\n        val database: String? = if (ctx.catalog != null) ctx.catalog.text else null\n        val expr = ctx.expression().text\n        var queryId: String = StringUtils.substringBetween(expr, \"\\\"\", \"\\\"\")\n        if (StringUtils.isBlank(queryId)) {\n            queryId = StringUtils.substringBetween(expr, \"'\", \"'\")\n        }\n\n        return CancelExport(database, queryId)\n    }\n\n    override fun visitCreateFunctionStatement(ctx: CreateFunctionStatementContext): Statement {\n        val functionId = parseTableName(ctx.qualifiedName())\n        val global = ctx.GLOBAL() != null\n        val properties = parseOptions(ctx.properties())\n        val argumentTypes = parseTypeList(ctx.typeList())\n        val createFunction =\n            CreateFunction(\n                FunctionId(functionId.schemaName, functionId.tableName),\n                arrayListOf(),\n            )\n        createFunction.global = global\n        createFunction.properties = properties\n        createFunction.argumentTypes = argumentTypes\n        createFunction.returnType = ctx.returnType.text\n        return createFunction\n    }\n\n    override fun visitDropFunctionStatement(ctx: DropFunctionStatementContext): Statement {\n        val functionId = parseTableName(ctx.qualifiedName())\n        val argumentTypes = parseTypeList(ctx.typeList())\n\n        val dropFunction = DropFunction(FunctionId(functionId.schemaName, functionId.tableName))\n        dropFunction.argumentTypes = argumentTypes\n        return dropFunction\n    }\n\n    override fun visitQualifiedName(ctx: QualifiedNameContext): Statement? {\n        if (\n            currentOptType == StatementType.SELECT ||\n                currentOptType == StatementType.CREATE_TABLE_AS_SELECT ||\n                currentOptType == StatementType.CREATE_VIEW ||\n                currentOptType == StatementType.CREATE_MATERIALIZED_VIEW ||\n                currentOptType == StatementType.UPDATE ||\n                currentOptType == StatementType.DELETE ||\n                currentOptType == StatementType.MERGE ||\n                currentOptType == StatementType.INSERT ||\n                currentOptType == StatementType.CREATE_FUNCTION\n        ) {\n\n            val tableId = parseTableName(ctx)\n            if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {\n                inputTables.add(tableId)\n            }\n        }\n        return null\n    }\n\n    override fun visitSimpleFunctionCall(ctx: SimpleFunctionCallContext): Statement? {\n        if (\n            StatementType.SELECT == currentOptType ||\n                StatementType.CREATE_VIEW == currentOptType ||\n                StatementType.CREATE_MATERIALIZED_VIEW == currentOptType ||\n                StatementType.INSERT == currentOptType ||\n                StatementType.CREATE_TABLE_AS_SELECT == currentOptType\n        ) {\n\n            val names = ctx.qualifiedName().identifier()\n            if (names.size == 3) {\n                val catalog = StringUtils.lowerCase(names.get(0).text)\n                val schema = StringUtils.lowerCase(names.get(1).text)\n                val funcName = StringUtils.lowerCase(names.get(2).text)\n                functionNames.add(FunctionId(catalog, schema, funcName))\n            } else if (names.size == 2) {\n                val schema = StringUtils.lowerCase(names.get(0).text)\n                val funcName = StringUtils.lowerCase(names.get(1).text)\n                functionNames.add(FunctionId(schema, funcName))\n            } else if (names.size == 1) {\n                val funcName = StringUtils.lowerCase(names.get(0).text)\n                functionNames.add(FunctionId(funcName))\n            }\n        }\n\n        return null\n    }\n\n    override fun visitAggregationFunctionCall(ctx: AggregationFunctionCallContext): Statement? {\n        if (\n            StatementType.SELECT == currentOptType ||\n            StatementType.CREATE_VIEW == currentOptType ||\n            StatementType.CREATE_MATERIALIZED_VIEW == currentOptType ||\n            StatementType.INSERT == currentOptType ||\n            StatementType.CREATE_TABLE_AS_SELECT == currentOptType\n        ) {\n            val funcName = ctx.aggregationFunction().getChild(0).text.lowercase()\n            functionNames.add(FunctionId(funcName))\n        }\n\n        return null\n    }\n\n    override fun visitSubqueryWithAlias(ctx: SubqueryWithAliasContext): Statement? {\n        return this.visitSubquery(ctx.subquery())\n    }\n\n    override fun visitSelectAll(ctx: SelectAllContext): Statement? {\n        return null;\n    }\n\n    override fun visitWithClause(ctx: WithClauseContext): Statement? {\n        ctx.commonTableExpression().forEach { cteTempTables.add(TableId(it.name.text)) }\n        return super.visitWithClause(ctx)\n    }\n\n    override fun visitLimitElement(ctx: LimitElementContext): Statement? {\n        if (ctx.limit != null) {\n            limit = ctx.limit.text.toInt()\n        }\n        if (ctx.offset != null) {\n            offset = ctx.offset.text.toInt()\n        }\n\n        return super.visitLimitElement(ctx)\n    }\n\n    fun parseTableName(ctx: QualifiedNameContext): TableId {\n        return if (ctx.identifier().size == 3 || ctx.children.size == 4) {\n            if (ctx.identifier().size == 3) {\n                val catalotName = CommonUtils.cleanQuote(ctx.identifier().get(0).text)\n                val schemaName = CommonUtils.cleanQuote(ctx.identifier().get(1).text)\n                val tableName = CommonUtils.cleanQuote(ctx.identifier().get(2).text)\n                TableId(catalotName, schemaName, tableName)\n            } else {\n                // hive.bigdata.1v1_users 表名数字开头场景\n                val catalotName = CommonUtils.cleanQuote(ctx.identifier().get(0).text)\n                val schemaName = CommonUtils.cleanQuote(ctx.identifier().get(1).text)\n                val tableName = ctx.getChild(3).text.substring(1)\n                TableId(catalotName, schemaName, tableName)\n            }\n        } else if (ctx.identifier().size == 2 || ctx.children.size == 2) {\n            if (ctx.identifier().size == 2) {\n                val schemaName = CommonUtils.cleanQuote(ctx.identifier().get(0).text)\n                val tableName = CommonUtils.cleanQuote(ctx.identifier().get(1).text)\n                TableId(schemaName, tableName)\n            } else {\n                // bigdata.1v1_users 表名数字开头场景\n                val schemaName = CommonUtils.cleanQuote(ctx.identifier().get(0).text)\n                val tableName = ctx.getChild(1).text.substring(1)\n                TableId(schemaName, tableName)\n            }\n        } else if (ctx.identifier().size == 1) {\n            val tableName = CommonUtils.cleanQuote(ctx.identifier().get(0).text)\n            TableId(tableName)\n        } else {\n            throw SQLParserException(\"parse qualifiedName error: \" + ctx.identifier().size)\n        }\n    }\n\n    private fun parseOptions(ctx: PropertiesContext?): Map<String, String> {\n        val properties = HashMap<String, String>()\n        if (ctx != null) {\n            ctx.property().forEach { item ->\n                val property = item as PropertyContext\n                val key = CommonUtils.cleanQuote(property.key.text)\n                val value = CommonUtils.cleanQuote(property.value.text)\n                properties.put(key, value)\n            }\n        }\n\n        return properties\n    }\n\n    private fun parseColumnNameWithComment(columns: List<ColumnNameWithCommentContext>): List<ColumnRel> {\n        return columns.map { col ->\n            val name = col.columnName.text\n            val comment = CommonUtils.cleanQuote(col.comment().string().text)\n            ColumnRel(name, null, comment)\n        }\n    }\n\n    private fun parseOptions(ctx: PropertyListContext?): Map<String, String> {\n        val properties = HashMap<String, String>()\n        if (ctx != null) {\n            ctx.property().forEach { item ->\n                val property = item as PropertyContext\n                val key = CommonUtils.cleanQuote(property.key.text)\n                val value = CommonUtils.cleanQuote(property.value.text)\n                properties.put(key, value)\n            }\n        }\n\n        return properties\n    }\n\n    private fun parseTypeList(ctx: TypeListContext?): List<String> {\n        val types = java.util.ArrayList<String>()\n        if (ctx != null) {\n            ctx.type().forEach { item ->\n                val type = item as TypeContext\n                types.add(type.text)\n            }\n\n            if (ctx.DOTDOTDOT() != null) {\n                types.add(ctx.DOTDOTDOT().text)\n            }\n        }\n\n        return types\n    }\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/kotlin/io/github/melin/superior/parser/starrocks/StarRocksHelper.kt",
    "content": "package io.github.melin.superior.parser.starrocks\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.antlr4.UpperCaseCharStream\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.starrocks.antlr4.StarRocksLexer\nimport io.github.melin.superior.parser.starrocks.antlr4.StarRocksParser\nimport io.github.melin.superior.parser.starrocks.antlr4.StarRocksParserBaseVisitor\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2020/6/30 10:01 上午 */\nobject StarRocksHelper {\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until StarRocksLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = StarRocksLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement {\n        val statements = this.parseMultiStatement(command)\n        if (statements.size != 1) {\n            throw IllegalStateException(\"only parser one sql, sql count: \" + statements.size)\n        } else {\n            return statements.get(0)\n        }\n    }\n\n    @JvmStatic\n    fun parseMultiStatement(command: String): List<Statement> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = StarRocksAntlr4Visitor(false)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSqlStatements()\n    }\n\n    @JvmStatic\n    fun splitSql(command: String): List<String> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = StarRocksAntlr4Visitor(true)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSplitSqls()\n    }\n\n    @JvmStatic\n    fun checkSqlSyntax(command: String) {\n        val sqlVisitor = StarRocksParserBaseVisitor<Statement>()\n        innerParseStatement(command, sqlVisitor)\n    }\n\n    private fun innerParseStatement(command: String, sqlVisitor: StarRocksParserBaseVisitor<Statement>) {\n        val charStream = UpperCaseCharStream(CharStreams.fromString(command))\n        val lexer = StarRocksLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = StarRocksParser(tokenStream)\n        AbstractSqlParser.installCaches(parser)\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n        parser.addParseListener(PostProcessListener(3500000, 10000))\n\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visit(parser.sqlStatements())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                sqlVisitor.visit(parser.sqlStatements())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(command)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/kotlin/io/github/melin/superior/parser/starrocks/relational/AlterRoutineLoad.kt",
    "content": "package io.github.melin.superior.parser.starrocks.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class AlterRoutineLoad(\n    val catalogName: String?,\n    val schemaName: String?,\n    val jobName: String,\n    val loadPropertiesExpr: String,\n    val jobProperties: Map<String, String>?,\n    val source: String?,\n    val sourceProperties: Map<String, String>?\n) : Statement() {\n    override val statementType = StatementType.SR_ALTER_ROUTINE_LOAD\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/kotlin/io/github/melin/superior/parser/starrocks/relational/CancelRefreshMaterializedView.kt",
    "content": "package io.github.melin.superior.parser.starrocks.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\n\ndata class CancelRefreshMaterializedView(val tableId: TableId) : Statement() {\n    override val statementType = StatementType.CANCEL_REFRESH_MV\n    override val privilegeType = PrivilegeType.ADMIN\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/kotlin/io/github/melin/superior/parser/starrocks/relational/CreateRoutineLoad.kt",
    "content": "package io.github.melin.superior.parser.starrocks.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\n\ndata class CreateRoutineLoad(\n    val catalogName: String?,\n    val schemaName: String?,\n    val jobName: String,\n    val tableId: TableId,\n    val loadPropertiesExpr: String,\n    val jobProperties: Map<String, String>?,\n    val source: String,\n    val sourceProperties: Map<String, String>?\n) : Statement() {\n    override val statementType = StatementType.SR_CREATE_ROUTINE_LOAD\n    override val privilegeType = PrivilegeType.CREATE\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/kotlin/io/github/melin/superior/parser/starrocks/relational/DropTask.kt",
    "content": "package io.github.melin.superior.parser.starrocks.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class DropTask(val taskName: String) : Statement() {\n    override val statementType = StatementType.SR_DROP_TASK\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/kotlin/io/github/melin/superior/parser/starrocks/relational/PauseRoutineLoad.kt",
    "content": "package io.github.melin.superior.parser.starrocks.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class PauseRoutineLoad(val catalogName: String?, val schemaName: String?, val jobName: String) : Statement() {\n    override val statementType = StatementType.SR_PAUSE_ROUTINE_LOAD\n    override val privilegeType = PrivilegeType.ADMIN\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/kotlin/io/github/melin/superior/parser/starrocks/relational/ResumeRoutineLoad.kt",
    "content": "package io.github.melin.superior.parser.starrocks.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class ResumeRoutineLoad(val catalogName: String?, val schemaName: String?, val jobName: String) : Statement() {\n    override val statementType = StatementType.SR_RESUME_ROUTINE_LOAD\n    override val privilegeType = PrivilegeType.ADMIN\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/kotlin/io/github/melin/superior/parser/starrocks/relational/StopRoutineLoad.kt",
    "content": "package io.github.melin.superior.parser.starrocks.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class StopRoutineLoad(val catalogName: String?, val schemaName: String?, val jobName: String) : Statement() {\n    override val statementType = StatementType.SR_STOP_ROUTINE_LOAD\n    override val privilegeType = PrivilegeType.ADMIN\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/main/kotlin/io/github/melin/superior/parser/starrocks/relational/SubmitTask.kt",
    "content": "package io.github.melin.superior.parser.starrocks.relational\n\nimport io.github.melin.superior.common.PrivilegeType\nimport io.github.melin.superior.common.SqlType\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.Statement\n\ndata class SubmitTask(val taskName: String?, val taskExecSql: String) : Statement() {\n    override val statementType = StatementType.SR_SUBMIT_TASK\n    override val privilegeType = PrivilegeType.OTHER\n    override val sqlType = SqlType.DML\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/test/kotlin/io/github/melin/superior/parser/starrocks/StarRocksSqlParserDdlTest.kt",
    "content": "package io.github.melin.superior.parser.starrocks\n\nimport io.github.melin.superior.common.StatementType.*\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.PartitionType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.alter.*\nimport io.github.melin.superior.common.relational.common.RefreshMaterializedView\nimport io.github.melin.superior.common.relational.create.*\nimport io.github.melin.superior.common.relational.drop.*\nimport io.github.melin.superior.parser.starrocks.relational.CancelRefreshMaterializedView\nimport org.junit.Assert\nimport org.junit.Test\n\nclass StarRocksSqlParserDdlTest {\n\n    @Test\n    fun createCatalogTest() {\n        val sql =\n            \"\"\"\n            CREATE EXTERNAL CATALOG iceberg_metastore_catalog\n            PROPERTIES(\n                \"type\"=\"iceberg\",\n                \"iceberg.catalog.type\"=\"hive\",\n                \"iceberg.catalog.hive.metastore.uris\"=\"thrift://x.x.x.x:9083\"\n            );\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is CreateCatalog) {\n            Assert.assertEquals(CREATE_CATALOG, statement.statementType)\n            Assert.assertEquals(\"iceberg_metastore_catalog\", statement.catalogName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropCatalogTest() {\n        val sql =\n            \"\"\"\n            DROP CATALOG iceberg_metastore_catalog;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is DropCatalog) {\n            Assert.assertEquals(DROP_CATALOG, statement.statementType)\n            Assert.assertEquals(\"iceberg_metastore_catalog\", statement.catalogName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createDatabaseTest() {\n        val sql =\n            \"\"\"\n            CREATE DATABASE IF Not EXISTS db_test;\n            Drop DATABASE IF EXISTS db_test1;\n        \"\"\"\n                .trimIndent()\n\n        val statements = StarRocksHelper.parseMultiStatement(sql)\n\n        val createDatabse = statements.get(0)\n        val dropDatabase = statements.get(1)\n        if (createDatabse is CreateDatabase) {\n            Assert.assertEquals(\"db_test\", createDatabse.databaseName)\n        }\n        if (dropDatabase is CreateDatabase) {\n            Assert.assertEquals(\"db_test1\", dropDatabase.databaseName)\n        }\n    }\n\n    @Test\n    fun dropDatabaseTest() {\n        val sql =\n            \"\"\"\n            DROP DATABASE IF EXISTS db_test;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is DropDatabase) {\n            Assert.assertEquals(DROP_DATABASE, statement.statementType)\n            Assert.assertEquals(\"db_test\", statement.databaseName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun alterDatabaseTest() {\n        val sql =\n            \"\"\"\n            ALTER DATABASE example_db SET DATA QUOTA 100G;\n        \"\"\"\n                .trimIndent()\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is AlterDatabase) {\n            Assert.assertEquals(ALTER_DATABASE, statement.statementType)\n            Assert.assertEquals(\"example_db\", statement.databaseName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun renameDatabaseTest() {\n        val sql =\n            \"\"\"\n            ALTER DATABASE example_db RENAME example_db2;\n        \"\"\"\n                .trimIndent()\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is AlterDatabase) {\n            Assert.assertEquals(ALTER_DATABASE, statement.statementType)\n            Assert.assertEquals(\"example_db\", statement.databaseName)\n            val action = statement.firstAction() as RenameDbAction\n            Assert.assertEquals(\"example_db2\", action.newDatabaseName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest() {\n        val sql =\n            \"\"\"\n            create table meta_role (\n                id           int          not null,\n                tenant_id    int          null comment '租户ID',\n                code         varchar(255) null comment '角色code, 字母数字和下划线',\n                name         varchar(255) null comment '角色名称，一般为中文',\n                type         varchar(32)  not null comment '角色类型：superadmin、workspaceadmin、dataadmin、custom',\n                order_index  int          null,\n                creater      varchar(45)  null,\n                modifier     varchar(45)  null,\n                gmt_created  datetime     null,\n                gmt_modified datetime     null\n            ) ENGINE = olap PRIMARY KEY(id)\n            DISTRIBUTED BY HASH (id) BUCKETS 10;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is CreateTable) {\n            Assert.assertEquals(CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"meta_role\", statement.tableId.tableName)\n            Assert.assertEquals(\"primary\", statement.modelType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableTest0() {\n        val sql =\n            \"\"\"\n            CREATE TABLE site_access1 (\n                event_day DATETIME NOT NULL,\n                site_id INT DEFAULT '10',\n                city_code VARCHAR(100),\n                user_name VARCHAR(32) DEFAULT '',\n                pv BIGINT DEFAULT '0'\n            )\n            DUPLICATE KEY(event_day, site_id, city_code, user_name)\n            PARTITION BY date_trunc('day', event_day)\n            DISTRIBUTED BY HASH(event_day, site_id);\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is CreateTable) {\n            Assert.assertEquals(CREATE_TABLE, statement.statementType)\n            Assert.assertEquals(\"site_access1\", statement.tableId.tableName)\n            Assert.assertEquals(\"duplicate\", statement.modelType)\n            Assert.assertEquals(PartitionType.EXPRESSION, statement.partitionType)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropTableTest() {\n        val sql =\n            \"\"\"\n           DROP TABLE IF EXISTS example_db.My_table force;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is DropTable) {\n            Assert.assertEquals(DROP_TABLE, statement.statementType)\n            Assert.assertEquals(TableId(\"example_db\", \"My_table\"), statement.tableId)\n            Assert.assertTrue(statement.force)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createViewTest() {\n        val sql =\n            \"\"\"\n            CREATE VIEW example_db.example_view (\n                k1 COMMENT \"first key\",\n                k2 COMMENT \"second key\",\n                k3 COMMENT \"third key\",\n                v1 COMMENT \"first value\"\n            )\n            COMMENT \"my first view\"\n            AS SELECT c1 as k1, k2, k3, SUM(v1) FROM example_table\n            WHERE k1 = 20160112\n            GROUP BY k1,k2,k3;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is CreateView) {\n            Assert.assertEquals(CREATE_VIEW, statement.statementType)\n            Assert.assertEquals(\"my first view\", statement.comment)\n            Assert.assertEquals(4, statement.columnRels?.size)\n            Assert.assertEquals(TableId(\"example_db\", \"example_view\"), statement.tableId)\n            Assert.assertEquals(TableId(\"example_table\"), statement.queryStmt.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropViewTest() {\n        val sql =\n            \"\"\"\n           DROP VIEW IF EXISTS example_db.example_view;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is DropView) {\n            Assert.assertEquals(DROP_VIEW, statement.statementType)\n            Assert.assertEquals(TableId(\"example_db\", \"example_view\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createMaterializedViewTest() {\n        val sql =\n            \"\"\"\n            CREATE MATERIALIZED VIEW example_db.lo_mv1\n            DISTRIBUTED BY HASH(`lo_orderkey`) BUCKETS 10\n            REFRESH ASYNC\n            AS\n            select\n                lo_orderkey, \n                lo_custkey, \n                sum(lo_quantity) as total_quantity, \n                sum(lo_revenue) as total_revenue, \n                count(lo_shipmode) as shipmode_count\n            from lineorder \n            group by lo_orderkey, lo_custkey \n            order by lo_orderkey;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is CreateMaterializedView) {\n            Assert.assertEquals(CREATE_MATERIALIZED_VIEW, statement.statementType)\n            Assert.assertEquals(\"Async\", statement.modelType)\n            Assert.assertEquals(TableId(\"example_db\", \"lo_mv1\"), statement.tableId)\n            Assert.assertEquals(TableId(\"lineorder\"), statement.queryStmt.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropMaterializedViewTest() {\n        val sql =\n            \"\"\"\n           DROP MATERIALIZED VIEW IF EXISTS k1_k2;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is DropMaterializedView) {\n            Assert.assertEquals(DROP_MATERIALIZED_VIEW, statement.statementType)\n            Assert.assertEquals(TableId(\"k1_k2\"), statement.tableId)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun alterMaterializedViewTest() {\n        val sql =\n            \"\"\"\n           ALTER MATERIALIZED VIEW lo_mv1 RENAME lo_mv1_new_name;\n           ALTER MATERIALIZED VIEW lo_mv2 REFRESH ASYNC EVERY(INTERVAL 1 DAY);\n           ALTER MATERIALIZED VIEW mv1 SET (\"session.query_timeout\" = \"40000\");\n        \"\"\"\n                .trimIndent()\n\n        val statements = StarRocksHelper.parseMultiStatement(sql)\n        Assert.assertEquals(3, statements.size)\n    }\n\n    @Test\n    fun refreshMaterializedViewTest() {\n        val sql =\n            \"\"\"\n           REFRESH MATERIALIZED VIEW lo_mv1 PARTITION START (\"2020-02-01\") END (\"2020-03-01\") FORCE;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is RefreshMaterializedView) {\n            Assert.assertEquals(REFRESH_MV, statement.statementType)\n\n            Assert.assertEquals(\"lo_mv1\", statement.tableId.tableName)\n            Assert.assertEquals(\"2020-02-01\", statement.partitionStart)\n            Assert.assertEquals(\"2020-03-01\", statement.partitionEnd)\n            Assert.assertTrue(statement.force)\n            Assert.assertEquals(\"Async\", statement.mode)\n        }\n    }\n\n    @Test\n    fun cancelRefreshMaterializedViewTest() {\n        val sql =\n            \"\"\"\n           CANCEL REFRESH MATERIALIZED VIEW lo_mv1;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is CancelRefreshMaterializedView) {\n            Assert.assertEquals(CANCEL_REFRESH_MV, statement.statementType)\n            Assert.assertEquals(\"lo_mv1\", statement.tableId.tableName)\n        }\n    }\n\n    @Test\n    fun createIndexTest() {\n        val sql =\n            \"\"\"\n            CREATE INDEX index3 ON sales_records (item_id) USING BITMAP COMMENT '';\n\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is AlterTable) {\n            Assert.assertEquals(ALTER_TABLE, statement.statementType)\n            val createIndex = statement.firstAction() as CreateIndex\n            Assert.assertEquals(\"index3\", createIndex.indexName)\n            Assert.assertEquals(\"sales_records\", statement.tableId.tableName)\n            Assert.assertEquals(1, createIndex.indexColumnNames.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropIndexTest() {\n        val sql =\n            \"\"\"\n            DROP INDEX index3 ON sales_records;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is AlterTable) {\n            Assert.assertEquals(ALTER_TABLE, statement.statementType)\n            val dropIndex = statement.firstAction() as DropIndex\n            Assert.assertEquals(\"index3\", dropIndex.indexName)\n            Assert.assertEquals(\"sales_records\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createFuncTest() {\n        val sql =\n            \"\"\"\n            CREATE GLOBAL FUNCTION MY_UDF_JSON_GET(string, string) \n            RETURNS string\n            properties (\n                \"symbol\" = \"com.starrocks.udf.sample.UDFJsonGet\", \n                \"type\" = \"StarrocksJar\",\n                \"file\" = \"http://http_host:http_port/udf-1.0-SNAPSHOT-jar-with-dependencies.jar\"\n            );\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is CreateFunction) {\n            Assert.assertEquals(CREATE_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId(\"MY_UDF_JSON_GET\"), statement.functionId)\n            Assert.assertEquals(\"string\", statement.returnType)\n            Assert.assertEquals(2, statement.argumentTypes?.size)\n            Assert.assertEquals(3, statement.properties?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropFuncTest() {\n        val sql =\n            \"\"\"\n            DROP GLOBAL FUNCTION MY_UDF_JSON_GET(string, string) \n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is DropFunction) {\n            Assert.assertEquals(DROP_FUNCTION, statement.statementType)\n            Assert.assertEquals(FunctionId(\"MY_UDF_JSON_GET\"), statement.functionId)\n            Assert.assertEquals(2, statement.argumentTypes?.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/test/kotlin/io/github/melin/superior/parser/starrocks/StarRocksSqlParserDmlTest.kt",
    "content": "package io.github.melin.superior.parser.starrocks\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.common.ShowStatement\nimport io.github.melin.superior.common.relational.create.CreateTableAsSelect\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.parser.starrocks.relational.DropTask\nimport io.github.melin.superior.parser.starrocks.relational.SubmitTask\nimport org.junit.Assert\nimport org.junit.Test\n\nclass StarRocksSqlParserDmlTest {\n\n    @Test\n    fun selectTest0() {\n        val sql =\n            \"\"\"\n            SELECT * FROM hive1.hive_db.hive_table limit 10 offset 20;\n            select hello('test', 23)\n        \"\"\"\n                .trimIndent()\n\n        val statements = StarRocksHelper.parseMultiStatement(sql)\n        Assert.assertEquals(2, statements.size)\n\n        val statement = statements.get(0)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(10, statement.limit)\n            Assert.assertEquals(20, statement.offset)\n            Assert.assertEquals(TableId(\"hive1\", \"hive_db\", \"hive_table\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n\n        val statement1 = statements.get(1)\n        if (statement1 is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement1.statementType)\n            Assert.assertEquals(0, statement1.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun selectTest1() {\n        val sql =\n            \"\"\"\n            with t1 as (select * from bigdata.users),\n                t2 as (select 2)\n            select * from t1 union all select * from t2;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(TableId(\"bigdata\", \"users\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest0() {\n        val sql =\n            \"\"\"\n            DELETE FROM my_table PARTITION p1 WHERE k1 = 3;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"my_table\", statement.tableId.tableName)\n            Assert.assertEquals(0, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest1() {\n        val sql =\n            \"\"\"\n            DELETE FROM score_board\n            WHERE name IN (select name from users where country = \"China\");\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"score_board\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(\"users\", statement.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest2() {\n        val sql =\n            \"\"\"\n            WITH foo_producers as (\n                SELECT * from producers\n                where producers.name = 'foo'\n            )\n            DELETE FROM films USING foo_producers\n            WHERE producer_id = foo_producers.id;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"films\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(\"producers\", statement.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest1() {\n        val sql =\n            \"\"\"\n            UPDATE employees\n            SET sales_count = sales_count + 1           \n            FROM accounts\n            WHERE accounts.name = 'Acme Corporation'\n               AND employees.id = accounts.sales_person;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(\"accounts\", statement.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun updateTest2() {\n        val sql =\n            \"\"\"\n            WITH acme_accounts as (\n                SELECT * from accounts\n                 WHERE accounts.name = 'Acme Corporation'\n            )\n            UPDATE employees SET sales_count = sales_count + 1\n            FROM acme_accounts\n            WHERE employees.id = acme_accounts.sales_person;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is UpdateTable) {\n            Assert.assertEquals(StatementType.UPDATE, statement.statementType)\n            Assert.assertEquals(\"employees\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(\"accounts\", statement.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest1() {\n        val sql =\n            \"\"\"\n            INSERT INTO test SELECT * FROM test2;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"test\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(\"test2\", statement.queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest2() {\n        val sql =\n            \"\"\"\n            INSERT INTO test PARTITION(p1, p2) WITH LABEL `label1` SELECT * FROM test2;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"test\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(\"test2\", statement.queryStmt.inputTables.get(0).tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest3() {\n        val sql =\n            \"\"\"\n            INSERT INTO test.`table1` VALUES (1, \"test\", 23)\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"table1\", statement.tableId.tableName)\n            Assert.assertEquals(0, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest4() {\n        val sql =\n            \"\"\"\n            INSERT OVERWRITE\n            FILES(\n                \"path\" = \"s3://test/test.parquest\",\n                \"format\" = \"parquet\",\n                \"compression\" = \"uncompressed\",\n                \"target_max_file_size\" = \"10240\", -- 1M\n                \"aws.s3.access_key\" = \"test_access_key\",\n                \"aws.s3.secret_key\" = \"test_secret_key\",\n                \"aws.s3.region\" = \"test-region-1\"\n            )\n            SELECT * FROM test_db.test_table;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is InsertFiles) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(7, statement.properties.size)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest5() {\n        val sql =\n            \"\"\"\n            INSERT INTO target_table (id, cnt)\n            SELECT u.id, COUNT(o.order_id)\n            FROM users u\n            JOIN orders o ON u.id = o.user_id\n            WHERE o.amount > 100\n            GROUP BY u.id\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(2, statement.queryStmt.inputTables.size)\n            Assert.assertEquals(1, statement.queryStmt.functionNames.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun showTest() {\n        val sql =\n            \"\"\"\n            SHOW CREATE MATERIALIZED VIEW lo_mv1;\n            SHOW CREATE TABLE example_db.example_table;\n            SHOW DELETE FROM bigdata;\n        \"\"\"\n                .trimIndent()\n\n        val statements = StarRocksHelper.parseMultiStatement(sql)\n        Assert.assertEquals(3, statements.size)\n\n        val statement = statements.get(2) as ShowStatement\n        Assert.assertTrue(statement.checkSql(\"SHOW DELETE FROM\"))\n\n        Assert.assertFalse(statement.checkSql(\"SHOW DELETE\"))\n    }\n\n    @Test\n    fun taskTest() {\n        val sql =\n            \"\"\"\n            SUBMIT /*+set_var(query_timeout=100000)*/ TASK test1 AS\n            INSERT OVERWRITE insert_wiki_edit\n            SELECT * FROM source_wiki_edit;\n            \n            DROP TASK test1\n        \"\"\"\n                .trimIndent()\n\n        val statements = StarRocksHelper.parseMultiStatement(sql)\n        Assert.assertEquals(2, statements.size)\n\n        val submitTask = statements.get(0) as SubmitTask\n        Assert.assertEquals(\"test1\", submitTask.taskName)\n\n        val dropTask = statements.get(1) as DropTask\n        Assert.assertEquals(\"test1\", dropTask.taskName)\n    }\n\n    @Test\n    fun ctasTest() {\n        val sql =\n            \"\"\"\n            CREATE TABLE order_new (a, b, c) AS SELECT k1, k2, k3 FROM orders;\n        \"\"\"\n                .trimIndent()\n\n        val statements = StarRocksHelper.parseMultiStatement(sql)\n        Assert.assertEquals(1, statements.size)\n\n        val statement = statements.get(0) as CreateTableAsSelect\n\n        Assert.assertEquals(\"order_new\", statement.tableId.tableName)\n        Assert.assertEquals(\"orders\", statement.queryStmt.inputTables.get(0).tableName)\n    }\n\n    // 排除表别名\n    @Test\n    fun selectTest() {\n        val sql =\n            \"\"\"\n            select t1.* from (\n                select * from `default`.person\n            ) t1\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    // 校验数字开头表\n    @Test\n    fun select1Test() {\n        val sql =\n            \"\"\"\n            SELECT * FROM users.1v1_user\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n\n            Assert.assertEquals(TableId(\"users\", \"1v1_user\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    // 校验数字开头表\n    @Test\n    fun select2Test() {\n        val sql =\n            \"\"\"\n            SELECT * FROM hive.users.1v1_user\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n\n            Assert.assertEquals(TableId(\"hive\", \"users\", \"1v1_user\"), statement.inputTables.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/test/kotlin/io/github/melin/superior/parser/starrocks/StarRocksSqlParserLoadAndExportTest.kt",
    "content": "package io.github.melin.superior.parser.starrocks\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.common.*\nimport io.github.melin.superior.common.relational.io.AlterLoadTable\nimport io.github.melin.superior.common.relational.io.CancelLoadTable\nimport io.github.melin.superior.common.relational.io.ExportTable\nimport io.github.melin.superior.common.relational.io.LoadTable\nimport io.github.melin.superior.parser.starrocks.relational.*\nimport org.junit.Assert\nimport org.junit.Test\n\nclass StarRocksSqlParserLoadAndExportTest {\n\n    @Test\n    fun createRoutineLoadTest() {\n        val sql =\n            \"\"\"\n            CREATE ROUTINE LOAD example_db.example_tbl1_ordertest1 ON example_tbl1\n            COLUMNS TERMINATED BY \",\",\n            COLUMNS (order_id, pay_dt, customer_name, nationality, temp_gender, price)\n            PROPERTIES (\n                \"desired_concurrent_number\" = \"5\"\n            )\n            FROM KAFKA (\n                \"kafka_broker_list\" = \"172.18.5.44:9092\",\n                \"kafka_topic\" = \"ordertest1\",\n                \"property.kafka_default_offsets\" = \"OFFSET_BEGINNING\"\n            );\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is CreateRoutineLoad) {\n            Assert.assertEquals(StatementType.SR_CREATE_ROUTINE_LOAD, statement.statementType)\n            Assert.assertNull(statement.catalogName)\n            Assert.assertEquals(\"example_db\", statement.schemaName)\n            Assert.assertEquals(\"example_tbl1_ordertest1\", statement.jobName)\n            Assert.assertEquals(TableId(\"example_tbl1\"), statement.tableId)\n            Assert.assertEquals(\"KAFKA\", statement.source)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun alterRoutineLoadTest() {\n        val sql =\n            \"\"\"\n            ALTER ROUTINE LOAD FOR example_tbl2_ordertest2\n            PROPERTIES (\n                \"desired_concurrent_number\" = \"6\"\n            )\n            FROM kafka (\n                \"kafka_partitions\" = \"0,1,2,3,4,5,6,7\",\n                \"kafka_offsets\" = \"OFFSET_BEGINNING,OFFSET_BEGINNING,OFFSET_BEGINNING,OFFSET_BEGINNING,OFFSET_END,OFFSET_END,OFFSET_END,OFFSET_END\"\n            );\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is AlterRoutineLoad) {\n            Assert.assertEquals(StatementType.SR_ALTER_ROUTINE_LOAD, statement.statementType)\n            Assert.assertNull(statement.catalogName)\n            Assert.assertNull(statement.schemaName)\n            Assert.assertEquals(\"example_tbl2_ordertest2\", statement.jobName)\n            Assert.assertEquals(\"kafka\", statement.source)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun pauseRoutineLoadTest() {\n        val sql =\n            \"\"\"\n            PAUSE ROUTINE LOAD FOR example_tbl2_ordertest2;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is PauseRoutineLoad) {\n            Assert.assertEquals(StatementType.SR_PAUSE_ROUTINE_LOAD, statement.statementType)\n            Assert.assertNull(statement.catalogName)\n            Assert.assertNull(statement.schemaName)\n            Assert.assertEquals(\"example_tbl2_ordertest2\", statement.jobName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun resumeRoutineLoadTest() {\n        val sql =\n            \"\"\"\n            RESUME ROUTINE LOAD FOR example_tbl2_ordertest2;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is ResumeRoutineLoad) {\n            Assert.assertEquals(StatementType.SR_RESUME_ROUTINE_LOAD, statement.statementType)\n            Assert.assertNull(statement.catalogName)\n            Assert.assertNull(statement.schemaName)\n            Assert.assertEquals(\"example_tbl2_ordertest2\", statement.jobName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun stopRoutineLoadTest() {\n        val sql =\n            \"\"\"\n            STOP ROUTINE LOAD FOR example_tbl2_ordertest2;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is StopRoutineLoad) {\n            Assert.assertEquals(StatementType.SR_STOP_ROUTINE_LOAD, statement.statementType)\n            Assert.assertNull(statement.catalogName)\n            Assert.assertNull(statement.schemaName)\n            Assert.assertEquals(\"example_tbl2_ordertest2\", statement.jobName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createLoadTest() {\n        val sql =\n            \"\"\"\n            LOAD LABEL test_db.label_brokerload_multiplefile_multipletable (\n                DATA INFILE(\"hdfs://<hdfs_host>:<hdfs_port>/user/starrocks/file1.csv\")\n                INTO TABLE table1\n                COLUMNS TERMINATED BY \",\"\n                (id, name, score),\n                DATA INFILE(\"hdfs://<hdfs_host>:<hdfs_port>/user/starrocks/file2.csv\")\n                INTO TABLE table2\n                COLUMNS TERMINATED BY \",\"\n                (id, name, score)\n            ) \n            PROPERTIES (\n                \"timeout\" = \"3600\"\n            );\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is LoadTable) {\n            Assert.assertEquals(StatementType.LOAD_TABLE, statement.statementType)\n            Assert.assertEquals(\"test_db\", statement.schemaName)\n            Assert.assertEquals(\"label_brokerload_multiplefile_multipletable\", statement.labelName)\n            Assert.assertEquals(2, statement.tableNames.size)\n            Assert.assertEquals(\"table1\", statement.tableNames.get(0))\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun cancelLoadTest() {\n        val sql =\n            \"\"\"\n            CANCEL LOAD FROM db1 WHERE LABEL = \"label\";\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is CancelLoadTable) {\n            Assert.assertEquals(StatementType.CANCEL_LOAD_TABLE, statement.statementType)\n            Assert.assertEquals(\"db1\", statement.schemaName)\n            Assert.assertEquals(\"label\", statement.labelName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun alterLoadTest() {\n        val sql =\n            \"\"\"\n            ALTER LOAD FOR test_db.label1 properties (\n                'priority'='HIGHEST'\n            );\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is AlterLoadTable) {\n            Assert.assertEquals(StatementType.ALTER_LOAD_TABLE, statement.statementType)\n            Assert.assertEquals(\"test_db\", statement.schemaName)\n            Assert.assertEquals(\"label1\", statement.labelName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createExportTest() {\n        val sql =\n            \"\"\"\n            EXPORT TABLE testTbl \n            TO \"s3a://s3-package/export/\"\n            WITH BROKER\n            (\n                \"aws.s3.access_key\" = \"xxx\",\n                \"aws.s3.secret_key\" = \"yyy\",\n                \"aws.s3.region\" = \"zzz\"\n            );\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is ExportTable) {\n            Assert.assertEquals(StatementType.EXPORT_TABLE, statement.statementType)\n            Assert.assertEquals(\"testTbl\", statement.tableId.tableName)\n            Assert.assertEquals(\"s3a://s3-package/export/\", statement.path)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun cancelExportTest() {\n        val sql =\n            \"\"\"\n            CANCEL Export\n            FROM example_db\n            WHERE queryid = \"921d8f80-7c9d-11eb-9342-acde48001121\";\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is CancelExport) {\n            Assert.assertEquals(StatementType.CANCEL_EXPORT, statement.statementType)\n            Assert.assertEquals(\"example_db\", statement.database)\n            Assert.assertEquals(\"921d8f80-7c9d-11eb-9342-acde48001121\", statement.queryId)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/test/kotlin/io/github/melin/superior/parser/starrocks/StarRocksSqlParserRoutineLoadTest.kt",
    "content": "package io.github.melin.superior.parser.starrocks\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.parser.starrocks.relational.*\nimport org.junit.Assert\nimport org.junit.Test\n\nclass StarRocksSqlParserRoutineLoadTest {\n\n    @Test\n    fun createRoutineLoadTest() {\n        val sql =\n            \"\"\"\n            CREATE ROUTINE LOAD example_db.example_tbl1_ordertest1 ON example_tbl1\n            COLUMNS TERMINATED BY \",\",\n            COLUMNS (order_id, pay_dt, customer_name, nationality, temp_gender, price)\n            PROPERTIES (\n                \"desired_concurrent_number\" = \"5\"\n            )\n            FROM KAFKA (\n                \"kafka_broker_list\" = \"172.18.5.44:9092\",\n                \"kafka_topic\" = \"ordertest1\",\n                \"property.kafka_default_offsets\" = \"OFFSET_BEGINNING\"\n            );\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is CreateRoutineLoad) {\n            Assert.assertEquals(StatementType.SR_CREATE_ROUTINE_LOAD, statement.statementType)\n            Assert.assertNull(statement.catalogName)\n            Assert.assertEquals(\"example_db\", statement.schemaName)\n            Assert.assertEquals(\"example_tbl1_ordertest1\", statement.jobName)\n            Assert.assertEquals(TableId(\"example_tbl1\"), statement.tableId)\n            Assert.assertEquals(\"KAFKA\", statement.source)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun alterRoutineLoadTest() {\n        val sql =\n            \"\"\"\n            ALTER ROUTINE LOAD FOR example_tbl2_ordertest2\n            PROPERTIES (\n                \"desired_concurrent_number\" = \"6\"\n            )\n            FROM kafka (\n                \"kafka_partitions\" = \"0,1,2,3,4,5,6,7\",\n                \"kafka_offsets\" = \"OFFSET_BEGINNING,OFFSET_BEGINNING,OFFSET_BEGINNING,OFFSET_BEGINNING,OFFSET_END,OFFSET_END,OFFSET_END,OFFSET_END\"\n            );\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is AlterRoutineLoad) {\n            Assert.assertEquals(StatementType.SR_ALTER_ROUTINE_LOAD, statement.statementType)\n            Assert.assertNull(statement.catalogName)\n            Assert.assertNull(statement.schemaName)\n            Assert.assertEquals(\"example_tbl2_ordertest2\", statement.jobName)\n            Assert.assertEquals(\"kafka\", statement.source)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun pauseRoutineLoadTest() {\n        val sql =\n            \"\"\"\n            PAUSE ROUTINE LOAD FOR example_tbl2_ordertest2;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is PauseRoutineLoad) {\n            Assert.assertEquals(StatementType.SR_PAUSE_ROUTINE_LOAD, statement.statementType)\n            Assert.assertNull(statement.catalogName)\n            Assert.assertNull(statement.schemaName)\n            Assert.assertEquals(\"example_tbl2_ordertest2\", statement.jobName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun resumeRoutineLoadTest() {\n        val sql =\n            \"\"\"\n            RESUME ROUTINE LOAD FOR example_tbl2_ordertest2;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is ResumeRoutineLoad) {\n            Assert.assertEquals(StatementType.SR_RESUME_ROUTINE_LOAD, statement.statementType)\n            Assert.assertNull(statement.catalogName)\n            Assert.assertNull(statement.schemaName)\n            Assert.assertEquals(\"example_tbl2_ordertest2\", statement.jobName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun stopRoutineLoadTest() {\n        val sql =\n            \"\"\"\n            STOP ROUTINE LOAD FOR example_tbl2_ordertest2;\n        \"\"\"\n                .trimIndent()\n\n        val statement = StarRocksHelper.parseStatement(sql)\n\n        if (statement is StopRoutineLoad) {\n            Assert.assertEquals(StatementType.SR_STOP_ROUTINE_LOAD, statement.statementType)\n            Assert.assertNull(statement.catalogName)\n            Assert.assertNull(statement.schemaName)\n            Assert.assertEquals(\"example_tbl2_ordertest2\", statement.jobName)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-starrocks-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  },
  {
    "path": "superior-trino-parser/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <parent>\n        <groupId>io.github.melin.superior</groupId>\n        <artifactId>superior-sql-parser</artifactId>\n        <version>4.0.23</version>\n    </parent>\n\n    <artifactId>superior-trino-parser</artifactId>\n    <name>superior-trino-parser</name>\n\n    <dependencies>\n        <dependency>\n            <groupId>io.github.melin.superior</groupId>\n            <artifactId>superior-common-parser</artifactId>\n            <version>${project.version}</version>\n        </dependency>\n    </dependencies>\n</project>\n"
  },
  {
    "path": "superior-trino-parser/src/main/antlr4/io/github/melin/superior/parser/trino/antlr4/TrinoSqlBase.g4",
    "content": "/*\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\ngrammar TrinoSqlBase;\n\ntokens {\n    DELIMITER\n}\n\nsqlStatements\n    : singleStatement* EOF\n    ;\n\nsingleStatement\n    : statement ';'?\n    ;\n\nstandaloneExpression\n    : expression EOF\n    ;\n\nstandalonePathSpecification\n    : pathSpecification EOF\n    ;\n\nstandaloneType\n    : type EOF\n    ;\n\nstandaloneRowPattern\n    : rowPattern EOF\n    ;\n\nstandaloneFunctionSpecification\n    : functionSpecification EOF\n    ;\n\nstatement\n    : rootQuery                                                        #statementDefault\n    | USE schema=identifier                                            #use\n    | USE catalog=identifier '.' schema=identifier                     #use\n    | CREATE CATALOG (IF NOT EXISTS)? catalog=identifier\n         USING connectorName=identifier\n         (COMMENT string)?\n         (AUTHORIZATION principal)?\n         (WITH properties)?                                            #createCatalog\n    | DROP CATALOG (IF EXISTS)? catalog=identifier\n         (CASCADE | RESTRICT)?                                         #dropCatalog\n    | CREATE SCHEMA (IF NOT EXISTS)? qualifiedName\n        (AUTHORIZATION principal)?\n        (WITH properties)?                                             #createSchema\n    | DROP SCHEMA (IF EXISTS)? qualifiedName (CASCADE | RESTRICT)?     #dropSchema\n    | ALTER SCHEMA qualifiedName RENAME TO identifier                  #renameSchema\n    | ALTER SCHEMA qualifiedName SET AUTHORIZATION principal           #setSchemaAuthorization\n    | CREATE (OR REPLACE)? TABLE (IF NOT EXISTS)? qualifiedName\n        columnAliases?\n        (COMMENT string)?\n        (WITH properties)? AS (rootQuery | '('rootQuery')')\n        (WITH (NO)? DATA)?                                             #createTableAsSelect\n    | CREATE (OR REPLACE)? TABLE (IF NOT EXISTS)? qualifiedName\n        '(' tableElement (',' tableElement)* ')'\n         (COMMENT string)?\n         (WITH properties)?                                            #createTable\n    | DROP TABLE (IF EXISTS)? qualifiedName                            #dropTable\n    | INSERT INTO qualifiedName columnAliases? rootQuery               #insertInto\n    | DELETE FROM qualifiedName (whereClause)?                         #delete\n    | TRUNCATE TABLE qualifiedName                                     #truncateTable\n    | COMMENT ON TABLE qualifiedName IS (string | NULL)                #commentTable\n    | COMMENT ON VIEW qualifiedName IS (string | NULL)                 #commentView\n    | COMMENT ON COLUMN qualifiedName IS (string | NULL)               #commentColumn\n    | ALTER TABLE (IF EXISTS)? from=qualifiedName\n        RENAME TO to=qualifiedName                                     #renameTable\n    | ALTER TABLE (IF EXISTS)? tableName=qualifiedName\n        ADD COLUMN (IF NOT EXISTS)? column=columnDefinition            #addColumn\n    | ALTER TABLE (IF EXISTS)? tableName=qualifiedName\n        RENAME COLUMN (IF EXISTS)? from=qualifiedName TO to=identifier #renameColumn\n    | ALTER TABLE (IF EXISTS)? tableName=qualifiedName\n        DROP COLUMN (IF EXISTS)? column=qualifiedName                  #dropColumn\n    | ALTER TABLE (IF EXISTS)? tableName=qualifiedName\n        ALTER COLUMN columnName=qualifiedName SET DATA TYPE type       #setColumnType\n    | ALTER TABLE (IF EXISTS)? tableName=qualifiedName\n        ALTER COLUMN columnName=identifier DROP NOT NULL               #dropNotNullConstraint\n    | ALTER TABLE tableName=qualifiedName SET AUTHORIZATION principal  #setTableAuthorization\n    | ALTER TABLE tableName=qualifiedName\n        SET PROPERTIES propertyAssignments                             #setTableProperties\n    | ALTER TABLE tableName=qualifiedName\n        EXECUTE procedureName=identifier\n        ('(' (callArgument (',' callArgument)*)? ')')?\n        (WHERE where=booleanExpression)?                               #tableExecute\n    | ANALYZE qualifiedName (WITH properties)?                         #analyze\n    | CREATE (OR REPLACE)? MATERIALIZED VIEW\n        (IF NOT EXISTS)? qualifiedName\n        (GRACE PERIOD interval)?\n        (COMMENT string)?\n        (WITH properties)? AS rootQuery                                #createMaterializedView\n    | CREATE (OR REPLACE)? VIEW qualifiedName\n        (COMMENT string)?\n        (SECURITY (DEFINER | INVOKER))? AS rootQuery                   #createView\n    | REFRESH MATERIALIZED VIEW qualifiedName                          #refreshMaterializedView\n    | DROP MATERIALIZED VIEW (IF EXISTS)? qualifiedName                #dropMaterializedView\n    | ALTER MATERIALIZED VIEW (IF EXISTS)? from=qualifiedName\n        RENAME TO to=qualifiedName                                     #renameMaterializedView\n    | ALTER MATERIALIZED VIEW qualifiedName\n        SET PROPERTIES propertyAssignments                             #setMaterializedViewProperties\n    | DROP VIEW (IF EXISTS)? qualifiedName                             #dropView\n    | ALTER VIEW from=qualifiedName RENAME TO to=qualifiedName         #renameView\n    | ALTER VIEW from=qualifiedName SET AUTHORIZATION principal        #setViewAuthorization\n    | CALL qualifiedName '(' (callArgument (',' callArgument)*)? ')'   #call\n    | CREATE (OR REPLACE)? functionSpecification                       #createFunction\n    | DROP FUNCTION (IF EXISTS)? functionDeclaration                   #dropFunction\n    | CREATE ROLE name=identifier\n        (WITH ADMIN grantor)?\n        (IN catalog=identifier)?                                       #createRole\n    | DROP ROLE name=identifier (IN catalog=identifier)?               #dropRole\n    | GRANT\n        privilegeOrRole (',' privilegeOrRole)*\n        TO principal (',' principal)*\n        (WITH ADMIN OPTION)?\n        (GRANTED BY grantor)?\n        (IN catalog=identifier)?                                       #grantRoles\n    | GRANT\n        ((privilegeOrRole (',' privilegeOrRole)*) | ALL PRIVILEGES)\n        ON grantObject\n        TO principal\n        (WITH GRANT OPTION)?                                           #grantPrivileges\n    | REVOKE\n        (ADMIN OPTION FOR)?\n        privilegeOrRole (',' privilegeOrRole)*\n        FROM principal (',' principal)*\n        (GRANTED BY grantor)?\n        (IN catalog=identifier)?                                       #revokeRoles\n    | REVOKE\n        (GRANT OPTION FOR)?\n        ((privilegeOrRole (',' privilegeOrRole)*) | ALL PRIVILEGES)\n        ON grantObject\n        FROM grantee=principal                                         #revokePrivileges\n    | DENY\n        (privilege (',' privilege)* | ALL PRIVILEGES)\n        ON grantObject\n        TO grantee=principal                                           #deny\n    | SET ROLE (ALL | NONE | role=identifier)\n        (IN catalog=identifier)?                                       #setRole\n    | SHOW GRANTS (ON grantObject)?                                    #showGrants\n    | EXPLAIN ('(' explainOption (',' explainOption)* ')')? statement  #explain\n    | EXPLAIN ANALYZE VERBOSE? statement                               #explainAnalyze\n    | SHOW CREATE TABLE qualifiedName                                  #showCreateTable\n    | SHOW CREATE SCHEMA qualifiedName                                 #showCreateSchema\n    | SHOW CREATE VIEW qualifiedName                                   #showCreateView\n    | SHOW CREATE MATERIALIZED VIEW qualifiedName                      #showCreateMaterializedView\n    | SHOW TABLES ((FROM | IN) qualifiedName)?\n        (LIKE pattern=string (ESCAPE escape=string)?)?                 #showTables\n    | SHOW SCHEMAS ((FROM | IN) identifier)?\n        (LIKE pattern=string (ESCAPE escape=string)?)?                 #showSchemas\n    | SHOW CATALOGS\n        (LIKE pattern=string (ESCAPE escape=string)?)?                 #showCatalogs\n    | SHOW COLUMNS (FROM | IN) qualifiedName\n        (LIKE pattern=string (ESCAPE escape=string)?)?                 #showColumns\n    | SHOW STATS FOR qualifiedName                                     #showStats\n    | SHOW STATS FOR '(' rootQuery ')'                                 #showStatsForQuery\n    | SHOW CURRENT? ROLES ((FROM | IN) identifier)?                    #showRoles\n    | SHOW ROLE GRANTS ((FROM | IN) identifier)?                       #showRoleGrants\n    | DESCRIBE qualifiedName                                           #showColumns\n    | DESC qualifiedName                                               #showColumns\n    | SHOW FUNCTIONS ((FROM | IN) qualifiedName)?\n        (LIKE pattern=string (ESCAPE escape=string)?)?                 #showFunctions\n    | SHOW SESSION\n        (LIKE pattern=string (ESCAPE escape=string)?)?                 #showSession\n    | SET SESSION AUTHORIZATION authorizationUser                      #setSessionAuthorization\n    | RESET SESSION AUTHORIZATION                                      #resetSessionAuthorization\n    | SET SESSION qualifiedName EQ expression                          #setSession\n    | RESET SESSION qualifiedName                                      #resetSession\n    | START TRANSACTION (transactionMode (',' transactionMode)*)?      #startTransaction\n    | COMMIT WORK?                                                     #commit\n    | ROLLBACK WORK?                                                   #rollback\n    | PREPARE identifier FROM statement                                #prepare\n    | DEALLOCATE PREPARE identifier                                    #deallocate\n    | EXECUTE identifier (USING expression (',' expression)*)?         #execute\n    | EXECUTE IMMEDIATE string (USING expression (',' expression)*)?   #executeImmediate\n    | DESCRIBE INPUT identifier                                        #describeInput\n    | DESCRIBE OUTPUT identifier                                       #describeOutput\n    | SET PATH pathSpecification                                       #setPath\n    | SET TIME ZONE (LOCAL | expression)                               #setTimeZone\n    | UPDATE qualifiedName\n        SET updateAssignment (',' updateAssignment)*\n        (whereClause)?                                                 #update\n    | MERGE INTO qualifiedName (AS? identifier)?\n        USING relation ON expression mergeCase+                        #merge\n    ;\n\nrootQuery\n    : withFunction? query\n    ;\n\nwithFunction\n    : WITH functionSpecification (',' functionSpecification)*\n    ;\n\nquery\n    : with? queryNoWith\n    ;\n\nwith\n    : WITH RECURSIVE? namedQuery (',' namedQuery)*\n    ;\n\ntableElement\n    : columnDefinition\n    | likeClause\n    ;\n\ncolumnDefinition\n    : qualifiedName type (NOT NULL)? (COMMENT string)? (WITH properties)?\n    ;\n\nlikeClause\n    : LIKE qualifiedName (optionType=(INCLUDING | EXCLUDING) PROPERTIES)?\n    ;\n\nproperties\n    : '(' propertyAssignments ')'\n    ;\n\npropertyAssignments\n    : property (',' property)*\n    ;\n\nproperty\n    : identifier EQ propertyValue\n    ;\n\npropertyValue\n    : DEFAULT       #defaultPropertyValue\n    | expression    #nonDefaultPropertyValue\n    ;\n\nqueryNoWith\n    : queryTerm\n      (ORDER BY sortItem (',' sortItem)*)?\n      (OFFSET offset=rowCount (ROW | ROWS)?)?\n      ( (LIMIT limit=limitRowCount)\n      | (FETCH (FIRST | NEXT) (fetchFirst=rowCount)? (ROW | ROWS) (ONLY | WITH TIES))\n      )?\n    ;\n\nlimitRowCount\n    : ALL\n    | rowCount\n    ;\n\nrowCount\n    : INTEGER_VALUE\n    | QUESTION_MARK\n    ;\n\nqueryTerm\n    : queryPrimary                                                             #queryTermDefault\n    | left=queryTerm operator=INTERSECT setQuantifier? right=queryTerm         #setOperation\n    | left=queryTerm operator=(UNION | EXCEPT) setQuantifier? right=queryTerm  #setOperation\n    ;\n\nqueryPrimary\n    : querySpecification                   #queryPrimaryDefault\n    | TABLE qualifiedName                  #table\n    | VALUES expression (',' expression)*  #inlineTable\n    | '(' queryNoWith ')'                  #subquery\n    ;\n\nsortItem\n    : expression ordering=(ASC | DESC)? (NULLS nullOrdering=(FIRST | LAST))?\n    ;\n\nquerySpecification\n    : SELECT setQuantifier? selectItem (',' selectItem)*\n      (FROM relation (',' relation)*)?\n      (WHERE where=booleanExpression)?\n      (GROUP BY groupBy)?\n      (HAVING having=booleanExpression)?\n      (WINDOW windowDefinition (',' windowDefinition)*)?\n    ;\n\ngroupBy\n    : setQuantifier? groupingElement (',' groupingElement)*\n    ;\n\ngroupingElement\n    : groupingSet                                            #singleGroupingSet\n    | ROLLUP '(' (groupingSet (',' groupingSet)*)? ')'       #rollup\n    | CUBE '(' (groupingSet (',' groupingSet)*)? ')'         #cube\n    | GROUPING SETS '(' groupingSet (',' groupingSet)* ')'   #multipleGroupingSets\n    ;\n\ngroupingSet\n    : '(' (expression (',' expression)*)? ')'\n    | expression\n    ;\n\nwindowDefinition\n    : name=identifier AS '(' windowSpecification ')'\n    ;\n\nwindowSpecification\n    : (existingWindowName=identifier)?\n      (PARTITION BY partition+=expression (',' partition+=expression)*)?\n      (ORDER BY sortItem (',' sortItem)*)?\n      windowFrame?\n    ;\n\nnamedQuery\n    : name=identifier (columnAliases)? AS '(' query ')'\n    ;\n\nsetQuantifier\n    : DISTINCT\n    | ALL\n    ;\n\nselectItem\n    : expression (AS? identifier)?                          #selectSingle\n    | primaryExpression '.' ASTERISK (AS columnAliases)?    #selectAll\n    | ASTERISK                                              #selectAll\n    ;\n\nrelation\n    : left=relation\n      ( CROSS JOIN right=sampledRelation\n      | joinType JOIN rightRelation=relation joinCriteria\n      | NATURAL joinType JOIN right=sampledRelation\n      )                                                     #joinRelation\n    | sampledRelation                                       #relationDefault\n    ;\n\njoinType\n    : INNER?\n    | LEFT OUTER?\n    | RIGHT OUTER?\n    | FULL OUTER?\n    ;\n\njoinCriteria\n    : ON booleanExpression\n    | USING '(' identifier (',' identifier)* ')'\n    ;\n\nsampledRelation\n    : patternRecognition (\n        TABLESAMPLE sampleType '(' percentage=expression ')'\n      )?\n    ;\n\nsampleType\n    : BERNOULLI\n    | SYSTEM\n    ;\n\ntrimsSpecification\n    : LEADING\n    | TRAILING\n    | BOTH\n    ;\n\nlistAggOverflowBehavior\n    : ERROR\n    | TRUNCATE string? listaggCountIndication\n    ;\n\nlistaggCountIndication\n    : WITH COUNT\n    | WITHOUT COUNT\n    ;\n\npatternRecognition\n    : aliasedRelation (\n        MATCH_RECOGNIZE '('\n          (PARTITION BY partition+=expression (',' partition+=expression)*)?\n          (ORDER BY sortItem (',' sortItem)*)?\n          (MEASURES measureDefinition (',' measureDefinition)*)?\n          rowsPerMatch?\n          (AFTER MATCH skipTo)?\n          (INITIAL | SEEK)?\n          PATTERN '(' rowPattern ')'\n          (SUBSET subsetDefinition (',' subsetDefinition)*)?\n          DEFINE variableDefinition (',' variableDefinition)*\n        ')'\n        (AS? identifier columnAliases?)?\n      )?\n    ;\n\nmeasureDefinition\n    : expression AS identifier\n    ;\n\nrowsPerMatch\n    : ONE ROW PER MATCH\n    | ALL ROWS PER MATCH emptyMatchHandling?\n    ;\n\nemptyMatchHandling\n    : SHOW EMPTY MATCHES\n    | OMIT EMPTY MATCHES\n    | WITH UNMATCHED ROWS\n    ;\n\nskipTo\n    : 'SKIP' TO NEXT ROW\n    | 'SKIP' PAST LAST ROW\n    | 'SKIP' TO FIRST identifier\n    | 'SKIP' TO LAST identifier\n    | 'SKIP' TO identifier\n    ;\n\nsubsetDefinition\n    : name=identifier EQ '(' union+=identifier (',' union+=identifier)* ')'\n    ;\n\nvariableDefinition\n    : identifier AS expression\n    ;\n\naliasedRelation\n    : relationPrimary (AS? identifier columnAliases?)?\n    ;\n\ncolumnAliases\n    : '(' identifier (',' identifier)* ')'\n    ;\n\nrelationPrimary\n    : qualifiedName queryPeriod?                                      #tableName\n    | '(' query ')'                                                   #subqueryRelation\n    | UNNEST '(' expression (',' expression)* ')' (WITH ORDINALITY)?  #unnest\n    | LATERAL '(' query ')'                                           #lateral\n    | TABLE '(' tableFunctionCall ')'                                 #tableFunctionInvocation\n    | '(' relation ')'                                                #parenthesizedRelation\n    | JSON_TABLE '('\n        jsonPathInvocation\n        COLUMNS '(' jsonTableColumn (',' jsonTableColumn)* ')'\n        (PLAN '(' jsonTableSpecificPlan ')'\n        | PLAN DEFAULT '(' jsonTableDefaultPlan ')'\n        )?\n        ((ERROR | EMPTY) ON ERROR)?\n      ')'                                                             #jsonTable\n    ;\n\njsonTableColumn\n    : identifier FOR ORDINALITY                                     #ordinalityColumn\n    | identifier type\n        (PATH string)?\n        (emptyBehavior=jsonValueBehavior ON EMPTY)?\n        (errorBehavior=jsonValueBehavior ON ERROR)?                 #valueColumn\n    | identifier type FORMAT jsonRepresentation\n        (PATH string)?\n        (jsonQueryWrapperBehavior WRAPPER)?\n        ((KEEP | OMIT) QUOTES (ON SCALAR TEXT_STRING)?)?\n        (emptyBehavior=jsonQueryBehavior ON EMPTY)?\n        (errorBehavior=jsonQueryBehavior ON ERROR)?                 #queryColumn\n    | NESTED PATH? string (AS identifier)?\n        COLUMNS '(' jsonTableColumn (',' jsonTableColumn)* ')'      #nestedColumns\n    ;\n\njsonTableSpecificPlan\n    : jsonTablePathName                                         #leafPlan\n    | jsonTablePathName (OUTER | INNER) planPrimary             #joinPlan\n    | planPrimary UNION planPrimary (UNION planPrimary)*        #unionPlan\n    | planPrimary CROSS planPrimary (CROSS planPrimary)*        #crossPlan\n    ;\n\njsonTablePathName\n    : identifier\n    ;\n\nplanPrimary\n    : jsonTablePathName\n    | '(' jsonTableSpecificPlan ')'\n    ;\n\njsonTableDefaultPlan\n    : (OUTER | INNER) (',' (UNION | CROSS))?\n    | (UNION | CROSS) (',' (OUTER | INNER))?\n    ;\n\ntableFunctionCall\n    : qualifiedName '(' (tableFunctionArgument (',' tableFunctionArgument)*)?\n      (COPARTITION copartitionTables (',' copartitionTables)*)? ')'\n    ;\n\ntableFunctionArgument\n    : (identifier '=>')? (tableArgument | descriptorArgument | expression) // descriptor before expression to avoid parsing descriptor as a function call\n    ;\n\ntableArgument\n    : tableArgumentRelation\n        (PARTITION BY ('(' (expression (',' expression)*)? ')' | expression))?\n        (PRUNE WHEN EMPTY | KEEP WHEN EMPTY)?\n        (ORDER BY ('(' sortItem (',' sortItem)* ')' | sortItem))?\n    ;\n\ntableArgumentRelation\n    : TABLE '(' qualifiedName ')' (AS? identifier columnAliases?)?  #tableArgumentTable\n    | TABLE '(' query ')' (AS? identifier columnAliases?)?          #tableArgumentQuery\n    ;\n\ndescriptorArgument\n    : DESCRIPTOR '(' descriptorField (',' descriptorField)* ')'\n    | CAST '(' NULL AS DESCRIPTOR ')'\n    ;\n\ndescriptorField\n    : identifier type?\n    ;\n\ncopartitionTables\n    : '(' qualifiedName ',' qualifiedName (',' qualifiedName)* ')'\n    ;\n\nexpression\n    : booleanExpression\n    ;\n\nwhereClause\n    : WHERE booleanExpression\n    ;\n\nbooleanExpression\n    : valueExpression predicate[$valueExpression.ctx]?  #predicated\n    | NOT booleanExpression                             #logicalNot\n    | booleanExpression AND booleanExpression           #and\n    | booleanExpression OR booleanExpression            #or\n    ;\n\n// workaround for https://github.com/antlr/antlr4/issues/780\npredicate[ParserRuleContext value]\n    : comparisonOperator right=valueExpression                            #comparison\n    | comparisonOperator comparisonQuantifier '(' query ')'               #quantifiedComparison\n    | NOT? BETWEEN lower=valueExpression AND upper=valueExpression        #between\n    | NOT? IN '(' expression (',' expression)* ')'                        #inList\n    | NOT? IN '(' query ')'                                               #inSubquery\n    | NOT? LIKE pattern=valueExpression (ESCAPE escape=valueExpression)?  #like\n    | IS NOT? NULL                                                        #nullPredicate\n    | IS NOT? DISTINCT FROM right=valueExpression                         #distinctFrom\n    ;\n\nvalueExpression\n    : primaryExpression                                                                 #valueExpressionDefault\n    | valueExpression AT timeZoneSpecifier                                              #atTimeZone\n    | operator=(MINUS | PLUS) valueExpression                                           #arithmeticUnary\n    | left=valueExpression operator=(ASTERISK | SLASH | PERCENT) right=valueExpression  #arithmeticBinary\n    | left=valueExpression operator=(PLUS | MINUS) right=valueExpression                #arithmeticBinary\n    | left=valueExpression CONCAT right=valueExpression                                 #concatenation\n    ;\n\nprimaryExpression\n    : NULL                                                                                #nullLiteral\n    | interval                                                                            #intervalLiteral\n    | identifier string                                                                   #typeConstructor\n    | DOUBLE PRECISION string                                                             #typeConstructor\n    | number                                                                              #numericLiteral\n    | booleanValue                                                                        #booleanLiteral\n    | string                                                                              #stringLiteral\n    | BINARY_LITERAL                                                                      #binaryLiteral\n    | QUESTION_MARK                                                                       #parameter\n    | POSITION '(' valueExpression IN valueExpression ')'                                 #position\n    | '(' expression (',' expression)+ ')'                                                #rowConstructor\n    | ROW '(' expression (',' expression)* ')'                                            #rowConstructor\n    | name=LISTAGG '(' setQuantifier? expression (',' string)?\n        (ON OVERFLOW listAggOverflowBehavior)? ')'\n        (WITHIN GROUP '(' ORDER BY sortItem (',' sortItem)* ')')\n        filter?                                                                           #listagg\n    | processingMode? qualifiedName '(' (label=identifier '.')? ASTERISK ')'\n        filter? over?                                                                     #functionCall\n    | processingMode? qualifiedName '(' (setQuantifier? expression (',' expression)*)?\n        (ORDER BY sortItem (',' sortItem)*)? ')' filter? (nullTreatment? over)?           #functionCall\n    | identifier over                                                                     #measure\n    | identifier '->' expression                                                          #lambda\n    | '(' (identifier (',' identifier)*)? ')' '->' expression                             #lambda\n    | '(' query ')'                                                                       #subqueryExpression\n    // This is an extension to ANSI SQL, which considers EXISTS to be a <boolean expression>\n    | EXISTS '(' query ')'                                                                #exists\n    | CASE operand=expression whenClause+ (ELSE elseExpression=expression)? END           #simpleCase\n    | CASE whenClause+ (ELSE elseExpression=expression)? END                              #searchedCase\n    | CAST '(' expression AS type ')'                                                     #cast\n    | TRY_CAST '(' expression AS type ')'                                                 #cast\n    | ARRAY '[' (expression (',' expression)*)? ']'                                       #arrayConstructor\n    | value=primaryExpression '[' index=valueExpression ']'                               #subscript\n    | identifier                                                                          #columnReference\n    | base=primaryExpression '.' fieldName=identifier                                     #dereference\n    | name=CURRENT_DATE                                                                   #currentDate\n    | name=CURRENT_TIME ('(' precision=INTEGER_VALUE ')')?                                #currentTime\n    | name=CURRENT_TIMESTAMP ('(' precision=INTEGER_VALUE ')')?                           #currentTimestamp\n    | name=LOCALTIME ('(' precision=INTEGER_VALUE ')')?                                   #localTime\n    | name=LOCALTIMESTAMP ('(' precision=INTEGER_VALUE ')')?                              #localTimestamp\n    | name=CURRENT_USER                                                                   #currentUser\n    | name=CURRENT_CATALOG                                                                #currentCatalog\n    | name=CURRENT_SCHEMA                                                                 #currentSchema\n    | name=CURRENT_PATH                                                                   #currentPath\n    | TRIM '(' (trimsSpecification? trimChar=valueExpression? FROM)?\n        trimSource=valueExpression ')'                                                    #trim\n    | TRIM '(' trimSource=valueExpression ',' trimChar=valueExpression ')'                #trim\n    | SUBSTRING '(' valueExpression FROM valueExpression (FOR valueExpression)? ')'       #substring\n    | NORMALIZE '(' valueExpression (',' normalForm)? ')'                                 #normalize\n    | EXTRACT '(' identifier FROM valueExpression ')'                                     #extract\n    | '(' expression ')'                                                                  #parenthesizedExpression\n    | GROUPING '(' (qualifiedName (',' qualifiedName)*)? ')'                              #groupingOperation\n    | JSON_EXISTS '(' jsonPathInvocation (jsonExistsErrorBehavior ON ERROR)? ')'          #jsonExists\n    | JSON_VALUE '('\n        jsonPathInvocation\n        (RETURNING type)?\n        (emptyBehavior=jsonValueBehavior ON EMPTY)?\n        (errorBehavior=jsonValueBehavior ON ERROR)?\n      ')'                                                                                 #jsonValue\n    | JSON_QUERY '('\n        jsonPathInvocation\n        (RETURNING type (FORMAT jsonRepresentation)?)?\n        (jsonQueryWrapperBehavior WRAPPER)?\n        ((KEEP | OMIT) QUOTES (ON SCALAR TEXT_STRING)?)?\n        (emptyBehavior=jsonQueryBehavior ON EMPTY)?\n        (errorBehavior=jsonQueryBehavior ON ERROR)?\n      ')'                                                                                 #jsonQuery\n    | JSON_OBJECT '('\n        (\n          jsonObjectMember (',' jsonObjectMember)*\n          (NULL ON NULL | ABSENT ON NULL)?\n          (WITH UNIQUE KEYS? | WITHOUT UNIQUE KEYS?)?\n        )?\n        (RETURNING type (FORMAT jsonRepresentation)?)?\n      ')'                                                                                 #jsonObject\n    | JSON_ARRAY '('\n        (\n          jsonValueExpression (',' jsonValueExpression)*\n          (NULL ON NULL | ABSENT ON NULL)?\n        )?\n        (RETURNING type (FORMAT jsonRepresentation)?)?\n     ')'                                                                                  #jsonArray\n    ;\n\njsonPathInvocation\n    : jsonValueExpression ',' path=string\n        (AS pathName=identifier)?\n        (PASSING jsonArgument (',' jsonArgument)*)?\n    ;\n\njsonValueExpression\n    : expression (FORMAT jsonRepresentation)?\n    ;\n\njsonRepresentation\n    : JSON (ENCODING (UTF8 | UTF16 | UTF32))? // TODO add implementation-defined JSON representation option\n    ;\n\njsonArgument\n    : jsonValueExpression AS identifier\n    ;\n\njsonExistsErrorBehavior\n    : TRUE\n    | FALSE\n    | UNKNOWN\n    | ERROR\n    ;\n\njsonValueBehavior\n    : ERROR\n    | NULL\n    | DEFAULT expression\n    ;\n\njsonQueryWrapperBehavior\n    : WITHOUT ARRAY?\n    | WITH (CONDITIONAL | UNCONDITIONAL)? ARRAY?\n    ;\n\njsonQueryBehavior\n    : ERROR\n    | NULL\n    | EMPTY ARRAY\n    | EMPTY OBJECT\n    ;\n\njsonObjectMember\n    : KEY? expression VALUE jsonValueExpression\n    | expression ':' jsonValueExpression\n    ;\n\nprocessingMode\n    : RUNNING\n    | FINAL\n    ;\n\nnullTreatment\n    : IGNORE NULLS\n    | RESPECT NULLS\n    ;\n\nstring\n    : STRING                                #basicStringLiteral\n    | UNICODE_STRING (UESCAPE STRING)?      #unicodeStringLiteral\n    ;\n\ntimeZoneSpecifier\n    : TIME ZONE interval  #timeZoneInterval\n    | TIME ZONE string    #timeZoneString\n    ;\n\ncomparisonOperator\n    : EQ | NEQ | LT | LTE | GT | GTE\n    ;\n\ncomparisonQuantifier\n    : ALL | SOME | ANY\n    ;\n\nbooleanValue\n    : TRUE | FALSE\n    ;\n\ninterval\n    : INTERVAL sign=(PLUS | MINUS)? string from=intervalField (TO to=intervalField)?\n    ;\n\nintervalField\n    : YEAR | MONTH | DAY | HOUR | MINUTE | SECOND\n    ;\n\nnormalForm\n    : NFD | NFC | NFKD | NFKC\n    ;\n\ntype\n    : ROW '(' rowField (',' rowField)* ')'                                         #rowType\n    | INTERVAL from=intervalField (TO to=intervalField)?                           #intervalType\n    | base=TIMESTAMP ('(' precision = typeParameter ')')? (WITHOUT TIME ZONE)?     #dateTimeType\n    | base=TIMESTAMP ('(' precision = typeParameter ')')? WITH TIME ZONE           #dateTimeType\n    | base=TIME ('(' precision = typeParameter ')')? (WITHOUT TIME ZONE)?          #dateTimeType\n    | base=TIME ('(' precision = typeParameter ')')? WITH TIME ZONE                #dateTimeType\n    | DOUBLE PRECISION                                                             #doublePrecisionType\n    | ARRAY '<' type '>'                                                           #legacyArrayType\n    | MAP '<' keyType=type ',' valueType=type '>'                                  #legacyMapType\n    | type ARRAY ('[' INTEGER_VALUE ']')?                                          #arrayType\n    | identifier ('(' typeParameter (',' typeParameter)* ')')?                     #genericType\n    ;\n\nrowField\n    : type\n    | identifier type;\n\ntypeParameter\n    : INTEGER_VALUE | type\n    ;\n\nwhenClause\n    : WHEN condition=expression THEN result=expression\n    ;\n\nfilter\n    : FILTER '(' WHERE booleanExpression ')'\n    ;\n\nmergeCase\n    : WHEN MATCHED (AND condition=expression)? THEN\n        UPDATE SET targets+=identifier EQ values+=expression\n          (',' targets+=identifier EQ values+=expression)*                  #mergeUpdate\n    | WHEN MATCHED (AND condition=expression)? THEN DELETE                  #mergeDelete\n    | WHEN NOT MATCHED (AND condition=expression)? THEN\n        INSERT ('(' targets+=identifier (',' targets+=identifier)* ')')?\n        VALUES '(' values+=expression (',' values+=expression)* ')'         #mergeInsert\n    ;\n\nover\n    : OVER (windowName=identifier | '(' windowSpecification ')')\n    ;\n\nwindowFrame\n    : (MEASURES measureDefinition (',' measureDefinition)*)?\n      frameExtent\n      (AFTER MATCH skipTo)?\n      (INITIAL | SEEK)?\n      (PATTERN '(' rowPattern ')')?\n      (SUBSET subsetDefinition (',' subsetDefinition)*)?\n      (DEFINE variableDefinition (',' variableDefinition)*)?\n    ;\n\nframeExtent\n    : frameType=RANGE start=frameBound\n    | frameType=ROWS start=frameBound\n    | frameType=GROUPS start=frameBound\n    | frameType=RANGE BETWEEN start=frameBound AND end=frameBound\n    | frameType=ROWS BETWEEN start=frameBound AND end=frameBound\n    | frameType=GROUPS BETWEEN start=frameBound AND end=frameBound\n    ;\n\nframeBound\n    : UNBOUNDED boundType=PRECEDING                 #unboundedFrame\n    | UNBOUNDED boundType=FOLLOWING                 #unboundedFrame\n    | CURRENT ROW                                   #currentRowBound\n    | expression boundType=(PRECEDING | FOLLOWING)  #boundedFrame\n    ;\n\nrowPattern\n    : patternPrimary patternQuantifier?                 #quantifiedPrimary\n    | rowPattern rowPattern                             #patternConcatenation\n    | rowPattern '|' rowPattern                         #patternAlternation\n    ;\n\npatternPrimary\n    : identifier                                        #patternVariable\n    | '(' ')'                                           #emptyPattern\n    | PERMUTE '(' rowPattern (',' rowPattern)* ')'      #patternPermutation\n    | '(' rowPattern ')'                                #groupedPattern\n    | '^'                                               #partitionStartAnchor\n    | '$'                                               #partitionEndAnchor\n    | '{-' rowPattern '-}'                              #excludedPattern\n    ;\n\npatternQuantifier\n    : ASTERISK (reluctant=QUESTION_MARK)?                                                       #zeroOrMoreQuantifier\n    | PLUS (reluctant=QUESTION_MARK)?                                                           #oneOrMoreQuantifier\n    | QUESTION_MARK (reluctant=QUESTION_MARK)?                                                  #zeroOrOneQuantifier\n    | '{' exactly=INTEGER_VALUE '}' (reluctant=QUESTION_MARK)?                                  #rangeQuantifier\n    | '{' (atLeast=INTEGER_VALUE)? ',' (atMost=INTEGER_VALUE)? '}' (reluctant=QUESTION_MARK)?   #rangeQuantifier\n    ;\n\nupdateAssignment\n    : identifier EQ expression\n    ;\n\nexplainOption\n    : FORMAT value=(TEXT | GRAPHVIZ | JSON)                 #explainFormat\n    | TYPE value=(LOGICAL | DISTRIBUTED | VALIDATE | IO)    #explainType\n    ;\n\ntransactionMode\n    : ISOLATION LEVEL levelOfIsolation    #isolationLevel\n    | READ accessMode=(ONLY | WRITE)      #transactionAccessMode\n    ;\n\nlevelOfIsolation\n    : READ UNCOMMITTED                    #readUncommitted\n    | READ COMMITTED                      #readCommitted\n    | REPEATABLE READ                     #repeatableRead\n    | SERIALIZABLE                        #serializable\n    ;\n\ncallArgument\n    : expression                    #positionalArgument\n    | identifier '=>' expression    #namedArgument\n    ;\n\npathElement\n    : identifier '.' identifier     #qualifiedArgument\n    | identifier                    #unqualifiedArgument\n    ;\n\npathSpecification\n    : pathElement (',' pathElement)*\n    ;\n\nfunctionSpecification\n    : FUNCTION functionDeclaration returnsClause routineCharacteristic* controlStatement\n    ;\n\nfunctionDeclaration\n    : qualifiedName '(' (parameterDeclaration (',' parameterDeclaration)*)? ')'\n    ;\n\nparameterDeclaration\n    : identifier? type\n    ;\n\nreturnsClause\n    : RETURNS type\n    ;\n\nroutineCharacteristic\n    : LANGUAGE identifier               #languageCharacteristic\n    | NOT? DETERMINISTIC                #deterministicCharacteristic\n    | RETURNS NULL ON NULL INPUT        #returnsNullOnNullInputCharacteristic\n    | CALLED ON NULL INPUT              #calledOnNullInputCharacteristic\n    | SECURITY (DEFINER | INVOKER)      #securityCharacteristic\n    | COMMENT string                    #commentCharacteristic\n    ;\n\ncontrolStatement\n    : RETURN valueExpression                                                        #returnStatement\n    | SET identifier EQ expression                                                  #assignmentStatement\n    | CASE expression caseStatementWhenClause+ elseClause? END CASE                 #simpleCaseStatement\n    | CASE caseStatementWhenClause+ elseClause? END CASE                            #searchedCaseStatement\n    | IF expression THEN sqlStatementList elseIfClause* elseClause? END IF          #ifStatement\n    | ITERATE identifier                                                            #iterateStatement\n    | LEAVE identifier                                                              #leaveStatement\n    | BEGIN (variableDeclaration SEMICOLON)* sqlStatementList? END                  #compoundStatement\n    | (label=identifier ':')? LOOP sqlStatementList END LOOP                        #loopStatement\n    | (label=identifier ':')? WHILE expression DO sqlStatementList END WHILE        #whileStatement\n    | (label=identifier ':')? REPEAT sqlStatementList UNTIL expression END REPEAT   #repeatStatement\n    ;\n\ncaseStatementWhenClause\n    : WHEN expression THEN sqlStatementList\n    ;\n\nelseIfClause\n    : ELSEIF expression THEN sqlStatementList\n    ;\n\nelseClause\n    : ELSE sqlStatementList\n    ;\n\nvariableDeclaration\n    : DECLARE identifier (',' identifier)* type (DEFAULT valueExpression)?\n    ;\n\nsqlStatementList\n    : (controlStatement SEMICOLON)+\n    ;\n\nprivilege\n    : CREATE | SELECT | DELETE | INSERT | UPDATE | identifier\n    ;\n\nentityKind\n    : TABLE | SCHEMA | identifier\n    ;\n\ngrantObject\n    : entityKind? qualifiedName\n    ;\n\nqualifiedName\n    : identifier ('.' identifier)*\n    ;\n\nqueryPeriod\n    : FOR rangeType AS OF end=valueExpression\n    ;\n\nrangeType\n    : TIMESTAMP\n    | VERSION\n    ;\n\ngrantor\n    : principal             #specifiedPrincipal\n    | CURRENT_USER          #currentUserGrantor\n    | CURRENT_ROLE          #currentRoleGrantor\n    ;\n\nprincipal\n    : identifier            #unspecifiedPrincipal\n    | USER identifier       #userPrincipal\n    | ROLE identifier       #rolePrincipal\n    ;\n\nroles\n    : identifier (',' identifier)*\n    ;\n\nprivilegeOrRole\n    : CREATE | SELECT | DELETE | INSERT | UPDATE | identifier\n    ;\n\nidentifier\n    : IDENTIFIER             #unquotedIdentifier\n    | QUOTED_IDENTIFIER      #quotedIdentifier\n    | nonReserved            #unquotedIdentifier\n    | BACKQUOTED_IDENTIFIER  #backQuotedIdentifier\n    | DIGIT_IDENTIFIER       #digitIdentifier\n    ;\n\nnumber\n    : MINUS? DECIMAL_VALUE  #decimalLiteral\n    | MINUS? DOUBLE_VALUE   #doubleLiteral\n    | MINUS? INTEGER_VALUE  #integerLiteral\n    ;\n\nauthorizationUser\n    : identifier            #identifierUser\n    | string                #stringUser\n    ;\n\nnonReserved\n    // IMPORTANT: this rule must only contain tokens. Nested rules are not supported. See SqlParser.exitNonReserved\n    : ABSENT | ADD | ADMIN | AFTER | ALL | ANALYZE | ANY | ARRAY | ASC | AT | AUTHORIZATION\n    | BEGIN | BERNOULLI | BOTH\n    | CALL | CALLED | CASCADE | CATALOG | CATALOGS | COLUMN | COLUMNS | COMMENT | COMMIT | COMMITTED | CONDITIONAL | COPARTITION | COUNT | CURRENT\n    | DATA | DATE | DAY | DECLARE | DEFAULT | DEFINE | DEFINER | DENY | DESC | DESCRIPTOR | DETERMINISTIC | DISTRIBUTED | DO | DOUBLE\n    | ELSEIF | EMPTY | ENCODING | ERROR | EXCLUDING | EXPLAIN\n    | FETCH | FILTER | FINAL | FIRST | FOLLOWING | FORMAT | FUNCTION | FUNCTIONS\n    | GRACE | GRANT | GRANTED | GRANTS | GRAPHVIZ | GROUPS\n    | HOUR\n    | IF | IGNORE | IMMEDIATE | INCLUDING | INITIAL | INPUT | INTERVAL | INVOKER | IO | ITERATE | ISOLATION\n    | JSON\n    | KEEP | KEY | KEYS\n    | LANGUAGE | LAST | LATERAL | LEADING | LEAVE | LEVEL | LIMIT | LOCAL | LOGICAL | LOOP\n    | MAP | MATCH | MATCHED | MATCHES | MATCH_RECOGNIZE | MATERIALIZED | MEASURES | MERGE | MINUTE | MONTH\n    | NESTED | NEXT | NFC | NFD | NFKC | NFKD | NO | NONE | NULLIF | NULLS\n    | OBJECT | OF | OFFSET | OMIT | ONE | ONLY | OPTION | ORDINALITY | OUTPUT | OVER | OVERFLOW\n    | PARTITION | PARTITIONS | PASSING | PAST | PATH | PATTERN | PER | PERIOD | PERMUTE | PLAN | POSITION | PRECEDING | PRECISION | PRIVILEGES | PROPERTIES | PRUNE\n    | QUOTES\n    | RANGE | READ | REFRESH | RENAME | REPEAT  | REPEATABLE | REPLACE | RESET | RESPECT | RESTRICT | RETURN | RETURNING | RETURNS | REVOKE | ROLE | ROLES | ROLLBACK | ROW | ROWS | RUNNING\n    | SCALAR | SCHEMA | SCHEMAS | SECOND | SECURITY | SEEK | SERIALIZABLE | SESSION | SET | SETS\n    | SHOW | SOME | START | STATS | SUBSET | SUBSTRING | SYSTEM\n    | TABLES | TABLESAMPLE | TEXT | TEXT_STRING | TIES | TIME | TIMESTAMP | TO | TRAILING | TRANSACTION | TRUNCATE | TRY_CAST | TYPE\n    | UNBOUNDED | UNCOMMITTED | UNCONDITIONAL | UNIQUE | UNKNOWN | UNMATCHED | UNTIL | UPDATE | USE | USER | UTF16 | UTF32 | UTF8\n    | VALIDATE | VALUE | VERBOSE | VERSION | VIEW\n    | WHILE | WINDOW | WITHIN | WITHOUT | WORK | WRAPPER | WRITE\n    | YEAR\n    | ZONE\n    ;\n\nABSENT: 'ABSENT';\nADD: 'ADD';\nADMIN: 'ADMIN';\nAFTER: 'AFTER';\nALL: 'ALL';\nALTER: 'ALTER';\nANALYZE: 'ANALYZE';\nAND: 'AND';\nANY: 'ANY';\nARRAY: 'ARRAY';\nAS: 'AS';\nASC: 'ASC';\nAT: 'AT';\nAUTHORIZATION: 'AUTHORIZATION';\nBEGIN: 'BEGIN';\nBERNOULLI: 'BERNOULLI';\nBETWEEN: 'BETWEEN';\nBOTH: 'BOTH';\nBY: 'BY';\nCALL: 'CALL';\nCALLED: 'CALLED';\nCASCADE: 'CASCADE';\nCASE: 'CASE';\nCAST: 'CAST';\nCATALOG: 'CATALOG';\nCATALOGS: 'CATALOGS';\nCOLUMN: 'COLUMN';\nCOLUMNS: 'COLUMNS';\nCOMMENT: 'COMMENT';\nCOMMIT: 'COMMIT';\nCOMMITTED: 'COMMITTED';\nCONDITIONAL: 'CONDITIONAL';\nCONSTRAINT: 'CONSTRAINT';\nCOUNT: 'COUNT';\nCOPARTITION: 'COPARTITION';\nCREATE: 'CREATE';\nCROSS: 'CROSS';\nCUBE: 'CUBE';\nCURRENT: 'CURRENT';\nCURRENT_CATALOG: 'CURRENT_CATALOG';\nCURRENT_DATE: 'CURRENT_DATE';\nCURRENT_PATH: 'CURRENT_PATH';\nCURRENT_ROLE: 'CURRENT_ROLE';\nCURRENT_SCHEMA: 'CURRENT_SCHEMA';\nCURRENT_TIME: 'CURRENT_TIME';\nCURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP';\nCURRENT_USER: 'CURRENT_USER';\nDATA: 'DATA';\nDATE: 'DATE';\nDAY: 'DAY';\nDEALLOCATE: 'DEALLOCATE';\nDECLARE: 'DECLARE';\nDEFAULT: 'DEFAULT';\nDEFINE: 'DEFINE';\nDEFINER: 'DEFINER';\nDELETE: 'DELETE';\nDENY: 'DENY';\nDESC: 'DESC';\nDESCRIBE: 'DESCRIBE';\nDESCRIPTOR: 'DESCRIPTOR';\nDETERMINISTIC: 'DETERMINISTIC';\nDISTINCT: 'DISTINCT';\nDISTRIBUTED: 'DISTRIBUTED';\nDO: 'DO';\nDOUBLE: 'DOUBLE';\nDROP: 'DROP';\nELSE: 'ELSE';\nEMPTY: 'EMPTY';\nELSEIF: 'ELSEIF';\nENCODING: 'ENCODING';\nEND: 'END';\nERROR: 'ERROR';\nESCAPE: 'ESCAPE';\nEXCEPT: 'EXCEPT';\nEXCLUDING: 'EXCLUDING';\nEXECUTE: 'EXECUTE';\nEXISTS: 'EXISTS';\nEXPLAIN: 'EXPLAIN';\nEXTRACT: 'EXTRACT';\nFALSE: 'FALSE';\nFETCH: 'FETCH';\nFILTER: 'FILTER';\nFINAL: 'FINAL';\nFIRST: 'FIRST';\nFOLLOWING: 'FOLLOWING';\nFOR: 'FOR';\nFORMAT: 'FORMAT';\nFROM: 'FROM';\nFULL: 'FULL';\nFUNCTION: 'FUNCTION';\nFUNCTIONS: 'FUNCTIONS';\nGRACE: 'GRACE';\nGRANT: 'GRANT';\nGRANTED: 'GRANTED';\nGRANTS: 'GRANTS';\nGRAPHVIZ: 'GRAPHVIZ';\nGROUP: 'GROUP';\nGROUPING: 'GROUPING';\nGROUPS: 'GROUPS';\nHAVING: 'HAVING';\nHOUR: 'HOUR';\nIF: 'IF';\nIGNORE: 'IGNORE';\nIMMEDIATE: 'IMMEDIATE';\nIN: 'IN';\nINCLUDING: 'INCLUDING';\nINITIAL: 'INITIAL';\nINNER: 'INNER';\nINPUT: 'INPUT';\nINSERT: 'INSERT';\nINTERSECT: 'INTERSECT';\nINTERVAL: 'INTERVAL';\nINTO: 'INTO';\nINVOKER: 'INVOKER';\nIO: 'IO';\nIS: 'IS';\nISOLATION: 'ISOLATION';\nITERATE: 'ITERATE';\nJOIN: 'JOIN';\nJSON: 'JSON';\nJSON_ARRAY: 'JSON_ARRAY';\nJSON_EXISTS: 'JSON_EXISTS';\nJSON_OBJECT: 'JSON_OBJECT';\nJSON_QUERY: 'JSON_QUERY';\nJSON_TABLE: 'JSON_TABLE';\nJSON_VALUE: 'JSON_VALUE';\nKEEP: 'KEEP';\nKEY: 'KEY';\nKEYS: 'KEYS';\nLANGUAGE: 'LANGUAGE';\nLAST: 'LAST';\nLATERAL: 'LATERAL';\nLEADING: 'LEADING';\nLEAVE: 'LEAVE';\nLEFT: 'LEFT';\nLEVEL: 'LEVEL';\nLIKE: 'LIKE';\nLIMIT: 'LIMIT';\nLISTAGG: 'LISTAGG';\nLOCAL: 'LOCAL';\nLOCALTIME: 'LOCALTIME';\nLOCALTIMESTAMP: 'LOCALTIMESTAMP';\nLOGICAL: 'LOGICAL';\nLOOP: 'LOOP';\nMAP: 'MAP';\nMATCH: 'MATCH';\nMATCHED: 'MATCHED';\nMATCHES: 'MATCHES';\nMATCH_RECOGNIZE: 'MATCH_RECOGNIZE';\nMATERIALIZED: 'MATERIALIZED';\nMEASURES: 'MEASURES';\nMERGE: 'MERGE';\nMINUTE: 'MINUTE';\nMONTH: 'MONTH';\nNATURAL: 'NATURAL';\nNESTED: 'NESTED';\nNEXT: 'NEXT';\nNFC : 'NFC';\nNFD : 'NFD';\nNFKC : 'NFKC';\nNFKD : 'NFKD';\nNO: 'NO';\nNONE: 'NONE';\nNORMALIZE: 'NORMALIZE';\nNOT: 'NOT';\nNULL: 'NULL';\nNULLIF: 'NULLIF';\nNULLS: 'NULLS';\nOBJECT: 'OBJECT';\nOF: 'OF';\nOFFSET: 'OFFSET';\nOMIT: 'OMIT';\nON: 'ON';\nONE: 'ONE';\nONLY: 'ONLY';\nOPTION: 'OPTION';\nOR: 'OR';\nORDER: 'ORDER';\nORDINALITY: 'ORDINALITY';\nOUTER: 'OUTER';\nOUTPUT: 'OUTPUT';\nOVER: 'OVER';\nOVERFLOW: 'OVERFLOW';\nPARTITION: 'PARTITION';\nPARTITIONS: 'PARTITIONS';\nPASSING: 'PASSING';\nPAST: 'PAST';\nPATH: 'PATH';\nPATTERN: 'PATTERN';\nPER: 'PER';\nPERIOD: 'PERIOD';\nPERMUTE: 'PERMUTE';\nPLAN : 'PLAN';\nPOSITION: 'POSITION';\nPRECEDING: 'PRECEDING';\nPRECISION: 'PRECISION';\nPREPARE: 'PREPARE';\nPRIVILEGES: 'PRIVILEGES';\nPROPERTIES: 'PROPERTIES';\nPRUNE: 'PRUNE';\nQUOTES: 'QUOTES';\nRANGE: 'RANGE';\nREAD: 'READ';\nRECURSIVE: 'RECURSIVE';\nREFRESH: 'REFRESH';\nRENAME: 'RENAME';\nREPEAT: 'REPEAT';\nREPEATABLE: 'REPEATABLE';\nREPLACE: 'REPLACE';\nRESET: 'RESET';\nRESPECT: 'RESPECT';\nRESTRICT: 'RESTRICT';\nRETURN: 'RETURN';\nRETURNING: 'RETURNING';\nRETURNS: 'RETURNS';\nREVOKE: 'REVOKE';\nRIGHT: 'RIGHT';\nROLE: 'ROLE';\nROLES: 'ROLES';\nROLLBACK: 'ROLLBACK';\nROLLUP: 'ROLLUP';\nROW: 'ROW';\nROWS: 'ROWS';\nRUNNING: 'RUNNING';\nSCALAR: 'SCALAR';\nSCHEMA: 'SCHEMA';\nSCHEMAS: 'SCHEMAS';\nSECOND: 'SECOND';\nSECURITY: 'SECURITY';\nSEEK: 'SEEK';\nSELECT: 'SELECT';\nSERIALIZABLE: 'SERIALIZABLE';\nSESSION: 'SESSION';\nSET: 'SET';\nSETS: 'SETS';\nSHOW: 'SHOW';\nSOME: 'SOME';\nSTART: 'START';\nSTATS: 'STATS';\nSUBSET: 'SUBSET';\nSUBSTRING: 'SUBSTRING';\nSYSTEM: 'SYSTEM';\nTABLE: 'TABLE';\nTABLES: 'TABLES';\nTABLESAMPLE: 'TABLESAMPLE';\nTEXT: 'TEXT';\nTEXT_STRING: 'STRING';\nTHEN: 'THEN';\nTIES: 'TIES';\nTIME: 'TIME';\nTIMESTAMP: 'TIMESTAMP';\nTO: 'TO';\nTRAILING: 'TRAILING';\nTRANSACTION: 'TRANSACTION';\nTRIM: 'TRIM';\nTRUE: 'TRUE';\nTRUNCATE: 'TRUNCATE';\nTRY_CAST: 'TRY_CAST';\nTYPE: 'TYPE';\nUESCAPE: 'UESCAPE';\nUNBOUNDED: 'UNBOUNDED';\nUNCOMMITTED: 'UNCOMMITTED';\nUNCONDITIONAL: 'UNCONDITIONAL';\nUNION: 'UNION';\nUNIQUE: 'UNIQUE';\nUNKNOWN: 'UNKNOWN';\nUNMATCHED: 'UNMATCHED';\nUNNEST: 'UNNEST';\nUNTIL: 'UNTIL';\nUPDATE: 'UPDATE';\nUSE: 'USE';\nUSER: 'USER';\nUSING: 'USING';\nUTF16: 'UTF16';\nUTF32: 'UTF32';\nUTF8: 'UTF8';\nVALIDATE: 'VALIDATE';\nVALUE: 'VALUE';\nVALUES: 'VALUES';\nVERBOSE: 'VERBOSE';\nVERSION: 'VERSION';\nVIEW: 'VIEW';\nWHEN: 'WHEN';\nWHERE: 'WHERE';\nWHILE: 'WHILE';\nWINDOW: 'WINDOW';\nWITH: 'WITH';\nWITHIN: 'WITHIN';\nWITHOUT: 'WITHOUT';\nWORK: 'WORK';\nWRAPPER: 'WRAPPER';\nWRITE: 'WRITE';\nYEAR: 'YEAR';\nZONE: 'ZONE';\n\nEQ: '=';\nNEQ: '<>' | '!=';\nLT: '<';\nLTE: '<=';\nGT: '>';\nGTE: '>=';\n\nPLUS: '+';\nMINUS: '-';\nASTERISK: '*';\nSLASH: '/';\nPERCENT: '%';\nCONCAT: '||';\nQUESTION_MARK: '?';\nSEMICOLON: ';';\n\nSTRING\n    : '\\'' ( ~'\\'' | '\\'\\'' )* '\\''\n    ;\n\nUNICODE_STRING\n    : 'U&\\'' ( ~'\\'' | '\\'\\'' )* '\\''\n    ;\n\n// Note: we allow any character inside the binary literal and validate\n// its a correct literal when the AST is being constructed. This\n// allows us to provide more meaningful error messages to the user\nBINARY_LITERAL\n    : 'X\\'' (~'\\'')* '\\''\n    ;\n\nINTEGER_VALUE\n    : DECIMAL_INTEGER\n    | HEXADECIMAL_INTEGER\n    | OCTAL_INTEGER\n    | BINARY_INTEGER\n    ;\n\nDECIMAL_VALUE\n    : DECIMAL_INTEGER '.' DECIMAL_INTEGER?\n    | '.' DECIMAL_INTEGER\n    ;\n\nDOUBLE_VALUE\n    : DIGIT+ ('.' DIGIT*)? EXPONENT\n    | '.' DIGIT+ EXPONENT\n    ;\n\nIDENTIFIER\n    : (LETTER | '_') (LETTER | DIGIT | '_')*\n    ;\n\nDIGIT_IDENTIFIER\n    : DIGIT (LETTER | DIGIT | '_')+\n    ;\n\nQUOTED_IDENTIFIER\n    : '\"' ( ~'\"' | '\"\"' )* '\"'\n    ;\n\nBACKQUOTED_IDENTIFIER\n    : '`' ( ~'`' | '``' )* '`'\n    ;\n\nfragment DECIMAL_INTEGER\n    : DIGIT ('_'? DIGIT)*\n    ;\n\nfragment HEXADECIMAL_INTEGER\n    : '0X' ('_'? (DIGIT | [A-F]))+\n    ;\n\nfragment OCTAL_INTEGER\n    : '0O' ('_'? [0-7])+\n    ;\n\nfragment BINARY_INTEGER\n    : '0B' ('_'? [01])+\n    ;\n\nfragment EXPONENT\n    : 'E' [+-]? DIGIT+\n    ;\n\nfragment DIGIT\n    : [0-9]\n    ;\n\nfragment LETTER\n    : [A-Z]\n    ;\n\nSIMPLE_COMMENT\n    : '--' ~[\\r\\n]* '\\r'? '\\n'? -> channel(HIDDEN)\n    ;\n\nBRACKETED_COMMENT\n    : '/*' .*? '*/' -> channel(HIDDEN)\n    ;\n\nWS\n    : [ \\r\\n\\t]+ -> channel(HIDDEN)\n    ;\n\n// Catch-all for anything we can't recognize.\n// We use this to be able to ignore and recover all the text\n// when splitting statements with DelimiterLexer\nUNRECOGNIZED\n    : .\n    ;\n"
  },
  {
    "path": "superior-trino-parser/src/main/java/io/github/melin/superior/parser/trino/CaseInsensitiveStream.java",
    "content": "/*\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage io.github.melin.superior.parser.trino;\n\nimport org.antlr.v4.runtime.CharStream;\nimport org.antlr.v4.runtime.IntStream;\nimport org.antlr.v4.runtime.misc.Interval;\n\npublic class CaseInsensitiveStream implements CharStream {\n    private final CharStream stream;\n\n    public CaseInsensitiveStream(CharStream stream) {\n        this.stream = stream;\n    }\n\n    @Override\n    public String getText(Interval interval) {\n        return stream.getText(interval);\n    }\n\n    @Override\n    public void consume() {\n        stream.consume();\n    }\n\n    @Override\n    public int LA(int i) {\n        int result = stream.LA(i);\n\n        switch (result) {\n            case 0:\n            case IntStream.EOF:\n                return result;\n            default:\n                return Character.toUpperCase(result);\n        }\n    }\n\n    @Override\n    public int mark() {\n        return stream.mark();\n    }\n\n    @Override\n    public void release(int marker) {\n        stream.release(marker);\n    }\n\n    @Override\n    public int index() {\n        return stream.index();\n    }\n\n    @Override\n    public void seek(int index) {\n        stream.seek(index);\n    }\n\n    @Override\n    public int size() {\n        return stream.size();\n    }\n\n    @Override\n    public String getSourceName() {\n        return stream.getSourceName();\n    }\n}\n"
  },
  {
    "path": "superior-trino-parser/src/main/kotlin/io/github/melin/superior/parser/trino/AbstractSqlParser.kt",
    "content": "package io.github.melin.superior.parser.spark\n\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.parser.trino.antlr4.TrinoSqlBaseParser\nimport java.util.concurrent.atomic.AtomicReference\n\nobject AbstractSqlParser {\n    private val parserCaches = AtomicReference<AntlrCaches>(AntlrCaches(TrinoSqlBaseParser._ATN))\n\n    /**\n     * Install the parser caches into the given parser.\n     *\n     * This method should be called before parsing any input.\n     */\n    fun installCaches(parser: TrinoSqlBaseParser): Unit = parserCaches.get().installCaches(parser)\n\n    /**\n     * Drop the existing parser caches and create a new one.\n     *\n     * ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can\n     * consume a lot of memory depending on the input seen so far.\n     *\n     * This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL\n     * inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.\n     */\n    fun refreshParserCaches() {\n        parserCaches.set(AntlrCaches(TrinoSqlBaseParser._ATN))\n    }\n}\n"
  },
  {
    "path": "superior-trino-parser/src/main/kotlin/io/github/melin/superior/parser/trino/TrinoSqlAntlr4Visitor.kt",
    "content": "package io.github.melin.superior.parser.trino\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.*\nimport io.github.melin.superior.common.antlr4.ParserUtils.source\nimport io.github.melin.superior.common.relational.DefaultStatement\nimport io.github.melin.superior.common.relational.FunctionId\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.common.relational.TableId\nimport io.github.melin.superior.common.relational.common.ShowStatement\nimport io.github.melin.superior.common.relational.create.CreateTableAsSelect\nimport io.github.melin.superior.common.relational.dml.*\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport io.github.melin.superior.parser.trino.antlr4.TrinoSqlBaseBaseVisitor\nimport io.github.melin.superior.parser.trino.antlr4.TrinoSqlBaseParser\nimport org.antlr.v4.runtime.tree.RuleNode\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/1/10. */\nclass TrinoSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) :\n    TrinoSqlBaseBaseVisitor<Statement>() {\n\n    private var currentOptType: StatementType = StatementType.UNKOWN\n\n    private var limit: Int? = null\n    private var offset: Int? = null\n    private var inputTables: ArrayList<TableId> = arrayListOf()\n    private var cteTempTables: ArrayList<TableId> = arrayListOf()\n    private var functionNames: HashSet<FunctionId> = hashSetOf()\n\n    private var statements: ArrayList<Statement> = arrayListOf()\n    private val sqls: ArrayList<String> = arrayListOf()\n\n    fun getSqlStatements(): List<Statement> {\n        return statements\n    }\n\n    fun getSplitSqls(): List<String> {\n        return sqls\n    }\n\n    override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {\n        return if (currentResult == null) true else false\n    }\n\n    override fun visitSqlStatements(ctx: TrinoSqlBaseParser.SqlStatementsContext): Statement? {\n        ctx.singleStatement().forEach {\n            var sql = source(it)\n            if (splitSql) {\n                if (StringUtils.endsWith(sql, \";\")) {\n                    sql = StringUtils.substringBeforeLast(sql, \";\")\n                }\n                sqls.add(sql)\n            } else {\n                val startNode = it.start.text\n                val statement =\n                    if (StringUtils.equalsIgnoreCase(\"show\", startNode)) {\n                        val keyWords: ArrayList<String> = arrayListOf()\n                        CommonUtils.findShowStatementKeyWord(keyWords, it)\n                        ShowStatement(*keyWords.toTypedArray())\n                    } else {\n                        var statement = this.visitSingleStatement(it)\n                        if (statement == null) {\n                            statement = DefaultStatement(StatementType.UNKOWN)\n                        }\n                        statement\n                    }\n\n                statement.setSql(sql)\n                statements.add(statement)\n\n                clean()\n            }\n        }\n        return null\n    }\n\n    private fun clean() {\n        currentOptType = StatementType.UNKOWN\n\n        limit = null\n        offset = null\n        inputTables = arrayListOf()\n        cteTempTables = arrayListOf()\n    }\n\n    override fun visitStatementDefault(ctx: TrinoSqlBaseParser.StatementDefaultContext): Statement? {\n        if (StringUtils.equalsIgnoreCase(\"select\", ctx.start.text)) {\n            currentOptType = StatementType.SELECT\n            super.visitRootQuery(ctx.rootQuery())\n\n            val limit = ctx.rootQuery()?.query()?.queryNoWith()?.limit?.text?.toInt()\n            return QueryStmt(inputTables, limit)\n        } else {\n            return null\n        }\n    }\n\n    private fun parseRootQuery(ctx: TrinoSqlBaseParser.RootQueryContext): QueryStmt {\n        currentOptType = StatementType.SELECT\n        this.visitRootQuery(ctx)\n\n        val queryStmt = QueryStmt(inputTables, limit, offset)\n        queryStmt.functionNames.addAll(functionNames)\n        val querySql = source(ctx)\n        queryStmt.setSql(querySql)\n        return queryStmt\n    }\n\n    override fun visitCreateTableAsSelect(ctx: TrinoSqlBaseParser.CreateTableAsSelectContext): Statement? {\n        currentOptType = StatementType.CREATE_TABLE_AS_SELECT\n        val tableId = parseTableName(ctx.qualifiedName())\n        val queryStmt = parseRootQuery(ctx.rootQuery())\n        val createTable = CreateTableAsSelect(tableId, queryStmt)\n        createTable.lifeCycle = 7\n        return createTable\n    }\n\n    override fun visitDropTable(ctx: TrinoSqlBaseParser.DropTableContext): Statement? {\n        val tableId = parseTableName(ctx.qualifiedName())\n\n        val dropTable = DropTable(tableId)\n        dropTable.ifExists = ctx.EXISTS() != null\n        return dropTable\n    }\n\n    override fun visitInsertInto(ctx: TrinoSqlBaseParser.InsertIntoContext): Statement {\n        val tableId = parseTableName(ctx.qualifiedName())\n        val queryStmt = parseRootQuery(ctx.rootQuery())\n        val stmt = InsertTable(InsertMode.INTO, queryStmt, tableId)\n        return stmt\n    }\n\n    override fun visitDelete(ctx: TrinoSqlBaseParser.DeleteContext): Statement {\n        currentOptType = StatementType.DELETE\n        val tableId = parseTableName(ctx.qualifiedName())\n        if (ctx.whereClause() != null) {\n            super.visitWhereClause(ctx.whereClause())\n        }\n\n        return DeleteTable(tableId, inputTables)\n    }\n\n    override fun visitUpdate(ctx: TrinoSqlBaseParser.UpdateContext): Statement {\n        currentOptType = StatementType.UPDATE\n        val tableId = parseTableName(ctx.qualifiedName())\n        if (ctx.whereClause() != null) {\n            super.visitWhereClause(ctx.whereClause())\n        }\n\n        return UpdateTable(tableId, inputTables)\n    }\n\n    override fun visitMerge(ctx: TrinoSqlBaseParser.MergeContext): Statement {\n        currentOptType = StatementType.MERGE\n\n        val targetTable = parseTableName(ctx.qualifiedName())\n        val mergeTable = MergeTable(targetTable = targetTable)\n\n        // @TODO\n        mergeTable.inputTables = inputTables\n        return mergeTable\n    }\n\n    override fun visitExplain(ctx: TrinoSqlBaseParser.ExplainContext): Statement? {\n        return DefaultStatement(StatementType.EXPLAIN)\n    }\n\n    override fun visitQualifiedName(ctx: TrinoSqlBaseParser.QualifiedNameContext): Statement? {\n        if (!(ctx.parent is TrinoSqlBaseParser.TableNameContext)) {\n            return null\n        }\n\n        if (\n            currentOptType == StatementType.SELECT ||\n                currentOptType == StatementType.INSERT ||\n                currentOptType == StatementType.UPDATE ||\n                currentOptType == StatementType.DELETE ||\n                currentOptType == StatementType.MERGE ||\n                currentOptType == StatementType.CREATE_TABLE_AS_SELECT\n        ) {\n\n            val tableName = parseTableName(ctx)\n            inputTables.add(tableName)\n        }\n        return null\n    }\n\n    private fun parseTableName(ctx: TrinoSqlBaseParser.QualifiedNameContext): TableId {\n        val list = ctx.identifier()\n\n        var catalogName: String? = null\n        var databaseName: String? = null\n        val tableName =\n            if (list.size == 1) {\n                ctx.text\n            } else if (list.size == 2) {\n                val index = StringUtils.lastIndexOf(ctx.text, \".\")\n                databaseName = StringUtils.substring(ctx.text, 0, index)\n\n                StringUtils.substring(ctx.text, index + 1)\n            } else {\n                val items = StringUtils.split(ctx.text, \".\")\n                catalogName = items[0]\n                databaseName = items[1]\n                items[2]\n            }\n\n        return TableId(catalogName, databaseName, tableName)\n    }\n}\n"
  },
  {
    "path": "superior-trino-parser/src/main/kotlin/io/github/melin/superior/parser/trino/TrinoSqlHelper.kt",
    "content": "package io.github.melin.superior.parser.trino\n\nimport com.github.melin.superior.sql.parser.util.CommonUtils\nimport io.github.melin.superior.common.antlr4.AntlrCaches\nimport io.github.melin.superior.common.antlr4.ParseErrorListener\nimport io.github.melin.superior.common.antlr4.ParseException\nimport io.github.melin.superior.common.relational.Statement\nimport io.github.melin.superior.parser.spark.AbstractSqlParser\nimport io.github.melin.superior.parser.trino.antlr4.TrinoSqlBaseBaseVisitor\nimport io.github.melin.superior.parser.trino.antlr4.TrinoSqlBaseLexer\nimport io.github.melin.superior.parser.trino.antlr4.TrinoSqlBaseParser\nimport org.antlr.v4.runtime.CharStreams\nimport org.antlr.v4.runtime.CommonTokenStream\nimport org.antlr.v4.runtime.atn.PredictionMode\nimport org.antlr.v4.runtime.misc.ParseCancellationException\nimport org.apache.commons.lang3.StringUtils\n\n/** Created by libinsong on 2018/1/10. */\nobject TrinoSqlHelper {\n\n    @JvmStatic\n    fun sqlKeywords(): List<String> {\n        val keywords = hashSetOf<String>()\n        (0 until TrinoSqlBaseLexer.VOCABULARY.maxTokenType).forEach { idx ->\n            val name = TrinoSqlBaseLexer.VOCABULARY.getLiteralName(idx)\n            if (name != null) {\n                val matchResult = CommonUtils.KEYWORD_REGEX.find(name)\n                if (matchResult != null) {\n                    keywords.add(matchResult.groupValues.get(1))\n                }\n            }\n        }\n\n        return keywords.sorted()\n    }\n\n    @JvmStatic\n    fun parseStatement(command: String): Statement {\n        val statements = this.parseMultiStatement(command)\n        if (statements.size != 1) {\n            throw IllegalStateException(\"only parser one sql, sql count: \" + statements.size)\n        } else {\n            return statements.get(0)\n        }\n    }\n\n    @JvmStatic\n    fun parseMultiStatement(command: String): List<Statement> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = TrinoSqlAntlr4Visitor(false, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSqlStatements()\n    }\n\n    @JvmStatic\n    fun splitSql(command: String): List<String> {\n        val trimCmd = StringUtils.trim(command)\n        val sqlVisitor = TrinoSqlAntlr4Visitor(true, trimCmd)\n        innerParseStatement(trimCmd, sqlVisitor)\n        return sqlVisitor.getSplitSqls()\n    }\n\n    @JvmStatic\n    fun checkSqlSyntax(command: String) {\n        val sqlVisitor = TrinoSqlBaseBaseVisitor<Statement>()\n        innerParseStatement(command, sqlVisitor)\n    }\n\n    private fun innerParseStatement(command: String, sqlVisitor: TrinoSqlBaseBaseVisitor<Statement>) {\n        val charStream = CaseInsensitiveStream(CharStreams.fromString(command))\n        val lexer = TrinoSqlBaseLexer(charStream)\n        lexer.removeErrorListeners()\n        lexer.addErrorListener(ParseErrorListener())\n\n        val tokenStream = CommonTokenStream(lexer)\n        val parser = TrinoSqlBaseParser(tokenStream)\n        AbstractSqlParser.installCaches(parser)\n        parser.removeErrorListeners()\n        parser.addErrorListener(ParseErrorListener())\n        parser.interpreter.predictionMode = PredictionMode.SLL\n\n        try {\n            try {\n                // first, try parsing with potentially faster SLL mode\n                sqlVisitor.visit(parser.sqlStatements())\n            } catch (e: ParseCancellationException) {\n                tokenStream.seek(0) // rewind input stream\n                parser.reset()\n\n                // Try Again.\n                parser.interpreter.predictionMode = PredictionMode.LL\n                sqlVisitor.visit(parser.sqlStatements())\n            }\n        } catch (e: ParseException) {\n            if (StringUtils.isNotBlank(e.command)) {\n                throw e\n            } else {\n                throw e.withCommand(command)\n            }\n        } finally {\n            val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)\n            if (releaseAntlrCache == null || \"true\".equals(releaseAntlrCache)) {\n                AbstractSqlParser.refreshParserCaches()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "superior-trino-parser/src/test/kotlin/io/github/melin/superior/parser/trino/TrinoSqlParserTest.kt",
    "content": "package io.github.melin.superior.parser.trino\n\nimport io.github.melin.superior.common.StatementType\nimport io.github.melin.superior.common.relational.create.CreateTableAsSelect\nimport io.github.melin.superior.common.relational.dml.DeleteTable\nimport io.github.melin.superior.common.relational.dml.InsertTable\nimport io.github.melin.superior.common.relational.dml.QueryStmt\nimport io.github.melin.superior.common.relational.drop.DropTable\nimport org.junit.Assert\nimport org.junit.Test\n\n/** Created by libinsong on 2018/1/10. */\nclass TrinoSqlParserTest {\n\n    @Test\n    fun queryTest0() {\n        val sql =\n            \"\"\"\n            select a.* from datacompute1.datacompute.dc_job a left join datacompute1.datacompute.dc_job_scheduler b on a.id=b.job_id\n        \"\"\"\n                .trimIndent()\n\n        val statement = TrinoSqlHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(2, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryTest1() {\n        val sql =\n            \"\"\"\n            SELECT COUNT(app_name) AS \"应用名\" FROM (SELECT * FROM ops.dwd_app_to_container_wt \n            WHERE ds=date_format(CURRENT_DATE - interval '1' DAY, \"%Y%m%d\") ) tdbi_view\n        \"\"\"\n                .trimIndent()\n\n        val statement = TrinoSqlHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun queryLimitTest() {\n        val sql =\n            \"\"\"\n            select * from preso_table limit 10\n        \"\"\"\n                .trimIndent()\n\n        val statement = TrinoSqlHelper.parseStatement(sql)\n        if (statement is QueryStmt) {\n            Assert.assertEquals(StatementType.SELECT, statement.statementType)\n            Assert.assertEquals(1, statement.inputTables.size)\n            Assert.assertEquals(10, statement.limit)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun createTableSelectTest() {\n        val sql =\n            \"\"\"\n            create table dd_s_s as select * from bigdata.test_demo_test limit 1\n        \"\"\"\n                .trimIndent()\n\n        val statement = TrinoSqlHelper.parseStatement(sql)\n        if (statement is CreateTableAsSelect) {\n            Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)\n            Assert.assertEquals(\"dd_s_s\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.queryStmt.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun dropTableTest() {\n        val sql =\n            \"\"\"\n            drop table if exists bigdata.tdl_small_files_2\n        \"\"\"\n                .trimIndent()\n\n        val statement = TrinoSqlHelper.parseStatement(sql)\n        if (statement is DropTable) {\n            Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)\n            Assert.assertEquals(\"bigdata\", statement.tableId.schemaName)\n            Assert.assertEquals(\"tdl_small_files_2\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun insertTest() {\n        val sql =\n            \"\"\"\n            insert into orders select * from new_orders;\n        \"\"\"\n                .trimIndent()\n\n        val statement = TrinoSqlHelper.parseStatement(sql)\n        if (statement is InsertTable) {\n            Assert.assertEquals(StatementType.INSERT, statement.statementType)\n            Assert.assertEquals(\"orders\", statement.tableId.tableName)\n        } else {\n            Assert.fail()\n        }\n    }\n\n    @Test\n    fun deleteTest() {\n        val sql =\n            \"\"\"\n            DELETE FROM lineitem WHERE orderkey IN (SELECT orderkey FROM orders WHERE priority = 'LOW');\n        \"\"\"\n                .trimIndent()\n\n        val statement = TrinoSqlHelper.parseStatement(sql)\n        if (statement is DeleteTable) {\n            Assert.assertEquals(StatementType.DELETE, statement.statementType)\n            Assert.assertEquals(\"lineitem\", statement.tableId.tableName)\n            Assert.assertEquals(1, statement.inputTables.size)\n        } else {\n            Assert.fail()\n        }\n    }\n}\n"
  },
  {
    "path": "superior-trino-parser/src/test/resources/log4j2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Configuration>\n    <Appenders>\n        <Console name=\"Console\" target=\"SYSTEM_OUT\">\n            <PatternLayout\n                    pattern=\"%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable\" />\n        </Console>\n    </Appenders>\n\n    <Loggers>\n        <!-- LOG everything at INFO level -->\n        <Root level=\"INFO\">\n            <AppenderRef ref=\"Console\" />\n        </Root>\n    </Loggers>\n</Configuration>"
  }
]