Repository: melin/superior-sql-parser
Branch: branch-4.0
Commit: ca42eea29ca1
Files: 274
Total size: 2.4 MB
Directory structure:
gitextract_hvwwon62/
├── .gitignore
├── LICENSE
├── README.md
├── pom.xml
├── superior-appjar-parser/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── job/
│ │ │ └── antlr4/
│ │ │ ├── AppJarLexer.g4
│ │ │ └── AppJarParser.g4
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── appjar/
│ │ ├── AbstractJarParser.kt
│ │ ├── AppJarAntlr4Visitor.kt
│ │ ├── AppJarHelper.kt
│ │ └── AppJarInfo.kt
│ └── test/
│ ├── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── appjar/
│ │ └── AppJarParserTest.kt
│ └── resources/
│ └── log4j2.xml
├── superior-arithmetic-parser/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── antlr4/
│ │ │ └── arithmetic/
│ │ │ └── Arithmetic.g4
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── arithmetic/
│ │ ├── AbstractArithParser.kt
│ │ ├── ArithmeticAntlr4Visitor.kt
│ │ ├── ArithmeticHelper.kt
│ │ └── Data.kt
│ └── test/
│ ├── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── arithmetic/
│ │ └── ArithmetricParserTest.kt
│ └── resources/
│ └── log4j2.xml
├── superior-common-parser/
│ ├── pom.xml
│ └── src/
│ └── main/
│ ├── java/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── common/
│ │ └── antlr4/
│ │ ├── AntlrCaches.java
│ │ ├── Origin.java
│ │ ├── ParseErrorListener.java
│ │ ├── ParseException.java
│ │ ├── ParserUtils.java
│ │ └── UpperCaseCharStream.java
│ └── kotlin/
│ └── io/
│ └── github/
│ └── melin/
│ └── superior/
│ └── common/
│ ├── AlterActionType.kt
│ ├── PrivilegeType.kt
│ ├── SQLParserException.kt
│ ├── SqlType.kt
│ ├── StatementType.kt
│ ├── TableType.kt
│ ├── relational/
│ │ ├── AnalyzeTable.kt
│ │ ├── DefaultStatement.kt
│ │ ├── FunctionId.kt
│ │ ├── ProcedureId.kt
│ │ ├── SchemaId.kt
│ │ ├── Statement.kt
│ │ ├── TableId.kt
│ │ ├── abs/
│ │ │ ├── AbsDatabaseStatement.kt
│ │ │ └── AbsTableStatement.kt
│ │ ├── alter/
│ │ │ ├── AlterAction.kt
│ │ │ ├── AlterActions.kt
│ │ │ ├── AlterDatabase.kt
│ │ │ ├── AlterDatabaseActions.kt
│ │ │ ├── AlterMaterializedView.kt
│ │ │ ├── AlterTable.kt
│ │ │ ├── AlterView.kt
│ │ │ ├── DeltaAlterActions.kt
│ │ │ └── IcebergAlterActions.kt
│ │ ├── common/
│ │ │ ├── AddResourceStatement.kt
│ │ │ ├── CallProcedure.kt
│ │ │ ├── CancelExport.kt
│ │ │ ├── CommentStatement.kt
│ │ │ ├── DescModel.kt
│ │ │ ├── ListResourceStatement.kt
│ │ │ ├── ReSetStatement.kt
│ │ │ ├── RefreshMaterializedView.kt
│ │ │ ├── RemoveResourceStatement.kt
│ │ │ ├── SetStatement.kt
│ │ │ ├── ShowStatement.kt
│ │ │ ├── SyncStatement.kt
│ │ │ └── UseStatement.kt
│ │ ├── create/
│ │ │ ├── CreateCatalog.kt
│ │ │ ├── CreateDatabase.kt
│ │ │ ├── CreateFunction.kt
│ │ │ ├── CreateMaterializedView.kt
│ │ │ ├── CreateProcedure.kt
│ │ │ ├── CreateSchema.kt
│ │ │ ├── CreateTable.kt
│ │ │ ├── CreateTableAsSelect.kt
│ │ │ ├── CreateTableLike.kt
│ │ │ └── CreateView.kt
│ │ ├── delta/
│ │ │ ├── OptimizeTable.kt
│ │ │ └── VacuumTable.kt
│ │ ├── dml/
│ │ │ ├── DeleteTable.kt
│ │ │ ├── InsertFiles.kt
│ │ │ ├── InsertMode.kt
│ │ │ ├── InsertMultiTable.kt
│ │ │ ├── InsertTable.kt
│ │ │ ├── MergeTable.kt
│ │ │ ├── QueryStmt.kt
│ │ │ └── UpdateTable.kt
│ │ ├── drop/
│ │ │ ├── DropCatalog.kt
│ │ │ ├── DropDatabase.kt
│ │ │ ├── DropFunction.kt
│ │ │ ├── DropMaterializedView.kt
│ │ │ ├── DropProcedure.kt
│ │ │ ├── DropSchema.kt
│ │ │ ├── DropSequence.kt
│ │ │ ├── DropTable.kt
│ │ │ └── DropView.kt
│ │ ├── enums.kt
│ │ ├── io/
│ │ │ ├── AlterLoadTable.kt
│ │ │ ├── CancelLoadTable.kt
│ │ │ ├── ExportTable.kt
│ │ │ └── LoadTable.kt
│ │ └── table/
│ │ ├── ColumnRel.kt
│ │ ├── RepairTable.kt
│ │ └── TruncateTable.kt
│ ├── type/
│ │ ├── AbsDataTimeType.kt
│ │ ├── AbsNumericType.kt
│ │ ├── AbsStringType.kt
│ │ ├── AbsType.kt
│ │ └── Type.kt
│ └── util/
│ ├── CommonUtils.kt
│ └── DateUtils.kt
├── superior-dameng-parser/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── dameng/
│ │ │ └── antlr4/
│ │ │ ├── DmSqlLexer.g4
│ │ │ └── DmSqlParser.g4
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── dameng/
│ │ ├── AbstractSqlParser.kt
│ │ ├── DmSqlAntlr4Visitor.kt
│ │ └── DmSqlHelper.kt
│ └── test/
│ ├── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── dameng/
│ │ ├── DmSqlParserDdlTest.kt
│ │ ├── DmSqlParserDmlTest.kt
│ │ └── DmSqlProcedureParserTest.kt
│ └── resources/
│ ├── insert.sql
│ └── log4j2.xml
├── superior-flink-parser/
│ ├── README.md
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── flink/
│ │ │ └── antlr4/
│ │ │ ├── FlinkSqlLexer.g4
│ │ │ └── FlinkSqlParser.g4
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── flink/
│ │ ├── AbstractSqlParser.kt
│ │ ├── FlinkSqlAntlr4Visitor.kt
│ │ └── FlinkSqlHelper.kt
│ └── test/
│ ├── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── flink/
│ │ ├── FlinkCheckSql.kt
│ │ ├── FlinkSqlParserDdlTest.kt
│ │ └── FlinkSqlParserDmlTest.kt
│ └── resources/
│ └── log4j2.xml
├── superior-mysql-parser/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── mysql/
│ │ │ └── antlr4/
│ │ │ ├── MySqlLexer.g4
│ │ │ └── MySqlParser.g4
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── mysql/
│ │ ├── AbstractSqlParser.kt
│ │ ├── MySqlAntlr4Visitor.kt
│ │ ├── MySqlHelper.kt
│ │ └── type/
│ │ ├── JsonType.kt
│ │ ├── datetime.kt
│ │ ├── numeric.kt
│ │ └── string.kt
│ └── test/
│ ├── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── mysql/
│ │ ├── MySqlParserDdlTest.kt
│ │ ├── MySqlParserDmlTest.kt
│ │ └── MySqlProcedureParserTest.kt
│ └── resources/
│ └── log4j2.xml
├── superior-oracle-parser/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── oracle/
│ │ │ └── antlr4/
│ │ │ ├── OracleLexer.g4
│ │ │ └── OracleParser.g4
│ │ ├── java/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── oracle/
│ │ │ └── antlr4/
│ │ │ ├── OracleLexerBase.java
│ │ │ └── OracleParserBase.java
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── oracle/
│ │ ├── AbstractSqlParser.kt
│ │ ├── OracleSqlAntlr4Visitor.kt
│ │ └── OracleSqlHelper.kt
│ └── test/
│ ├── java/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── oracle/
│ │ ├── OracleProcessParserTest.kt
│ │ ├── OracleSqlParserDdlTest.kt
│ │ └── OracleSqlParserDmlTest.kt
│ └── resources/
│ ├── insert.sql
│ └── log4j2.xml
├── superior-postgres-parser/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── postgre/
│ │ │ └── antlr4/
│ │ │ ├── PostgreSqlLexer.g4
│ │ │ └── PostgreSqlParser.g4
│ │ ├── java/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── postgre/
│ │ │ └── antlr4/
│ │ │ ├── LexerDispatchingErrorListener.java
│ │ │ ├── ParserDispatchingErrorListener.java
│ │ │ ├── PostgreSqlLexerBase.java
│ │ │ └── PostgreSqlParserBase.java
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── postgre/
│ │ ├── AbstractSqlParser.kt
│ │ ├── PostgreSqlAntlr4Visitor.kt
│ │ ├── PostgreSqlHelper.kt
│ │ ├── relational/
│ │ │ └── CreatePartitionTable.kt
│ │ └── type/
│ │ ├── BooleanType.kt
│ │ ├── JsonType.kt
│ │ ├── datetime.kt
│ │ ├── numeric.kt
│ │ └── string.kt
│ └── test/
│ ├── java/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── postgre/
│ │ ├── PostgreSqlParserDdlTest.kt
│ │ ├── PostgreSqlParserDmlTest.kt
│ │ └── PostgreSqlProcessParserTest.kt
│ └── resources/
│ └── log4j2.xml
├── superior-presto-parser/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── presto/
│ │ │ └── antlr4/
│ │ │ └── PrestoSqlBase.g4
│ │ ├── java/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── presto/
│ │ │ └── CaseInsensitiveStream.java
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── presto/
│ │ ├── AbstractSqlParser.kt
│ │ ├── PrestoSqlAntlr4Visitor.kt
│ │ └── PrestoSqlHelper.kt
│ └── test/
│ ├── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── presto/
│ │ └── PrestoSqlParserTest.kt
│ └── resources/
│ └── log4j2.xml
├── superior-redshift-parser/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── redshift/
│ │ │ └── antlr4/
│ │ │ ├── RedshiftLexer.g4
│ │ │ └── RedshiftParser.g4
│ │ ├── java/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── redshift/
│ │ │ └── antlr4/
│ │ │ ├── LexerDispatchingErrorListener.java
│ │ │ ├── ParserDispatchingErrorListener.java
│ │ │ ├── RedshiftLexerBase.java
│ │ │ └── RedshiftParserBase.java
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── postgre/
│ │ ├── AbstractSqlParser.kt
│ │ ├── RedshiftSqlAntlr4Visitor.kt
│ │ ├── RedshiftSqlHelper.kt
│ │ ├── relational/
│ │ │ └── CreatePartitionTable.kt
│ │ └── type/
│ │ ├── BooleanType.kt
│ │ ├── JsonType.kt
│ │ ├── datetime.kt
│ │ ├── numeric.kt
│ │ └── string.kt
│ └── test/
│ ├── java/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── postgre/
│ │ ├── RedshiftSqlParserDdlTest.kt
│ │ ├── RedshiftSqlParserDmlTest.kt
│ │ └── RedshiftSqlProcessParserTest.kt
│ └── resources/
│ └── log4j2.xml
├── superior-spark-parser/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── spark/
│ │ │ └── antlr4/
│ │ │ ├── SparkSqlLexer.g4
│ │ │ ├── SparkSqlParser.g4
│ │ │ ├── SparkStreamSqlLexer.g4
│ │ │ └── SparkStreamSqlParser.g4
│ │ ├── java/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── spark/
│ │ │ └── SparkSqlPostProcessor.java
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── spark/
│ │ ├── AbstractSparkStreamSqlParser.kt
│ │ ├── AbstractSqlParser.kt
│ │ ├── SparkSqlAntlr4Visitor.kt
│ │ ├── SparkSqlHelper.kt
│ │ ├── SparkStreamSqlAntlr4Visitor.kt
│ │ ├── SparkStreamSqlHelper.kt
│ │ └── relational/
│ │ ├── CallHelp.kt
│ │ ├── CreateFileView.kt
│ │ ├── CreateTempViewUsing.kt
│ │ ├── DataTunnelExpr.kt
│ │ ├── DataTunnelHelp.kt
│ │ ├── DistCpExpr.kt
│ │ ├── LoadData.kt
│ │ ├── MergeFileData.kt
│ │ ├── RefreshStatement.kt
│ │ └── cache.kt
│ └── test/
│ ├── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── spark/
│ │ ├── DeltaSqlExtensionsTest.kt
│ │ ├── IcebergSqlExtensionsTest.kt
│ │ ├── SparkSqlParserTest.kt
│ │ └── SparkStreamSqlParserTest.kt
│ └── resources/
│ ├── demo.sql
│ └── log4j2.xml
├── superior-sqlserver-parser/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── sqlserver/
│ │ │ └── antlr4/
│ │ │ ├── SqlServerLexer.g4
│ │ │ └── SqlServerParser.g4
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── sqlserver/
│ │ ├── AbstractSqlParser.kt
│ │ ├── SqlServerAntlr4Visitor.kt
│ │ └── SqlServerHelper.kt
│ └── test/
│ ├── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── sqlserver/
│ │ ├── SqlServerParserDdlTest.kt
│ │ └── SqlServerParserDmlTest.kt
│ └── resources/
│ └── log4j2.xml
├── superior-starrocks-parser/
│ ├── pom.xml
│ └── src/
│ ├── main/
│ │ ├── antlr4/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── starrocks/
│ │ │ └── antlr4/
│ │ │ ├── StarRocksLexer.g4
│ │ │ └── StarRocksParser.g4
│ │ ├── java/
│ │ │ └── io/
│ │ │ └── github/
│ │ │ └── melin/
│ │ │ └── superior/
│ │ │ └── parser/
│ │ │ └── starrocks/
│ │ │ ├── NodePosition.java
│ │ │ ├── ParsingException.java
│ │ │ ├── PostProcessListener.java
│ │ │ └── SqlModeHelper.java
│ │ └── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── starrocks/
│ │ ├── AbstractSqlParser.kt
│ │ ├── StarRocksAntlr4Visitor.kt
│ │ ├── StarRocksHelper.kt
│ │ └── relational/
│ │ ├── AlterRoutineLoad.kt
│ │ ├── CancelRefreshMaterializedView.kt
│ │ ├── CreateRoutineLoad.kt
│ │ ├── DropTask.kt
│ │ ├── PauseRoutineLoad.kt
│ │ ├── ResumeRoutineLoad.kt
│ │ ├── StopRoutineLoad.kt
│ │ └── SubmitTask.kt
│ └── test/
│ ├── kotlin/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── starrocks/
│ │ ├── StarRocksSqlParserDdlTest.kt
│ │ ├── StarRocksSqlParserDmlTest.kt
│ │ ├── StarRocksSqlParserLoadAndExportTest.kt
│ │ └── StarRocksSqlParserRoutineLoadTest.kt
│ └── resources/
│ └── log4j2.xml
└── superior-trino-parser/
├── pom.xml
└── src/
├── main/
│ ├── antlr4/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── trino/
│ │ └── antlr4/
│ │ └── TrinoSqlBase.g4
│ ├── java/
│ │ └── io/
│ │ └── github/
│ │ └── melin/
│ │ └── superior/
│ │ └── parser/
│ │ └── trino/
│ │ └── CaseInsensitiveStream.java
│ └── kotlin/
│ └── io/
│ └── github/
│ └── melin/
│ └── superior/
│ └── parser/
│ └── trino/
│ ├── AbstractSqlParser.kt
│ ├── TrinoSqlAntlr4Visitor.kt
│ └── TrinoSqlHelper.kt
└── test/
├── kotlin/
│ └── io/
│ └── github/
│ └── melin/
│ └── superior/
│ └── parser/
│ └── trino/
│ └── TrinoSqlParserTest.kt
└── resources/
└── log4j2.xml
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Created by .ignore support plugin (hsz.mobi)
target
.idea
superior-sql-parser.iml
metastore_db
derby.log
.DS_Store
gen
*.tokens
*.iml
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2022 Ververica Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
## 介绍
基于 antlr4 的多种数据库SQL解析器,获取SQL中元数据,可用于数据平台产品中的多个场景:ddl语句提取元数据、sql 权限校验、表级血缘、sql语法校验等场景。支持spark、flink、gauss、starrocks、Oracle、MYSQL、Postgresql,sqlserver,、db2等
```xml
io.github.melin.superior
superior-[spark|presto|mysql|oracle|...]-parser
4.0.22
```
## Build
```
export GPG_TTY=$(tty)
mvn clean deploy -Pdeploy
```
### API
每个数据库SQL 提供 Helper 类,Helper 方法提供四个方法:
```agsl
1. parseStatement(String sql) // 解析单个完整sql
a. ddl: 获取ddl 详细信息。例如:数据库执行完ddl以后,解析ddl,获取到相关信息,同步到元数据信息。
b. dml: 获取sql中使用到的表,用于构建表级血缘,或者校验表权限。
2. parseMultiStatement(String sql) // 解析多个完整sql,支持空格、换行、分号分隔
3. splitSql(String sql) // sql 文本包含多个完整sql,方法用于分隔sql语句,支持空格、换行、分号分隔
4. checkSqlSyntax(String sql) // 验证单个完整sql语法是否正确
5. sqlKeywords() // 获取sql 关键字,主要用于sql editor 关键字提示
```
## Example
```kotlin
// Spark SQL
val sql = "select bzdys, bzhyyh, bzdy, week, round((bzdy-bzdys)*100/bzdys, 2) " +
"from (select lag(bzdy) over (order by week) bzdys, bzhyyh, bzdy, week " +
"from (select count(distinct partner_code) bzhyyh, count(1) bzdy, week from tdl_dt2x_table)) limit 111"
val statement = SparkSQLHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(1, statement.inputTables.size)
Assert.assertEquals("tdl_dt2x_table", statement.inputTables.get(0).tableName)
Assert.assertEquals(111, statement.limit)
} else {
Assert.fail()
}
// Spark Jar
val sql = """
set spark.shuffle.compress=true;set spark.rdd.compress=true;
set spark.driver.maxResultSize=3g;
set spark.serializer=org.apache.spark.serializer.KryoSerializer;
set spark.kryoserializer.buffer.max=1024m;
set spark.kryoserializer.buffer=256m;
set spark.network.timeout=300s;
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
""";
val statementDatas = JobTaskHelper.parseStatement(sql)
Assert.assertEquals(8, statementDatas.size)
var statementData = statementDatas.get(7)
var statement = statementData.statement
if (statement is JobData) {
Assert.assertEquals(StatementType.JOB, statement.statementType)
Assert.assertEquals("createHfile-1.2-SNAPSHOT-jar-with-dependencies.jar", statement.resourceName)
Assert.assertEquals("imei_test.euSaveHBase", statement.className)
Assert.assertEquals("/xiaoyong.fu/sh/mobile/loan", statement.params?.get(5))
Assert.assertEquals("400", statement.params?.get(6))
Assert.assertEquals("%7B%22job_type%22=", statement.params?.get(7))
Assert.assertEquals("--jar", statement.params?.get(8))
} else {
Assert.fail()
}
// MySQL
val sql = "insert into bigdata.user select * from users a left outer join address b on a.address_id = b.id"
val statement = MySQLHelper.parseStatement(sql)
if(statement is QueryStmt) {
Assert.assertEquals(StatementType.INSERT_SELECT, statement.statementType)
Assert.assertEquals("bigdata", statement.outpuTables.get(0).databaseName)
Assert.assertEquals("user", statement.outpuTables.get(0).tableName)
Assert.assertEquals(2, statement.inputTables.size)
} else {
Assert.fail()
}
// Postgres
val sql = """
select a.* from datacompute1.datacompute.dc_job a left join datacompute1.datacompute.dc_job_scheduler b on a.id=b.job_id
""".trimIndent()
val statement = PostgreSQLHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(2, statement.inputTables.size)
} else {
Assert.fail()
}
```
## 支持数据库
1. [MySQL](https://github.com/antlr/grammars-v4/tree/master/sql/mysql)
2. [PrestoSQL](https://github.com/prestosql/presto/tree/master/presto-parser/src/main/antlr4/io/prestosql/sql/parser)
3. [PostgreSQL](https://github.com/pgcodekeeper/pgcodekeeper/tree/master/apgdiff/antlr-src)
4. [Spark 3.x](https://github.com/apache/spark/tree/master/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser)
5. [Sql Server](https://github.com/antlr/grammars-v4/tree/master/sql/tsql)
6. [StarRocks](https://github.com/StarRocks/starrocks/tree/main/fe/fe-core/src/main/java/com/starrocks/sql/parser)
7. [Oracle](https://github.com/antlr/grammars-v4/tree/master/sql/plsql)
8. [OceanBase](https://github.com/oceanbase/odc/tree/main/libs/ob-sql-parser)
9. [Flink SQL / Flink CDC SQL](https://github.com/DTStack/dt-sql-parser/tree/main/src/grammar/flinksql)
## 相关项目
1. https://gitee.com/melin/bee
2. https://github.com/melin/sqlflow/ 字段血缘解析
3. https://github.com/melin/superior-sql-formatter spark sql 代码格式化
4. https://github.com/melin/datatunnel spark 数据同步工具
5. https://github.com/melin/flink-jobserver
6. https://github.com/melin/spark-jobserver
================================================
FILE: pom.xml
================================================
4.0.0
io.github.melin.superior
superior-sql-parser
4.0.23
pom
Superior SQL Parser
Superior SQL Parser
superior-common-parser
superior-arithmetic-parser
superior-appjar-parser
superior-spark-parser
superior-mysql-parser
superior-postgres-parser
superior-trino-parser
superior-presto-parser
superior-sqlserver-parser
superior-flink-parser
superior-oracle-parser
superior-dameng-parser
superior-starrocks-parser
superior-redshift-parser
8
8
UTF-8
true
2.3.20
4.9.3
2.0.17
2.25.3
3.20.0
2.21.0
org.antlr
antlr4-runtime
${antlr4.version}
org.jetbrains.kotlin
*
org.jetbrains.kotlin
kotlin-stdlib
${kotlin.version}
org.apache.commons
commons-lang3
${commons-lang3.version}
com.google.guava
guava
33.4.0-jre
provided
junit
junit
4.13.2
test
commons-io
commons-io
${commons-io.version}
test
org.slf4j
slf4j-api
${slf4j.version}
org.apache.logging.log4j
log4j-core
${log4j.version}
test
org.apache.logging.log4j
log4j-slf4j-impl
${log4j.version}
test
org.apache.maven.plugins
maven-javadoc-plugin
3.12.0
true
1024
UTF-8
protected
true
false
none
bundle-sources
jar
package
org.apache.maven.plugins
maven-surefire-plugin
3.5.4
org.jetbrains.kotlin
kotlin-maven-plugin
${kotlin.version}
true
compile
compile
process-sources
${project.basedir}/src/main/kotlin
${project.basedir}/src/main/java
${project.build.directory}/generated-sources/antlr4
test-compile
test-compile
${project.basedir}/src/test/kotlin
${project.basedir}/src/test/java
org.apache.maven.plugins
maven-compiler-plugin
1.8
1.8
UTF-8
default-compile
none
default-testCompile
none
java-compile
compile
compile
java-test-compile
testCompile
test-compile
org.antlr
antlr4-maven-plugin
${antlr4.version}
true
antlr
antlr4
generate-sources
org.apache.maven.plugins
maven-release-plugin
forked-path
false
-Psonatype-oss-release
org.apache.maven.plugins
maven-source-plugin
3.4.0
true
true
true
attach-sources
jar
deploy
org.apache.maven.plugins
maven-gpg-plugin
sign-artifacts
sign
verify
org.sonatype.central
central-publishing-maven-plugin
0.10.0
true
superior-sql-parser-${project.version}
central
true
https://github.com/melin/superior-sql-parser
The Apache Software License, Version 2.0
http://www.apache.org/licenses/LICENSE-2.0.txt
repo
melin
libinsong1204@gmail.com
https://github.com/melin/superior-sql-parser
scm:git:https://github.com/melin/superior-sql-parser.git
scm:git:https://github.com/melin/superior-sql-parser.git
https://github.com/melin/superior-sql-parser
gitee
https://github.com/melin/superior-sql-parser/issues
================================================
FILE: superior-appjar-parser/pom.xml
================================================
4.0.0
io.github.melin.superior
superior-sql-parser
4.0.23
superior-appjar-parser
superior-appjar-parser
io.github.melin.superior
superior-common-parser
${project.version}
================================================
FILE: superior-appjar-parser/src/main/antlr4/io/github/melin/superior/parser/job/antlr4/AppJarLexer.g4
================================================
lexer grammar AppJarLexer;
channels { DCSTREAMCOMMENT, ERRORCHANNEL }
// SKIP
SPACE: [ \t\r\n]+ -> channel(HIDDEN);
SPEC_MYSQL_COMMENT: '/*!' .+? '*/' -> channel(DCSTREAMCOMMENT);
COMMENT_INPUT: '/*' .*? '*/' -> channel(HIDDEN);
LINE_COMMENT: (
('-- ' | '#') ~[\r\n]* ('\r'? '\n' | EOF)
| '--' ('\r'? '\n' | EOF)
) -> channel(HIDDEN);
SET: 'SET';
RESET: 'RESET';
STAR: '*';
DIVIDE: '/';
MODULE: '%';
PLUS: '+';
MINUS: '-';
// Operators. Comparation
EQUAL_SYMBOL: '=';
GREATER_SYMBOL: '>';
LESS_SYMBOL: '<';
EXCLAMATION_SYMBOL: '!';
// Operators. Bit
BIT_NOT_OP: '~';
BIT_OR_OP: '|';
BIT_AND_OP: '&';
BIT_XOR_OP: '^';
// Constructors symbols
DOT: '.';
LR_BRACKET: '(';
RR_BRACKET: ')';
COMMA: ',';
SEMI: ';';
DOT_ID: '.' ID_LITERAL;
ID: ID_LITERAL;
REVERSE_QUOTE_ID: '`' ~'`'+ '`';
STRING_LITERAL: DQUOTA_STRING | SQUOTA_STRING;
fragment ID_LITERAL: [A-Z_$0-9,:-]*;
fragment DQUOTA_STRING: '"' ( '\\'. | '""' | ~('"'| '\\') )* '"';
fragment SQUOTA_STRING: '\'' ('\\'. | '\'\'' | ~('\'' | '\\'))* '\'';
ERROR_RECONGNIGION: . -> channel(ERRORCHANNEL);
================================================
FILE: superior-appjar-parser/src/main/antlr4/io/github/melin/superior/parser/job/antlr4/AppJarParser.g4
================================================
parser grammar AppJarParser;
options { tokenVocab=AppJarLexer; }
rootx
: jobTasks? EOF
;
jobTasks
: (jobTask SEMI | emptyStatement)*
(jobTask (SEMI)? | emptyStatement)
;
jobTask
: setStatement | resetStatement | jobStatement
;
jobStatement
: resourceNameExpr classNameExpr paramsExpr?
;
resourceNameExpr
: ID (DOT_ID)*
| fileDir
;
classNameExpr
: ID (DOT_ID)*
;
paramsExpr
: paramExpr (paramExpr)*
;
paramExpr
: ID (DOT_ID)*
| fileDir
| ID DOT_ID* ('/' '/'? ID DOT_ID*)*
| STRING_LITERAL
;
fileDir
: '/' ID DOT_ID* ('/' (ID DOT_ID* | '*'))* '/'?
;
setStatement
: SET keyExpr EQUAL_SYMBOL value=valueExpr
;
resetStatement
: RESET keyExpr
;
keyExpr
: ID (DOT_ID)*
;
valueExpr
: word (word)*
;
word
: ID
| DOT_ID | SET | RESET
| STAR | DIVIDE | MODULE | PLUS | MINUS
| EQUAL_SYMBOL | GREATER_SYMBOL | LESS_SYMBOL | EXCLAMATION_SYMBOL
| BIT_NOT_OP | BIT_OR_OP | BIT_AND_OP | BIT_XOR_OP
| LR_BRACKET | RR_BRACKET | COMMA
| STRING_LITERAL
;
emptyStatement
: SEMI
;
================================================
FILE: superior-appjar-parser/src/main/kotlin/io/github/melin/superior/parser/appjar/AbstractJarParser.kt
================================================
package io.github.melin.superior.parser.appjar
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.parser.job.antlr4.AppJarParser
import java.util.concurrent.atomic.AtomicReference
object AbstractJarParser {
private val parserCaches = AtomicReference(AntlrCaches(AppJarParser._ATN))
/**
* Install the parser caches into the given parser.
*
* This method should be called before parsing any input.
*/
fun installCaches(parser: AppJarParser): Unit = parserCaches.get().installCaches(parser)
/**
* Drop the existing parser caches and create a new one.
*
* ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can
* consume a lot of memory depending on the input seen so far.
*
* This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL
* inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.
*/
fun refreshParserCaches() {
parserCaches.set(AntlrCaches(AppJarParser._ATN))
}
}
================================================
FILE: superior-appjar-parser/src/main/kotlin/io/github/melin/superior/parser/appjar/AppJarAntlr4Visitor.kt
================================================
package io.github.melin.superior.parser.appjar
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.antlr4.ParserUtils.source
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.common.relational.common.ReSetStatement
import io.github.melin.superior.common.relational.common.SetStatement
import io.github.melin.superior.parser.job.antlr4.AppJarParser
import io.github.melin.superior.parser.job.antlr4.AppJarParserBaseVisitor
import org.apache.commons.lang3.StringUtils
/** Created by binsong.li on 2018/3/31 下午1:44 */
class AppJarAntlr4Visitor : AppJarParserBaseVisitor() {
private var command: String? = null
private val jobStmts = ArrayList()
override fun visitJobTask(ctx: AppJarParser.JobTaskContext): Statement {
val jobStmt = super.visitJobTask(ctx)
val sql = source(ctx)
jobStmt.setSql(sql)
jobStmts.add(jobStmt)
return jobStmt
}
override fun visitJobStatement(ctx: AppJarParser.JobStatementContext): Statement {
val resourceName = ctx.resourceNameExpr().text
val className = ctx.classNameExpr().text
val params: ArrayList = arrayListOf()
if (ctx.paramsExpr() != null) {
ctx.paramsExpr().children.forEach { item ->
val param = item as AppJarParser.ParamExprContext
var value = source(param)
if (StringUtils.startsWith(value, "/")) { // 解决连续多个文件路径,不能正确解析
value = replaceWhitespace(value)
params.addAll(StringUtils.split(value, " "))
} else {
value = CommonUtils.cleanQuote(value)
params.add(value)
}
}
}
return AppJarInfo(resourceName, className, params)
}
override fun visitSetStatement(ctx: AppJarParser.SetStatementContext): Statement {
val key = ctx.keyExpr().text
val value = CommonUtils.cleanQuote(source(ctx.value))
return SetStatement(key, value)
}
override fun visitResetStatement(ctx: AppJarParser.ResetStatementContext): Statement {
val key = ctx.keyExpr().text
return ReSetStatement(key)
}
private fun replaceWhitespace(str: String): String {
val len = str.length
if (len > 0) {
val dest = CharArray(len)
var destPos = 0
for (i in 0 until len) {
val c = str[i]
if (!Character.isWhitespace(c)) {
dest[destPos++] = c
} else {
dest[destPos++] = ' '
}
}
return String(dest, 0, destPos)
}
return str
}
fun getJobStmts(): ArrayList {
return jobStmts
}
fun setCommand(command: String) {
this.command = command
}
}
================================================
FILE: superior-appjar-parser/src/main/kotlin/io/github/melin/superior/parser/appjar/AppJarHelper.kt
================================================
package io.github.melin.superior.parser.appjar
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.antlr4.AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING
import io.github.melin.superior.common.antlr4.ParseErrorListener
import io.github.melin.superior.common.antlr4.ParseException
import io.github.melin.superior.common.antlr4.UpperCaseCharStream
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.parser.job.antlr4.AppJarLexer
import io.github.melin.superior.parser.job.antlr4.AppJarParser
import org.antlr.v4.runtime.CharStreams
import org.antlr.v4.runtime.CommonTokenStream
import org.antlr.v4.runtime.atn.PredictionMode
import org.antlr.v4.runtime.misc.ParseCancellationException
import org.apache.commons.lang3.StringUtils
/** Created by binsong.li on 2018/3/31 下午1:47 */
object AppJarHelper {
@JvmStatic
fun sqlKeywords(): List {
val keywords = hashSetOf()
(0 until AppJarLexer.VOCABULARY.maxTokenType).forEach { idx ->
val name = AppJarLexer.VOCABULARY.getLiteralName(idx)
if (name != null) {
val matchResult = CommonUtils.KEYWORD_REGEX.find(name)
if (matchResult != null) {
keywords.add(matchResult.groupValues.get(1))
}
}
}
return keywords.sorted()
}
@JvmStatic
fun parseStatement(command: String): ArrayList {
val trimCmd = StringUtils.trim(command)
val charStream = UpperCaseCharStream(CharStreams.fromString(trimCmd))
val lexer = AppJarLexer(charStream)
lexer.removeErrorListeners()
lexer.addErrorListener(ParseErrorListener())
val tokenStream = CommonTokenStream(lexer)
val parser = AppJarParser(tokenStream)
AbstractJarParser.installCaches(parser)
parser.removeErrorListeners()
parser.addErrorListener(ParseErrorListener())
parser.interpreter.predictionMode = PredictionMode.SLL
val cmdVisitor = AppJarAntlr4Visitor()
cmdVisitor.setCommand(trimCmd)
try {
try {
// first, try parsing with potentially faster SLL mode
cmdVisitor.visit(parser.jobTasks())
return cmdVisitor.getJobStmts()
} catch (e: ParseCancellationException) {
tokenStream.seek(0) // rewind input stream
parser.reset()
// Try Again.
parser.interpreter.predictionMode = PredictionMode.LL
cmdVisitor.visit(parser.jobTasks())
return cmdVisitor.getJobStmts()
}
} catch (e: ParseException) {
if (StringUtils.isNotBlank(e.command)) {
throw e
} else {
throw e.withCommand(trimCmd)
}
} finally {
val releaseAntlrCache = System.getenv(RELEASE_ANTLR_CACHE_AFTER_PARSING)
if (releaseAntlrCache == null || "true".equals(releaseAntlrCache)) {
AbstractJarParser.refreshParserCaches()
}
}
}
}
================================================
FILE: superior-appjar-parser/src/main/kotlin/io/github/melin/superior/parser/appjar/AppJarInfo.kt
================================================
package io.github.melin.superior.parser.appjar
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class AppJarInfo(val resourceName: String, val className: String, val params: List?) : Statement() {
override val statementType = StatementType.APP_JAR
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
}
================================================
FILE: superior-appjar-parser/src/test/kotlin/io/github/melin/superior/parser/appjar/AppJarParserTest.kt
================================================
package io.github.melin.superior.parser.appjar
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.common.ReSetStatement
import io.github.melin.superior.common.relational.common.SetStatement
import org.junit.Assert
import org.junit.Test
/** Created by binsong.li on 2018/3/31 下午1:59 */
class AppJarParserTest {
@Test
fun setConfigTest1() {
val sql =
"""
set flink.test = 'hello world';
set flink.test = setsd,sd,resr;
set flink.test = hello world;
set flink.test = hello-world;
set flink.test = hello $\{usename} test;
#set flink.test = hello comment;
set flink.test = hello 'test' world;
set flink.test = hello "test" world;
set flink.test = hdfs://user/hive;
set flink.test = 12,12;
set flink.test = 3.45;
set flink.test = ibdex.json;
reset flink.test;
set flink.test = dw.eset_sdfe_sd;
set flink.test = demo.test;
set flink.test = dsd(id)%=2;
tet_test-demo_1.23-sdfd.jar com.example.Demo1 param1 param2 'hello \n world'
'hdfs://user/hive'
'{"user": "binsong.li",
address: "hangzhou"
}'
/user/jars/*
--jars /user/jars/flink.jar
"""
val statements = AppJarHelper.parseStatement(sql)
Assert.assertEquals(16, statements.size)
var statement = statements.get(0)
if (statement is SetStatement) {
Assert.assertEquals(StatementType.SET, statement.statementType)
Assert.assertEquals("flink.test", statement.key)
Assert.assertEquals("hello world", statement.value)
} else {
Assert.fail()
}
var setCount = 0
statements.filter { it.statementType == StatementType.SET }.forEach { setCount = setCount + 1 }
Assert.assertEquals(14, setCount)
statement = statements.get(11)
if (statement is ReSetStatement) {
Assert.assertEquals(StatementType.RESET, statement.statementType)
Assert.assertEquals("flink.test", statement.key)
} else {
Assert.fail()
}
statement = statements.get(15)
if (statement is AppJarInfo) {
Assert.assertEquals(StatementType.APP_JAR, statement.statementType)
Assert.assertEquals("tet_test-demo_1.23-sdfd.jar", statement.resourceName)
Assert.assertEquals("com.example.Demo1", statement.className)
Assert.assertEquals(8, statement.params?.size)
Assert.assertEquals("/user/jars/*", statement.params?.get(5))
} else {
Assert.fail()
}
}
@Test
fun setConfigTest2() {
val sql = "demo.jar com.example.Demo 'hello \"test\" world' param2 \n param3"
val statementDatas = AppJarHelper.parseStatement(sql)
Assert.assertEquals(1, statementDatas.size)
val statement = statementDatas.get(0)
if (statement is AppJarInfo) {
Assert.assertEquals(StatementType.APP_JAR, statement.statementType)
Assert.assertEquals("demo.jar", statement.resourceName)
Assert.assertEquals("com.example.Demo", statement.className)
Assert.assertEquals(3, statement.params?.size)
Assert.assertEquals("hello \"test\" world", statement.params?.get(0))
Assert.assertEquals("param3", statement.params?.get(2))
} else {
Assert.fail()
}
}
@Test
fun setConfigTest3() {
val sql =
"""
set spark.yarn.queue=newoffline;
set spark.sql.autoBroadcastJoinThreshold=40485760;
set spark.executor.memory=8g;
set spark.sql.hive.convertMetastoreParquet=true ;
set spark.driver.maxResultSize=4g;
set spark.driver.memory=10g;
set spark.psi.ds=20180312;
set spark.psi.dstTable=dw.index_psi_dt;
set spark.psi.dims=idnumber;
set spark.psi.num=0;
set spark.psi.parNum=2;
set spark.indexPSI.type=2;
set spark.metrics.indexFile=index-mobile.json;
psi_new_calculate_metrics-1.1-SNAPSHOT-jar-with-dependencies.jar com.example.dw.psi.StartDCJob 1,3,sd,qw
"""
val statementDatas = AppJarHelper.parseStatement(sql)
Assert.assertEquals(14, statementDatas.size)
val statement = statementDatas.get(13)
if (statement is AppJarInfo) {
Assert.assertEquals(StatementType.APP_JAR, statement.statementType)
Assert.assertEquals(
"psi_new_calculate_metrics-1.1-SNAPSHOT-jar-with-dependencies.jar",
statement.resourceName
)
Assert.assertEquals("com.example.dw.psi.StartDCJob", statement.className)
Assert.assertEquals("1,3,sd,qw", statement.params?.get(0))
} else {
Assert.fail()
}
}
@Test
fun setConfigTest4() {
val sql =
"""
set spark.yarn.queue=newoffline;
set spark.dynamicAllocation.maxExecutors=100;
set spark.driver.maxResultSize=30g;
set spark.driver.memory=15g;
set spark.executor.instances=80;
set spark.executor.cores=5;
set spark.executor.memory=30g;
set spark.sql.shuffle.partitions=5000;
set spark.shuffle.io.maxRetries=60;
set spark.shuffle.io.retryWait=60s;
set spark.metrics.indexFile=index-mobile.json;
set spark.metrics.indexInputTable=dw.dwa_mobile_model_dt;
set spark.metrics.indexOutputTable=dw.app_mdl_mobile_index_dt;
set spark.metrics.indexWaitFullPartition=true;
set spark.metrics.indexHashWhere=abs(hash(mobile))%4=3;
new_calculate_metrics-100-SNAPSHOT-jar-with-dependencies.jar com.example.dw.index.StartDCJob IndexOffline 2018-03-18
"""
val statementDatas = AppJarHelper.parseStatement(sql)
Assert.assertEquals(16, statementDatas.size)
val statement = statementDatas.get(15)
if (statement is AppJarInfo) {
Assert.assertEquals(StatementType.APP_JAR, statement.statementType)
Assert.assertEquals("new_calculate_metrics-100-SNAPSHOT-jar-with-dependencies.jar", statement.resourceName)
Assert.assertEquals("com.example.dw.index.StartDCJob", statement.className)
Assert.assertEquals("2018-03-18", statement.params?.get(1))
} else {
Assert.fail()
}
}
@Test
fun setConfigTest5() {
val sql =
"""
set spark.shuffle.compress=true;set spark.rdd.compress=true;
set spark.driver.maxResultSize=3g;
set spark.serializer=org.apache.spark.serializer.KryoSerializer;
set spark.kryoserializer.buffer.max=1024m;
set spark.kryoserializer.buffer=256m;
set spark.network.timeout=300s;
createHfile-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
"""
val statementDatas = AppJarHelper.parseStatement(sql)
Assert.assertEquals(8, statementDatas.size)
val statement = statementDatas.get(7)
if (statement is AppJarInfo) {
Assert.assertEquals(StatementType.APP_JAR, statement.statementType)
Assert.assertEquals("createHfile-1.2-SNAPSHOT-jar-with-dependencies.jar", statement.resourceName)
Assert.assertEquals("imei_test.euSaveHBase", statement.className)
Assert.assertEquals("/xiaoyong.fu/sh/mobile/loan", statement.params?.get(5))
Assert.assertEquals("400", statement.params?.get(6))
Assert.assertEquals("%7B%22job_type%22=", statement.params?.get(7))
Assert.assertEquals("--jar", statement.params?.get(8))
} else {
Assert.fail()
}
}
@Test
fun setConfigTest6() {
val sql =
"""
set spark.toMysql.url=jdbc:mysql://192.168.40.110:3306/data_quality;set spark.toMysql.user=dq;
set spark.toMysql.password=0nlpSvpgC5leeKuw;
set spark.screenJob.screenType=3;
set spark.screenJob.test=true;
set spark.screenTool.srcTable=default.activity_flat;
set spark.toMysql.tableName=province;
set spark.toMysql.field=creditProvinceAmountJson,creditForeignAmount,creditCityAmountJson,zhejiangFraud,fraudProvinceAmountJson;
province-1.0-SNAPSHOT-jar-with-dependencies.jar com.example.screen_dc.ScreenJob /xiaoyong.fu/2017-22-03/sh/mobile/loan/ --write-private-test;
province-1.0-SNAPSHOT-jar-with-dependencies.jar com.example.screen_dc.ScreenJob /xiaoyong.fu/2017-22-03/sh/mobile/loan/ --write-private-test
"""
val statementDatas = AppJarHelper.parseStatement(sql)
Assert.assertEquals(10, statementDatas.size)
val statement = statementDatas.get(9)
if (statement is AppJarInfo) {
Assert.assertEquals(StatementType.APP_JAR, statement.statementType)
Assert.assertEquals("province-1.0-SNAPSHOT-jar-with-dependencies.jar", statement.resourceName)
Assert.assertEquals("com.example.screen_dc.ScreenJob", statement.className)
Assert.assertEquals("/xiaoyong.fu/2017-22-03/sh/mobile/loan/", statement.params?.get(0))
Assert.assertEquals("--write-private-test", statement.params?.get(1))
} else {
Assert.fail()
}
}
@Test
fun setConfigTest7() {
val sql =
"""
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
/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;
"""
val statementDatas = AppJarHelper.parseStatement(sql)
Assert.assertEquals(1, statementDatas.size)
val statement = statementDatas.get(0)
if (statement is AppJarInfo) {
Assert.assertEquals(StatementType.APP_JAR, statement.statementType)
Assert.assertEquals("raph.edgesSNAPSHOT.eventType.jar", statement.resourceName)
Assert.assertEquals("com.example.graph.PhoenixCSVWriterJob", statement.className)
Assert.assertEquals("hdfs://192.168.40.37,hdfs://192.168.39.130", statement.params?.get(6))
} else {
Assert.fail()
}
}
@Test
fun setConfigTest8() {
val sql =
"""
set spark.app.name=sparkAppName;
set spark.memory.storageFraction=0.1;
set spark.memory.fraction=0.95;
set spark.memory.useLegacyMode=true;
set master=yarn-cluster;
/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/*
"""
val statementDatas = AppJarHelper.parseStatement(sql)
Assert.assertEquals(6, statementDatas.size)
val statement = statementDatas.get(5)
if (statement is AppJarInfo) {
Assert.assertEquals(StatementType.APP_JAR, statement.statementType)
Assert.assertEquals("/user/pontus_2.1/pontus-core-2.1.0-SNAPSHOT-fat.jar", statement.resourceName)
Assert.assertEquals("com.example.pontus.core.Engine", statement.className)
Assert.assertEquals(4, statement.params?.size)
val config =
"""
-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'}}
"""
Assert.assertEquals(config.trim(), statement.params?.get(1))
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-appjar-parser/src/test/resources/log4j2.xml
================================================
================================================
FILE: superior-arithmetic-parser/pom.xml
================================================
4.0.0
io.github.melin.superior
superior-sql-parser
4.0.23
superior-arithmetic-parser
superior-arithmetic-parser
io.github.melin.superior
superior-common-parser
${project.version}
================================================
FILE: superior-arithmetic-parser/src/main/antlr4/io/github/melin/superior/parser/antlr4/arithmetic/Arithmetic.g4
================================================
grammar Arithmetic;
@members {
public boolean bracket_enbled = true;
}
arithmetic: expression EOF;
expression
: booleanExpression
;
booleanExpression
: NOT booleanExpression #logicalNot
| valueExpression predicate? #predicated
| left=booleanExpression operator=AND right=booleanExpression #logicalBinary
| left=booleanExpression operator=OR right=booleanExpression #logicalBinary
;
predicate
: NOT? kind=BETWEEN lower=valueExpression AND upper=valueExpression
| NOT? kind=IN '(' expression (',' expression)* ')'
| NOT? kind=RLIKE pattern=valueExpression
| NOT? kind=LIKE pattern=valueExpression (ESCAPE escapeChar=STRING)?
| IS NOT? kind=NULL
| IS NOT? kind=(TRUE | FALSE | UNKNOWN)
;
valueExpression
: primaryExpression #valueExpressionDefault
| operator=(MINUS | PLUS | TILDE) valueExpression #arithmeticUnary
| left=valueExpression operator=(ASTERISK | SLASH | PERCENT | DIV) right=valueExpression #arithmeticBinary
| left=valueExpression operator=(PLUS | MINUS | CONCAT_PIPE) right=valueExpression #arithmeticBinary
| left=valueExpression operator=AMPERSAND right=valueExpression #arithmeticBinary
| left=valueExpression operator=HAT right=valueExpression #arithmeticBinary
| left=valueExpression operator=PIPE right=valueExpression #arithmeticBinary
| left=valueExpression comparisonOperator right=valueExpression #comparison
;
primaryExpression
: CASE whenClause+ (ELSE elseExpression=expression)? END #searchedCase
| CASE value=expression whenClause+ (ELSE elseExpression=expression)? END #simpleCase
| constant #constantDefault
| functionName '(' (setQuantifier? argument+=expression (',' argument+=expression)*)? ')' #functionCall
| identifier '->' expression #lambda
| '(' identifier (',' identifier)+ ')' '->' expression #lambda
| value=primaryExpression '[' index=valueExpression ']' #subscript
| identifier #columnReference
| '(' expression ')' #parenthesizedExpression
;
comparisonOperator
: EQ | NEQ | NEQJ | LT | LTE | GT | GTE | NSEQ
;
whenClause
: WHEN condition=expression THEN result=expression
;
functionName
: IDENTIFIER
;
identifier
: {!bracket_enbled}? IDENTIFIER
| {bracket_enbled}? LBRACKET IDENTIFIER RBRACKET
;
constant
: NULL #nullLiteral
| number #numericLiteral
| booleanValue #booleanLiteral
| STRING+ #stringLiteral
;
setQuantifier
: DISTINCT
| ALL
;
number
: MINUS? INTEGER_VALUE #integerLiteral
| MINUS? BIGINT_LITERAL #bigIntLiteral
| MINUS? SMALLINT_LITERAL #smallIntLiteral
| MINUS? TINYINT_LITERAL #tinyIntLiteral
| MINUS? DOUBLE_LITERAL #doubleLiteral
| MINUS? BIGDECIMAL_LITERAL #bigDecimalLiteral
;
booleanValue
: TRUE | FALSE
;
STRING
: '\'' ( ~('\''|'\\') | ('\\' .) )* '\''
| '"' ( ~('"'|'\\') | ('\\' .) )* '"'
;
TRUE: 'TRUE';
FALSE: 'FALSE';
NULL: 'NULL';
CASE: 'CASE';
WHEN: 'WHEN';
THEN: 'THEN';
ELSE: 'ELSE';
END: 'END';
DISTINCT: 'DISTINCT';
ALL: 'ALL';
NOT: 'NOT';
AND: 'AND';
OR: 'OR';
BETWEEN: 'BETWEEN';
IN: 'IN';
RLIKE: 'RLIKE';
LIKE: 'LIKE';
IS: 'IS';
ESCAPE: 'ESCAPE';
UNKNOWN: 'UNKNOWN';
EQ : '=' | '==';
NSEQ: '<=>';
NEQ : '<>';
NEQJ: '!=';
LT : '<';
LTE : '<=';
GT : '>';
GTE : '>=';
LBRACKET : '[' ;
RBRACKET : ']' ;
PLUS: '+';
MINUS: '-';
ASTERISK: '*';
SLASH: '/';
PERCENT: '%';
DIV: 'DIV';
TILDE: '~';
AMPERSAND: '&';
PIPE: '|';
CONCAT_PIPE: '||';
HAT: '^';
BIGINT_LITERAL
: DIGIT+ 'L'
;
SMALLINT_LITERAL
: DIGIT+ 'S'
;
TINYINT_LITERAL
: DIGIT+ 'Y'
;
INTEGER_VALUE
: DIGIT+
;
IDENTIFIER
: (LETTER | DIGIT | '_')+
;
fragment EXPONENT
: 'E' [+-]? DIGIT+
;
fragment DECIMAL_DIGITS
: DIGIT+ '.' DIGIT*
| '.' DIGIT+
;
DOUBLE_LITERAL
: DIGIT+ EXPONENT? 'D'
| DECIMAL_DIGITS EXPONENT? 'D'
;
BIGDECIMAL_LITERAL
: DIGIT+ EXPONENT? 'BD'
| DECIMAL_DIGITS EXPONENT? 'BD'
;
fragment DIGIT
: [0-9]
;
fragment LETTER
: [a-zA-Z]
| ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate
| [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF
;
SIMPLE_COMMENT
: '--' ('\\\n' | ~[\r\n])* '\r'? '\n'? -> channel(HIDDEN)
;
BRACKETED_EMPTY_COMMENT
: '/**/' -> channel(HIDDEN)
;
BRACKETED_COMMENT
: '/*' ~[+] .*? '*/' -> channel(HIDDEN)
;
WS : [ \r\n\t] + -> skip ;
================================================
FILE: superior-arithmetic-parser/src/main/kotlin/io/github/melin/superior/parser/arithmetic/AbstractArithParser.kt
================================================
package io.github.melin.superior.parser.arithmetic
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.parser.antlr4.arithmetic.ArithmeticParser
import java.util.concurrent.atomic.AtomicReference
object AbstractArithParser {
private val parserCaches = AtomicReference(AntlrCaches(ArithmeticParser._ATN))
/**
* Install the parser caches into the given parser.
*
* This method should be called before parsing any input.
*/
fun installCaches(parser: ArithmeticParser): Unit = parserCaches.get().installCaches(parser)
/**
* Drop the existing parser caches and create a new one.
*
* ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can
* consume a lot of memory depending on the input seen so far.
*
* This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL
* inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.
*/
fun refreshParserCaches() {
parserCaches.set(AntlrCaches(ArithmeticParser._ATN))
}
}
================================================
FILE: superior-arithmetic-parser/src/main/kotlin/io/github/melin/superior/parser/arithmetic/ArithmeticAntlr4Visitor.kt
================================================
package com.github.melin.superior.sql.parser.arithmetic
import io.github.melin.superior.common.SQLParserException
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.parser.antlr4.arithmetic.ArithmeticBaseVisitor
import io.github.melin.superior.parser.antlr4.arithmetic.ArithmeticParser
import io.github.melin.superior.parser.arithmetic.ArithmeticData
import org.antlr.v4.runtime.tree.ParseTree
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2020/7/28 9:49 上午 */
class ArithmeticAntlr4Visitor(val bracketEnbled: Boolean) : ArithmeticBaseVisitor() {
private var statement: Statement? = null
private val arithmetic = ArithmeticData()
override fun visit(tree: ParseTree): Statement? {
super.visit(tree)
if (statement == null) {
throw SQLParserException("不支持的表达式")
}
return statement
}
override fun visitExpression(ctx: ArithmeticParser.ExpressionContext): Statement? {
statement = arithmetic
return super.visitExpression(ctx)
}
override fun visitIdentifier(ctx: ArithmeticParser.IdentifierContext): Statement? {
val name = ctx.text
if (!arithmetic.functions.contains(name)) {
if (bracketEnbled) {
arithmetic.variables.add(StringUtils.substringBetween(name, "[", "]"))
} else {
arithmetic.variables.add(name)
}
}
return super.visitIdentifier(ctx)
}
override fun visitFunctionName(ctx: ArithmeticParser.FunctionNameContext): Statement? {
val name = ctx.text
arithmetic.functions.add(name)
return super.visitFunctionName(ctx)
}
}
================================================
FILE: superior-arithmetic-parser/src/main/kotlin/io/github/melin/superior/parser/arithmetic/ArithmeticHelper.kt
================================================
package com.github.melin.superior.sql.parser.arithmetic
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.common.antlr4.ParseException
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.parser.antlr4.arithmetic.ArithmeticLexer
import io.github.melin.superior.parser.antlr4.arithmetic.ArithmeticParser
import io.github.melin.superior.parser.arithmetic.AbstractArithParser
import org.antlr.v4.runtime.CharStreams
import org.antlr.v4.runtime.CommonTokenStream
import org.antlr.v4.runtime.atn.PredictionMode
import org.antlr.v4.runtime.misc.ParseCancellationException
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2018/1/10. */
object ArithmeticHelper {
@JvmStatic
fun parseStatement(command: String): Statement? {
return ArithmeticHelper.parseStatement(command, true)
}
@JvmStatic
fun parseStatement(command: String, bracketEnbled: Boolean): Statement? {
val trimCmd = StringUtils.trim(command)
val charStream = CharStreams.fromString(trimCmd)
val lexer = ArithmeticLexer(charStream)
val tokenStream = CommonTokenStream(lexer)
val parser = ArithmeticParser(tokenStream)
AbstractArithParser.installCaches(parser)
parser.bracket_enbled = bracketEnbled
parser.interpreter.predictionMode = PredictionMode.SLL
val sqlVisitor = ArithmeticAntlr4Visitor(bracketEnbled)
try {
try {
// first, try parsing with potentially faster SLL mode
return sqlVisitor.visit(parser.expression())
} catch (e: ParseCancellationException) {
tokenStream.seek(0) // rewind input stream
parser.reset()
// Try Again.
parser.interpreter.predictionMode = PredictionMode.LL
return sqlVisitor.visit(parser.expression())
}
} catch (e: ParseException) {
if (StringUtils.isNotBlank(e.command)) {
throw e
} else {
throw e.withCommand(trimCmd)
}
} finally {
val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)
if (releaseAntlrCache == null || "true".equals(releaseAntlrCache)) {
AbstractArithParser.refreshParserCaches()
}
}
}
}
================================================
FILE: superior-arithmetic-parser/src/main/kotlin/io/github/melin/superior/parser/arithmetic/Data.kt
================================================
package io.github.melin.superior.parser.arithmetic
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class ArithmeticData(
val variables: java.util.HashSet = HashSet(),
val functions: java.util.HashSet = HashSet()
) : Statement() {
override val statementType = StatementType.ARITHMETIC
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
}
================================================
FILE: superior-arithmetic-parser/src/test/kotlin/io/github/melin/superior/parser/arithmetic/ArithmetricParserTest.kt
================================================
package io.github.melin.superior.parser.arithmetic
import com.github.melin.superior.sql.parser.arithmetic.ArithmeticHelper
import io.github.melin.superior.common.StatementType
import org.junit.Assert
import org.junit.Test
/** Created by libinsong on 2018/1/10. */
class ArithmetricParserTest {
@Test
fun test0() {
val sql = """
特征1 / (特征_dd_2
- (log2(feature_12) + 特征3))
"""
val statement = ArithmeticHelper.parseStatement(sql, false)
Assert.assertEquals(StatementType.ARITHMETIC, statement?.statementType)
if (statement is ArithmeticData) {
Assert.assertEquals(4, statement.variables.toArray().size)
Assert.assertEquals(1, statement.functions.size)
Assert.assertEquals("log2", statement.functions.toArray().get(0))
} else {
Assert.fail()
}
}
@Test
fun test1() {
val sql =
"""
case when rand <= 12 then 1
when rand <= 23 then 2
else 3 end
"""
val statement = ArithmeticHelper.parseStatement(sql, false)
Assert.assertEquals(StatementType.ARITHMETIC, statement?.statementType)
if (statement is ArithmeticData) {
Assert.assertEquals(1, statement.variables.toArray().size)
Assert.assertEquals(0, statement.functions.size)
} else {
Assert.fail()
}
}
@Test
fun test2() {
val sql = """
[特征1] / ([特征_dd_2]
- (log2([feature_12]) + [特征3]))
"""
val statement = ArithmeticHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ARITHMETIC, statement?.statementType)
if (statement is ArithmeticData) {
Assert.assertEquals(4, statement.variables.toArray().size)
Assert.assertEquals(1, statement.functions.size)
Assert.assertEquals("log2", statement.functions.toArray().get(0))
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-arithmetic-parser/src/test/resources/log4j2.xml
================================================
================================================
FILE: superior-common-parser/pom.xml
================================================
4.0.0
io.github.melin.superior
superior-sql-parser
4.0.23
superior-common-parser
superior-common-parser
================================================
FILE: superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/AntlrCaches.java
================================================
package io.github.melin.superior.common.antlr4;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ParserATNSimulator;
import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.dfa.DFA;
public class AntlrCaches {
public static final String RELEASE_ANTLR_CACHE_AFTER_PARSING = "releaseAntlrCacheAfterParsing";
private final ATN atn;
private final PredictionContextCache predictionContextCache = new PredictionContextCache();
private final DFA[] decisionToDFA;
public AntlrCaches(ATN atn) {
this.atn = atn;
this.decisionToDFA = makeDecisionToDFA(this.atn);
}
public void installCaches(Parser parser) {
parser.setInterpreter(new ParserATNSimulator(parser, atn, decisionToDFA, predictionContextCache));
}
private DFA[] makeDecisionToDFA(ATN atn) {
DFA[] decisionToDFA = new DFA[atn.getNumberOfDecisions()];
for (int i = 0, len = atn.getNumberOfDecisions(); i < len; i++) {
decisionToDFA[i] = new DFA(atn.getDecisionState(i), i);
}
return decisionToDFA;
}
}
================================================
FILE: superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/Origin.java
================================================
package io.github.melin.superior.common.antlr4;
public class Origin {
private int line;
private int startPosition;
public Origin(int line, int startPosition) {
this.line = line;
this.startPosition = startPosition;
}
public int getLine() {
return line;
}
public void setLine(int line) {
this.line = line;
}
public int getStartPosition() {
return startPosition;
}
public void setStartPosition(int startPosition) {
this.startPosition = startPosition;
}
}
================================================
FILE: superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/ParseErrorListener.java
================================================
package io.github.melin.superior.common.antlr4;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
public class ParseErrorListener extends BaseErrorListener {
@Override
public void syntaxError(
Recognizer, ?> recognizer,
Object offendingSymbol,
int line,
int charPositionInLine,
java.lang.String msg,
RecognitionException e) {
Origin position = new Origin(line, charPositionInLine);
throw new ParseException(msg, position, position);
}
}
================================================
FILE: superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/ParseException.java
================================================
package io.github.melin.superior.common.antlr4;
import org.apache.commons.lang3.StringUtils;
public class ParseException extends RuntimeException {
private String command;
private String message;
private Origin start;
private Origin stop;
public ParseException(String message, Origin start, Origin stop) {
this.message = message;
this.start = start;
this.stop = stop;
}
public ParseException(String command, String message, Origin start, Origin stop) {
this.command = command;
this.message = message;
this.start = start;
this.stop = stop;
}
@Override
public String getMessage() {
StringBuilder builder = new StringBuilder();
builder.append("\n").append(message);
if (start != null) {
builder.append("(line " + start.getLine() + ", pos " + start.getStartPosition() + ")\n");
if (StringUtils.isNotBlank(command)) {
String[] lines = command.split("\n");
builder.append("\n== SQL ==\n");
for (int i = 0; i < start.getLine(); i++) {
builder.append(lines[i]).append("\n");
}
for (int i = 0; i < start.getStartPosition(); i++) {
builder.append("-");
}
builder.append("^^^\n");
for (int i = start.getLine(); i < lines.length; i++) {
builder.append(lines[i]).append("\n");
}
}
} else {
builder.append("\n== SQL ==\n").append(command);
}
return StringUtils.trim(builder.toString());
}
public ParseException withCommand(String cmd) {
return new ParseException(cmd, message, start, stop);
}
public String getCommand() {
return command;
}
public Origin getStart() {
return start;
}
public Origin getStop() {
return stop;
}
}
================================================
FILE: superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/ParserUtils.java
================================================
package io.github.melin.superior.common.antlr4;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.tree.TerminalNode;
public class ParserUtils {
/** Get the code that creates the given node. */
public static String source(ParserRuleContext ctx) {
CharStream stream = ctx.getStart().getInputStream();
return stream.getText(
Interval.of(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex()));
}
public static String getString(Token token) {
return unescapeSQLString(token.getText());
}
public static String getString(TerminalNode token) {
return unescapeSQLString(token.getText());
}
public static int getInt(Token token) {
return Integer.parseInt(token.getText());
}
public static String command(ParserRuleContext ctx) {
CharStream stream = ctx.getStart().getInputStream();
return stream.getText(Interval.of(0, stream.size()));
}
public static Origin position(Token token) {
return new Origin(token.getLine(), token.getCharPositionInLine());
}
private static void appendEscapedChar(StringBuilder sb, char n) {
switch (n) {
case '0':
sb.append("\u0000");
case '\'':
sb.append("\'");
case '"':
sb.append("\"");
case 'b':
sb.append("\b");
case 'n':
sb.append("\n");
case 'r':
sb.append("\r");
case 't':
sb.append("\t");
case 'Z':
sb.append("\u001A");
case '\\':
sb.append("\\");
// The following 2 lines are exactly what MySQL does TODO: why do we do this?
case '%':
sb.append("\\%");
case '_':
sb.append("\\_");
default:
sb.append(n);
}
}
private static String unescapeSQLString(String b) {
Character enclosure = null;
StringBuilder sb = new StringBuilder(b.length());
int i = 0;
int strLength = b.length();
while (i < strLength) {
char currentChar = b.charAt(i);
if (enclosure == null) {
if (currentChar == '\'' || currentChar == '\"') {
enclosure = currentChar;
}
} else if (enclosure == currentChar) {
enclosure = null;
} else if (currentChar == '\\') {
if ((i + 6 < strLength) && b.charAt(i + 1) == 'u') {
// \u0000 style character literals.
int code = 0;
int base = i + 2;
for (int h = 0; h < 4; h++) {
int digit = Character.digit(b.charAt(h + base), 16);
code = (code << 4) + digit;
}
sb.append((char) code);
i += 5;
} else if (i + 4 < strLength) {
// \000 style character literals.
char i1 = b.charAt(i + 1);
char i2 = b.charAt(i + 2);
char i3 = b.charAt(i + 3);
if ((i1 >= '0' && i1 <= '1') && (i2 >= '0' && i2 <= '7') && (i3 >= '0' && i3 <= '7')) {
char tmp = (char) ((i3 - '0') + ((i2 - '0') << 3) + ((i1 - '0') << 6));
sb.append(tmp);
i += 3;
} else {
appendEscapedChar(sb, i1);
i += 1;
}
} else if (i + 2 < strLength) {
// escaped character literals.
char n = b.charAt(i + 1);
appendEscapedChar(sb, n);
i += 1;
}
} else {
// non-escaped character literals.
sb.append(currentChar);
}
i += 1;
}
return sb.toString();
}
}
================================================
FILE: superior-common-parser/src/main/java/io/github/melin/superior/common/antlr4/UpperCaseCharStream.java
================================================
package io.github.melin.superior.common.antlr4;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CodePointCharStream;
import org.antlr.v4.runtime.IntStream;
import org.antlr.v4.runtime.misc.Interval;
public class UpperCaseCharStream implements CharStream {
private CodePointCharStream wrapped;
public UpperCaseCharStream(CodePointCharStream wrapped) {
this.wrapped = wrapped;
}
@Override
public void consume() {
wrapped.consume();
}
@Override
public int LA(int i) {
int la = wrapped.LA(i);
if (la == 0 || la == IntStream.EOF) {
return la;
} else {
return Character.toUpperCase(la);
}
}
@Override
public String getText(Interval interval) {
if (size() > 0 && (interval.b - interval.a >= 0)) {
return wrapped.getText(interval);
} else {
return "";
}
}
@Override
public int mark() {
return wrapped.mark();
}
@Override
public void release(int i) {
wrapped.release(i);
}
@Override
public int index() {
return wrapped.index();
}
@Override
public void seek(int i) {
wrapped.seek(i);
}
@Override
public int size() {
return wrapped.size();
}
@Override
public String getSourceName() {
return wrapped.getSourceName();
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/AlterActionType.kt
================================================
package io.github.melin.superior.common
import java.io.Serializable
enum class AlterActionType : Serializable {
SET_PROPS,
SET_SERDE,
TOUCH_TABLE,
ALTER_COLUMN,
ALTER_VIEW_QUERY,
ADD_UNIQUE_KEY,
ADD_PRIMARY_KEY,
ADD_INDEX,
ADD_PARTITION,
DROP_INDEX,
ADD_COLUMN,
SET_COLUMN_DEFAULT,
DROP_COLUMN,
DROP_COLUMN_DRFAULT,
DROP_PARTITION,
DROP_PRIMARY_KEY,
RENAME,
RENAME_PARTITION,
DETACH_PARTITION,
ATTACH_PARTITION,
TRUNCATE_PARTITION,
REFRESH_MV,
// Iceberg SQL Extensions
CREATE_TAG,
CREATE_BRANCH,
DROP_TAG,
DROP_BRANCH,
ADD_PARTITION_FIELD,
DROP_PARTITION_FIELD,
REPLACE_PARTITION_FIELD,
SET_WRITE_DISTRIBUTION_AND_ORDERING,
SET_IDENTIFIER_FIELDS,
DROP_IDENTIFIER_FIELDS,
// delta
ADD_CONSTRAINT,
DROP_CONSTRAINT,
DROP_FEATURE,
CLUSTER_BY,
SYNC_IDENTITY,
UNKOWN
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/PrivilegeType.kt
================================================
package io.github.melin.superior.common
enum class PrivilegeType {
READ,
WRITE,
ALTER,
DROP,
ADMIN,
CREATE,
PROCEDURE,
OTHER,
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/SQLParserException.kt
================================================
package io.github.melin.superior.common
class SQLParserException : RuntimeException {
constructor(message: String, ex: Exception?) : super(message, ex) {}
constructor(message: String) : super(message) {}
constructor(ex: Exception) : super(ex) {}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/SqlType.kt
================================================
package io.github.melin.superior.common
enum class SqlType(val desc: String) {
DML("Data Manipulation Language"),
DDL("Data Definition Language"),
DQL("Data Query Language"),
DCL("Data Control Language"),
TCL("Transaction Control Language")
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/StatementType.kt
================================================
package io.github.melin.superior.common
import java.io.Serializable
/** Created by libinsong on 2017/3/6. */
enum class StatementType : Serializable {
CREATE_CATALOG,
CREATE_DATABASE,
CREATE_SCHEMA,
CREATE_TABLE,
CREATE_TABLE_AS_SELECT,
CREATE_TABLE_AS_LIKE,
CREATE_MATERIALIZED_VIEW,
CREATE_VIEW,
CREATE_FILE_VIEW, // spark
CREATE_TEMP_VIEW_USING, // spark
CREATE_FUNCTION,
CREATE_PROCEDURE,
DROP_CATALOG,
DROP_DATABASE,
DROP_SCHEMA,
DROP_TABLE,
DROP_VIEW,
DROP_MATERIALIZED_VIEW,
DROP_FUNCTION,
DROP_SEQUENCE,
DROP_PROCEDURE,
TRUNCATE_TABLE,
REFRESH_TABLE,
EXPORT_TABLE,
CANCEL_EXPORT,
ANALYZE_TABLE,
ALTER_DATABASE,
ALTER_VIEW,
ALTER_MATERIALIZED_VIEW,
ALTER_TABLE,
REPAIR_TABLE,
COMMENT,
// DML
SELECT,
DELETE,
UPDATE,
MERGE,
INSERT,
LOAD_DATA, // spark
SHOW,
DESC,
// spark
CACHE,
UNCACHE,
CLEAR_CACHE,
// spark delta
VACUUM_TABLE,
OPTIMIZE_TABLE,
DESC_DELTA_DETAIL,
DESC_DELTA_HISTORY,
// spark
DESC_FUNCTION,
DESC_CATALOG,
DESC_DATABASE,
DESC_SCHEMA,
DESC_TABLE,
DESC_QUERY,
//
REFRESH_MV,
CANCEL_REFRESH_MV,
EXPLAIN,
SET,
RESET,
USE,
SPARK_DIST_CP,
DATATUNNEL, // spark
MERGE_FILE, // spark
APP_JAR, // spark
CALL, // hudi
HELP, // hudi
ARITHMETIC,
// StarRocks
SR_SUBMIT_TASK,
SR_DROP_TASK,
SR_CREATE_ROUTINE_LOAD,
SR_PAUSE_ROUTINE_LOAD,
SR_RESUME_ROUTINE_LOAD,
SR_STOP_ROUTINE_LOAD,
SR_ALTER_ROUTINE_LOAD,
LOAD_TABLE,
CANCEL_LOAD_TABLE,
ALTER_LOAD_TABLE,
ADD_RESOURCE,
LIST_RESOURCE,
REMOVE_RESOURCE,
SYNC_META,
SYNC_TABLE,
SYNC_DATABASE,
UNKOWN
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/TableType.kt
================================================
package io.github.melin.superior.common
enum class TableType {
HIVE,
MYSQL,
ORACLE,
STARROCKS,
POSTGRES,
SQLSERVER,
FLINK,
SPARK_STREAM,
DAMENG,
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/AnalyzeTable.kt
================================================
package io.github.melin.superior.common.relational
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
data class AnalyzeTable(val tableIds: List) : Statement() {
override val statementType = StatementType.ANALYZE_TABLE
override val privilegeType = PrivilegeType.READ
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/DefaultStatement.kt
================================================
package io.github.melin.superior.common.relational
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
class DefaultStatement(override val statementType: StatementType) : Statement() {
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/FunctionId.kt
================================================
package io.github.melin.superior.common.relational
import com.google.common.collect.Lists
import org.apache.commons.lang3.StringUtils
data class FunctionId(
val catalogName: String?,
val schemaName: String?,
val functionName: String,
) {
companion object {
@JvmStatic fun of(functionName: String) = TableId(functionName)
@JvmStatic fun of(schemaName: String, functionName: String) = TableId(schemaName, functionName)
@JvmStatic
fun of(catalogName: String, schemaName: String, functionName: String) =
TableId(catalogName, schemaName, functionName)
}
var funcType: String = "CF" // callfunction & TVF
var functionArguments: List = Lists.newArrayList()
constructor(schemaName: String?, tableName: String) : this(null, schemaName, tableName)
constructor(tableName: String) : this(null, null, tableName)
fun getFullFunctionName(): String {
if (catalogName != null) {
return "$catalogName.$schemaName.$functionName"
}
if (schemaName != null) {
return "$schemaName.$functionName"
}
return functionName
}
fun getLowerCatalogName(): String {
return StringUtils.lowerCase(catalogName)
}
fun getLowerSchemaName(): String {
return StringUtils.lowerCase(schemaName)
}
fun getLowerTableName(): String {
return StringUtils.lowerCase(functionName)
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/ProcedureId.kt
================================================
package io.github.melin.superior.common.relational
import org.apache.commons.lang3.StringUtils
data class ProcedureId(val catalogName: String?, val schemaName: String?, val procedureName: String) {
constructor(schemaName: String?, procedureName: String) : this(null, schemaName, procedureName)
constructor(procedureName: String) : this(null, null, procedureName)
fun getFullFunctionName(): String {
if (catalogName != null) {
return "${catalogName}.${schemaName}.${procedureName}"
}
if (schemaName != null) {
return "${schemaName}.${procedureName}"
}
return procedureName
}
fun getLowerCatalogName(): String {
return StringUtils.lowerCase(catalogName)
}
fun getLowerSchemaName(): String {
return StringUtils.lowerCase(schemaName)
}
fun getLowerTableName(): String {
return StringUtils.lowerCase(procedureName)
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/SchemaId.kt
================================================
package io.github.melin.superior.common.relational
import org.apache.commons.lang3.StringUtils
data class SchemaId(val catalogName: String?, val schemaName: String) {
companion object {
@JvmStatic fun of(schemaName: String) = SchemaId(schemaName)
@JvmStatic fun of(catalogName: String, schemaName: String) = SchemaId(catalogName, schemaName)
}
constructor(schemaName: String) : this(null, schemaName)
fun getFullSchemaName(): String {
if (catalogName != null) {
return "${catalogName}.${schemaName}"
}
return schemaName
}
fun getLowerCatalogName(): String {
return StringUtils.lowerCase(catalogName)
}
fun getLowerSchemaName(): String {
return StringUtils.lowerCase(schemaName)
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/Statement.kt
================================================
package io.github.melin.superior.common.relational
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import org.apache.commons.lang3.StringUtils
import java.io.Serializable
abstract class Statement : Serializable {
abstract val statementType: StatementType
abstract val privilegeType: PrivilegeType
abstract val sqlType: SqlType
private var sql: String = ""
fun setSql(sql: String) {
if (StringUtils.endsWith(sql, ";")) {
this.sql = StringUtils.substringBeforeLast(sql, ";")
} else {
this.sql = sql
}
}
fun getSql(): String {
return this.sql
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/TableId.kt
================================================
package io.github.melin.superior.common.relational
import org.apache.commons.lang3.StringUtils
data class TableId(val catalogName: String?, val schemaName: String?, val tableName: String, val metaType: String?) {
companion object {
@JvmStatic fun of(tableName: String) = TableId(tableName)
@JvmStatic fun of(schemaName: String, tableName: String) = TableId(schemaName, tableName)
@JvmStatic
fun of(catalogName: String, schemaName: String, tableName: String) = TableId(catalogName, schemaName, tableName)
}
constructor(
catalogName: String?,
schemaName: String?,
tableName: String
) : this(catalogName, schemaName, tableName, null)
constructor(schemaName: String?, tableName: String) : this(null, schemaName, tableName, null)
constructor(tableName: String) : this(null, null, tableName, null)
fun getFullTableName(): String {
if (catalogName != null) {
return "${catalogName}.${schemaName}.${tableName}"
}
if (schemaName != null) {
return "${schemaName}.${tableName}"
}
return tableName
}
fun getLowerCatalogName(): String {
return StringUtils.lowerCase(catalogName)
}
fun getLowerSchemaName(): String {
return StringUtils.lowerCase(schemaName)
}
fun getLowerTableName(): String {
return StringUtils.lowerCase(tableName)
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/abs/AbsDatabaseStatement.kt
================================================
package io.github.melin.superior.common.relational.abs
import io.github.melin.superior.common.relational.Statement
abstract class AbsDatabaseStatement : Statement() {
abstract val databaseName: String
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/abs/AbsTableStatement.kt
================================================
package io.github.melin.superior.common.relational.abs
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.common.relational.TableId
abstract class AbsTableStatement : Statement() {
abstract val tableId: TableId
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterAction.kt
================================================
package io.github.melin.superior.common.relational.alter
import io.github.melin.superior.common.AlterActionType
import io.github.melin.superior.common.PrivilegeType
abstract class AlterAction(val privilegeType: PrivilegeType = PrivilegeType.ALTER) {
abstract val alterType: AlterActionType
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterActions.kt
================================================
package io.github.melin.superior.common.relational.alter
import com.google.common.collect.Maps
import io.github.melin.superior.common.AlterActionType
import io.github.melin.superior.common.relational.SortType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.dml.QueryStmt
import io.github.melin.superior.common.relational.table.ColumnRel
import java.util.HashMap
data class AlterTableAction(override var alterType: AlterActionType) : AlterAction()
data class AlterPropsAction(var location: String? = null, var properties: HashMap = Maps.newHashMap()) :
AlterAction() {
override var alterType: AlterActionType = AlterActionType.SET_PROPS
constructor(properties: HashMap) : this(null, properties)
}
data class AlterSerDeAction(var properties: HashMap = Maps.newHashMap()) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.SET_SERDE
}
data class RenameAction(var newTableId: TableId, var ifExists: Boolean = false) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.RENAME
}
data class AlterTouchPartitionAction(
val newTableId: TableId, // 修改表,新列名称
val partitionVals: LinkedHashMap?
) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.TOUCH_TABLE
}
data class AlterViewAction(
val queryStmt: QueryStmt // 修改表,新列名称
) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.ALTER_VIEW_QUERY
}
data class RefreshMvAction(var async: Boolean = false) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.REFRESH_MV
}
data class AlterColumnAction(
override var alterType: AlterActionType,
var columName: String? = null, // 修改列名
var dataType: String? = null,
var comment: String? = null,
var position: String? = null,
var afterCol: String? = null,
var setOrDrop: String? = null,
var nullable: Boolean = true,
var defaultExpression: String? = null,
var dropDefault: Boolean = false,
var ifNotExists: Boolean = false
) : AlterAction() {
var newColumName: String? = null // 修改列名,新列名称
fun getColumn(): ColumnRel? {
return if (columName != null) {
ColumnRel(columName!!, dataType, comment, nullable, defaultExpression)
} else {
null
}
}
}
data class DropColumnAction(var columNames: ArrayList = arrayListOf()) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.DROP_COLUMN
fun firstColumn(): String {
return columNames.first()
}
constructor(columName: String) : this(arrayListOf(columName))
}
data class AddPartitionAction(var ifNotExists: Boolean = false, var partitions: List>) :
AlterAction() {
override var alterType: AlterActionType = AlterActionType.ADD_PARTITION
}
data class DropPartitionAction(
var ifExists: Boolean = false,
var partitions: List> = listOf()
) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.DROP_PARTITION
}
data class RenamePartitionAction(
var fromPartitionVals: LinkedHashMap,
var toPartitionVals: LinkedHashMap
) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.RENAME_PARTITION
}
data class CreateIndex(val indexName: String, val indexColumnNames: ArrayList = arrayListOf()) :
AlterAction() {
override var alterType: AlterActionType = AlterActionType.ADD_INDEX
var intimeAction: String = "ONLINE" // mysql ONLINE & OFFLINE
var indexCategory: String? = null
var indexType: String? = null
var comment: String? = null
}
data class IndexColumnName(
val columnName: String,
val sortType: SortType = SortType.UNKOWN,
)
data class DropIndex(val indexName: String, var ifExists: Boolean = false) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.DROP_INDEX
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterDatabase.kt
================================================
package io.github.melin.superior.common.relational.alter
import io.github.melin.superior.common.*
import io.github.melin.superior.common.relational.abs.AbsDatabaseStatement
import kotlin.collections.ArrayList
data class AlterDatabase(
val alterActionType: AlterActionType,
override val databaseName: String,
private val action: AlterAction?
) : AbsDatabaseStatement() {
override val statementType = StatementType.ALTER_DATABASE
override val privilegeType = PrivilegeType.ALTER
override val sqlType = SqlType.DDL
val actions: ArrayList = ArrayList()
var ifExists: Boolean = false
init {
if (action != null) {
actions.add(action)
}
}
constructor(alterActionType: AlterActionType, databaseName: String) : this(alterActionType, databaseName, null)
fun addActions(list: List) {
actions.addAll(list)
}
fun firstAction(): AlterAction {
return actions.first()
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterDatabaseActions.kt
================================================
package io.github.melin.superior.common.relational.alter
import com.google.common.collect.Maps
import io.github.melin.superior.common.AlterActionType
import java.util.HashMap
data class AlterDbPropsAction(
var location: String? = null,
var properties: HashMap = Maps.newHashMap()
) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.SET_PROPS
}
data class RenameDbAction(var newDatabaseName: String) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.RENAME
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterMaterializedView.kt
================================================
package io.github.melin.superior.common.relational.alter
import io.github.melin.superior.common.*
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
import kotlin.collections.ArrayList
data class AlterMaterializedView(override val tableId: TableId, private val action: AlterAction?) :
AbsTableStatement() {
override val statementType = StatementType.ALTER_MATERIALIZED_VIEW
override val privilegeType = PrivilegeType.ALTER
override val sqlType = SqlType.DDL
val actions: ArrayList = ArrayList()
var ifExists: Boolean = false
init {
if (action != null) {
actions.add(action)
}
}
constructor(tableId: TableId) : this(tableId, null)
fun addActions(list: List) {
actions.addAll(list)
}
fun firstAction(): AlterAction {
return actions.first()
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterTable.kt
================================================
package io.github.melin.superior.common.relational.alter
import io.github.melin.superior.common.*
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
import kotlin.collections.ArrayList
data class AlterTable(
override val tableId: TableId,
private val action: AlterAction?,
) : AbsTableStatement() {
override val statementType = StatementType.ALTER_TABLE
override val privilegeType = PrivilegeType.ALTER
override val sqlType = SqlType.DDL
val actions: ArrayList = ArrayList()
var ifExists: Boolean = false
init {
if (action != null) {
actions.add(action)
}
}
constructor(tableId: TableId) : this(tableId, null)
fun addAction(action: AlterAction) {
actions.add(action)
}
fun addActions(list: List) {
actions.addAll(list)
}
fun firstAction(): AlterAction {
return if (action != null) action else actions.first()
}
fun getFirstAlterType(): AlterActionType {
val action = firstAction()
return action.alterType
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/AlterView.kt
================================================
package io.github.melin.superior.common.relational.alter
import io.github.melin.superior.common.*
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
import kotlin.collections.ArrayList
data class AlterView(override val tableId: TableId, private val action: AlterAction?) : AbsTableStatement() {
override val statementType = StatementType.ALTER_VIEW
override val privilegeType = PrivilegeType.ALTER
override val sqlType = SqlType.DDL
val actions: ArrayList = ArrayList()
var ifExists: Boolean = false
init {
if (action != null) {
actions.add(action)
}
}
constructor(tableId: TableId) : this(tableId, null)
fun addActions(list: List) {
actions.addAll(list)
}
fun firstAction(): AlterAction {
return actions.first()
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/DeltaAlterActions.kt
================================================
package io.github.melin.superior.common.relational.alter
import io.github.melin.superior.common.AlterActionType
class AlterAddConstraintAction() : AlterAction() {
override var alterType: AlterActionType = AlterActionType.ADD_CONSTRAINT
}
class AlterDropConstraintAction() : AlterAction() {
override var alterType: AlterActionType = AlterActionType.DROP_CONSTRAINT
}
class AlterDropFeatureAction() : AlterAction() {
override var alterType: AlterActionType = AlterActionType.DROP_FEATURE
}
class AlterClusterByAction() : AlterAction() {
override var alterType: AlterActionType = AlterActionType.CLUSTER_BY
}
class AlterSyncIdentityAction() : AlterAction() {
override var alterType: AlterActionType = AlterActionType.SYNC_IDENTITY
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/alter/IcebergAlterActions.kt
================================================
package io.github.melin.superior.common.relational.alter
import io.github.melin.superior.common.AlterActionType
data class AlterCreateTagAction(val tagName: String) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.CREATE_TAG
}
data class AlterDropTagAction(val tagName: String) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.DROP_TAG
}
data class AlterCreateBranchAction(val branchName: String) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.CREATE_BRANCH
}
data class AlterDropBranchAction(val branchName: String) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.DROP_BRANCH
}
data class AlterSetIdentifierFieldsAction(val fields: List) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.SET_IDENTIFIER_FIELDS
}
data class AlterDropIdentifierFieldsAction(val fields: List) : AlterAction() {
override var alterType: AlterActionType = AlterActionType.DROP_IDENTIFIER_FIELDS
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/AddResourceStatement.kt
================================================
package io.github.melin.superior.common.relational.common
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
class AddResourceStatement(val fileNames: List, val resourceType: String) : Statement() {
override val statementType = StatementType.ADD_RESOURCE
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
constructor(fileName: String, resourceType: String) : this(listOf(fileName), resourceType)
fun first(): String {
return fileNames.first()
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/CallProcedure.kt
================================================
package io.github.melin.superior.common.relational.common
import com.google.common.collect.Sets
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.ProcedureId
import io.github.melin.superior.common.relational.Statement
data class CallProcedure(var procedureIds: HashSet, var properties: Map = mapOf()) :
Statement() {
override val statementType = StatementType.CALL
override val privilegeType = PrivilegeType.ADMIN
override val sqlType = SqlType.DML
constructor(procedureId: ProcedureId) : this(Sets.newHashSet(procedureId))
constructor(
procedureId: ProcedureId,
properties: Map
) : this(Sets.newHashSet(procedureId), properties)
fun first(): ProcedureId {
return procedureIds.first()
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/CancelExport.kt
================================================
package io.github.melin.superior.common.relational.common
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class CancelExport(val database: String?, var queryId: String) : Statement() {
override val statementType = StatementType.CANCEL_EXPORT
override val privilegeType = PrivilegeType.ALTER
override val sqlType = SqlType.DML
constructor(queryId: String) : this(null, queryId)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/CommentStatement.kt
================================================
package io.github.melin.superior.common.relational.common
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class CommentStatement(
val comment: String? = null,
val isNull: Boolean = false,
val objType: String? = null,
val objValue: String? = null
) : Statement() {
override val statementType = StatementType.COMMENT
override val privilegeType = PrivilegeType.ALTER
override val sqlType = SqlType.TCL
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/DescModel.kt
================================================
package io.github.melin.superior.common.relational.common
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.FunctionId
import io.github.melin.superior.common.relational.SchemaId
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
import io.github.melin.superior.common.relational.dml.QueryStmt
import org.apache.commons.lang3.StringUtils
class DescStatement(vararg val keywords: String) : Statement() {
override val statementType = StatementType.DESC
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
fun checkSql(sql: String): Boolean {
val words = StringUtils.split(sql, " ")
if (this.keywords.size != words.size) {
return false
}
val size = this.keywords.size
for (i in 0 until size) {
if (!StringUtils.equalsIgnoreCase(this.keywords.get(i), words[i])) {
return false
}
}
return true
}
}
// spark
data class DescFunction(val functionId: FunctionId) : Statement() {
override val statementType = StatementType.DESC_FUNCTION
override val privilegeType = PrivilegeType.READ
override val sqlType = SqlType.DDL
}
data class DescCatalog(val catalog: String) : Statement() {
override val statementType = StatementType.DESC_CATALOG
override val privilegeType = PrivilegeType.READ
override val sqlType = SqlType.DDL
}
// 适用pg 类型数据库
data class DescDatabase(val database: String) : Statement() {
override val statementType = StatementType.DESC_DATABASE
override val privilegeType = PrivilegeType.READ
override val sqlType = SqlType.DDL
}
data class DescSchema(val schemaId: SchemaId) : Statement() {
override val statementType = StatementType.DESC_SCHEMA
override val privilegeType = PrivilegeType.READ
override val sqlType = SqlType.DDL
}
data class DescTable(val tableId: TableId) : Statement() {
override val statementType = StatementType.DESC_TABLE
override val privilegeType = PrivilegeType.READ
override val sqlType = SqlType.DDL
}
data class DescQuery(val queryStmt: QueryStmt) : Statement() {
override val statementType = StatementType.DESC_QUERY
override val privilegeType = PrivilegeType.READ
override val sqlType = SqlType.DDL
}
// spark delta
data class DescDeltaDetail(override val tableId: TableId) : AbsTableStatement() {
override val statementType = StatementType.DESC_DELTA_DETAIL
override val privilegeType = PrivilegeType.READ
override val sqlType = SqlType.DDL
}
// spark delta
data class DescDeltaHistory(override val tableId: TableId, val limit: Int? = null) : AbsTableStatement() {
override val statementType = StatementType.DESC_DELTA_HISTORY
override val privilegeType = PrivilegeType.READ
override val sqlType = SqlType.DDL
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/ListResourceStatement.kt
================================================
package io.github.melin.superior.common.relational.common
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
class ListResourceStatement(val fileNames: List, val resourceType: String) : Statement() {
override val statementType = StatementType.ADD_RESOURCE
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
constructor(fileName: String, resourceType: String) : this(listOf(fileName), resourceType)
fun first(): String {
return fileNames.first()
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/ReSetStatement.kt
================================================
package io.github.melin.superior.common.relational.common
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class ReSetStatement(val key: String) : Statement() {
override val statementType = StatementType.RESET
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.TCL
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/RefreshMaterializedView.kt
================================================
package io.github.melin.superior.common.relational.common
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.common.relational.TableId
data class RefreshMaterializedView(
val tableId: TableId,
val force: Boolean = false,
val mode: String = "Async",
val partitionStart: String? = null,
val partitionEnd: String? = null,
) : Statement() {
override val statementType = StatementType.REFRESH_MV
override val privilegeType = PrivilegeType.ADMIN
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/RemoveResourceStatement.kt
================================================
package io.github.melin.superior.common.relational.common
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
class RemoveResourceStatement(val fileNames: List, val resourceType: String) : Statement() {
override val statementType = StatementType.REMOVE_RESOURCE
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
constructor(fileName: String, resourceType: String) : this(listOf(fileName), resourceType)
fun first(): String {
return fileNames.first()
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/SetStatement.kt
================================================
package io.github.melin.superior.common.relational.common
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class SetStatement(val key: String, val value: String? = null) : Statement() {
override val statementType = StatementType.SET
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.TCL
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/ShowStatement.kt
================================================
package io.github.melin.superior.common.relational.common
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
import org.apache.commons.lang3.StringUtils
class ShowStatement(vararg val keywords: String) : Statement() {
override val statementType = StatementType.SHOW
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
fun checkSql(sql: String): Boolean {
val words = StringUtils.split(sql, " ")
if (this.keywords.size != words.size) {
return false
}
val size = this.keywords.size
for (i in 0 until size) {
if (!StringUtils.equalsIgnoreCase(this.keywords.get(i), words[i])) {
return false
}
}
return true
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/SyncStatement.kt
================================================
package io.github.melin.superior.common.relational.common
import com.google.common.collect.Maps
import io.github.melin.superior.common.*
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.table.ColumnRel
data class SyncTable(
var sinkTableId: TableId,
var sourceTableId: TableId,
) : Statement() {
override val statementType = StatementType.SYNC_TABLE
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DML
val sinkOptions: HashMap = Maps.newHashMap()
val sourceOptions: HashMap = Maps.newHashMap()
var computeCols: List? = null
}
data class SyncDatabase(
var sinkCatalogName: String?,
var sinkDatabaseName: String,
var sourceCatalogName: String?,
var sourceDatabaseName: String,
var includingTables: String = ".*"
) : Statement() {
override val statementType = StatementType.SYNC_DATABASE
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DML
val sinkOptions: HashMap = Maps.newHashMap()
val sourceOptions: HashMap = Maps.newHashMap()
var excludingTables: String? = null
}
data class SyncDatabaseMetadata(val catalogName: String?, val databaseName: String, val owner: String?) : Statement() {
override val statementType = StatementType.SYNC_META
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DDL
}
data class SyncTableMetadata(val tableId: TableId, val owner: String?) : Statement() {
override val statementType = StatementType.SYNC_META
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DDL
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/common/UseStatement.kt
================================================
package io.github.melin.superior.common.relational.common
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class UseCatalog(val catalogName: String) : Statement() {
override val statementType = StatementType.USE
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
}
data class UseDatabase(val catalogName: String?, val databaseName: String) : Statement() {
override val statementType = StatementType.USE
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
constructor(databaseName: String) : this(null, databaseName)
}
data class UseSchema(val databaseName: String?, val schemaName: String) : Statement() {
override val statementType = StatementType.USE
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
constructor(databaseName: String) : this(null, databaseName)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateCatalog.kt
================================================
package io.github.melin.superior.common.relational.create
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
class CreateCatalog(
val catalogName: String,
var properties: Map? = null,
) : Statement() {
override val statementType = StatementType.CREATE_CATALOG
override val privilegeType = PrivilegeType.ADMIN
override val sqlType = SqlType.DDL
constructor(catalogName: String) : this(catalogName, null)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateDatabase.kt
================================================
package io.github.melin.superior.common.relational.create
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
class CreateDatabase(
val catalogName: String?,
val databaseName: String,
val location: String? = null,
var properties: Map? = null,
var ifNotExists: Boolean = false,
) : Statement() {
override val statementType = StatementType.CREATE_DATABASE
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DDL
constructor(databaseName: String) : this(null, databaseName, null, null)
constructor(
catalogName: String?,
databaseName: String,
properties: Map? = null,
ifNotExists: Boolean = false
) : this(catalogName, databaseName, null, properties, ifNotExists)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateFunction.kt
================================================
package io.github.melin.superior.common.relational.create
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.FunctionId
import io.github.melin.superior.common.relational.Statement
data class CreateFunction(
val functionId: FunctionId,
val childStatements: ArrayList,
var replace: Boolean = false,
var temporary: Boolean = false,
val className: String? = null,
val file: String? = null
) : Statement() {
override val statementType = StatementType.CREATE_FUNCTION
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DML
var global: Boolean = false // starrocks
var properties: Map? = null // starrocks
var argumentTypes: List? = null // starrocks
var returnType: String? = null // starrocks
constructor(
functionId: FunctionId,
childStatements: ArrayList,
replace: Boolean
) : this(functionId, childStatements, replace, false)
constructor(
functionId: FunctionId,
childStatements: ArrayList
) : this(functionId, childStatements, false, false)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateMaterializedView.kt
================================================
package io.github.melin.superior.common.relational.create
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
import io.github.melin.superior.common.relational.dml.QueryStmt
import io.github.melin.superior.common.relational.table.ColumnRel
data class CreateMaterializedView(
override val tableId: TableId,
var queryStmt: QueryStmt,
val comment: String? = null,
var ifNotExists: Boolean = false, // 是否存在 if not exists 关键字
var columnRels: List? = null
) : AbsTableStatement() {
override val statementType = StatementType.CREATE_MATERIALIZED_VIEW
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DDL
var modelType: String = "Sync" // 表模型类型
var properties: Map = mapOf()
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateProcedure.kt
================================================
package io.github.melin.superior.common.relational.create
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.ProcedureId
import io.github.melin.superior.common.relational.Statement
data class CreateProcedure(
val procedureId: ProcedureId?,
val childStatements: ArrayList,
var replace: Boolean = false,
var temporary: Boolean = false,
val className: String? = null,
val file: String? = null
) : Statement() {
override val statementType = StatementType.CREATE_PROCEDURE
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DML
constructor(
procedureId: ProcedureId,
childStatements: ArrayList,
replace: Boolean
) : this(procedureId, childStatements, replace, false)
constructor(childStatements: ArrayList) : this(null, childStatements)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateSchema.kt
================================================
package io.github.melin.superior.common.relational.create
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
class CreateSchema(val databaseName: String?, val schemaName: String) : Statement() {
override val statementType = StatementType.CREATE_SCHEMA
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DDL
constructor(schemaName: String) : this(null, schemaName)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateTable.kt
================================================
package io.github.melin.superior.common.relational.create
import com.google.common.collect.Lists
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.TableType
import io.github.melin.superior.common.relational.PartitionType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
import io.github.melin.superior.common.relational.table.ColumnRel
data class CreateTable(
override val tableId: TableId,
val tableType: TableType,
val comment: String? = null,
var lifeCycle: Int? = null,
var partitionColumnRels: List? = null,
var columnRels: List? = null,
var properties: Map? = null,
var fileFormat: String? = null,
var ifNotExists: Boolean = false, // 是否存在 if not exists 关键字
var external: Boolean = false,
var temporary: Boolean = false,
var location: String? = null,
var querySql: String? = null,
val partitionColumnNames: ArrayList = arrayListOf()
) : AbsTableStatement() { // 是否存在 if exists 关键字
override val statementType = StatementType.CREATE_TABLE
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DDL
// 建表方式:hive & spark. https://spark.apache.org/docs/3.2.0/sql-ref-syntax-ddl-create-table.html
var replace = false
var modelType: String = "hive" // 表模型类型
var partitionType: PartitionType? = null // 分区类型
var options: Map? = null
var clusteredColumns: List = Lists.newArrayList() // 分桶表分桶列
var sortedColumns: List = Lists.newArrayList() // 分桶表排序列
var storageHandler: String? = null
constructor(
tableId: TableId,
tableType: TableType,
comment: String?,
columnRels: List?
) : this(tableId, tableType, comment, null, null, columnRels, null, null, false)
constructor(
tableId: TableId,
tableType: TableType,
comment: String?,
lifeCycle: Int?,
columnRels: List?
) : this(tableId, tableType, comment, lifeCycle, null, columnRels, null, null, false)
constructor(
tableId: TableId,
tableType: TableType,
comment: String? = null,
columnRels: List? = null,
ifNotExists: Boolean,
properties: Map? = null
) : this(tableId, tableType, comment, null, null, columnRels, properties, null, ifNotExists)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateTableAsSelect.kt
================================================
package io.github.melin.superior.common.relational.create
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.PartitionType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
import io.github.melin.superior.common.relational.dml.QueryStmt
import io.github.melin.superior.common.relational.table.ColumnRel
data class CreateTableAsSelect(
override val tableId: TableId,
var queryStmt: QueryStmt,
val comment: String? = null,
var lifeCycle: Int? = null,
var partitionColumnRels: List? = null,
var columnRels: List? = null,
var properties: Map? = null,
var fileFormat: String? = null,
var ifNotExists: Boolean = false, // 是否存在 if not exists 关键字
var locationPath: String? = null,
val partitionColumnNames: ArrayList = arrayListOf()
) : AbsTableStatement() { // 是否存在 if exists 关键字
override val statementType = StatementType.CREATE_TABLE_AS_SELECT
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DDL
var replace = false
// 建表方式:hive & spark. https://spark.apache.org/docs/3.2.0/sql-ref-syntax-ddl-create-table.html
var modelType: String = "hive"
var partitionType: PartitionType? = null // 分区类型
var options: Map? = null
var storageHandler: String? = null
constructor(
tableId: TableId,
queryStmt: QueryStmt
) : this(tableId, queryStmt, null, null, null, null, null, null, false)
constructor(
tableId: TableId,
queryStmt: QueryStmt,
comment: String? = null,
ifNotExists: Boolean,
properties: Map? = null
) : this(tableId, queryStmt, comment, null, null, null, properties, null, ifNotExists)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateTableLike.kt
================================================
package io.github.melin.superior.common.relational.create
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
data class CreateTableLike(
val oldTableId: TableId,
override val tableId: TableId,
var ifNotExists: Boolean = false,
var external: Boolean = false,
var temporary: Boolean = false
) : AbsTableStatement() {
override val statementType = StatementType.CREATE_TABLE_AS_LIKE
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DDL
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/create/CreateView.kt
================================================
package io.github.melin.superior.common.relational.create
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
import io.github.melin.superior.common.relational.dml.QueryStmt
import io.github.melin.superior.common.relational.table.ColumnRel
data class CreateView(
override val tableId: TableId,
var queryStmt: QueryStmt,
val comment: String? = null,
var ifNotExists: Boolean = false, // 是否存在 if not exists 关键字
var columnRels: List? = null
) : AbsTableStatement() {
override val statementType = StatementType.CREATE_VIEW
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DDL
var replace: Boolean = false
var temporary: Boolean = false
var global: Boolean = false
var fileFormat: String? = null
var properties: Map = mapOf()
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/delta/OptimizeTable.kt
================================================
package io.github.melin.superior.common.relational.delta
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
data class OptimizeTable(override val tableId: TableId) : AbsTableStatement() {
override val statementType = StatementType.OPTIMIZE_TABLE
override val privilegeType = PrivilegeType.WRITE
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/delta/VacuumTable.kt
================================================
package io.github.melin.superior.common.relational.delta
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
data class VacuumTable(override val tableId: TableId) : AbsTableStatement() {
override val statementType = StatementType.VACUUM_TABLE
override val privilegeType = PrivilegeType.WRITE
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/DeleteTable.kt
================================================
package io.github.melin.superior.common.relational.dml
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
data class DeleteTable(
override val tableId: TableId,
val inputTables: List,
) : AbsTableStatement() {
override val statementType = StatementType.DELETE
override val privilegeType = PrivilegeType.WRITE
override val sqlType = SqlType.DML
val outputTables: ArrayList = arrayListOf()
init {
if (!outputTables.contains(tableId)) {
outputTables.add(tableId)
}
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/InsertFiles.kt
================================================
package io.github.melin.superior.common.relational.dml
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class InsertFiles(
val mode: InsertMode,
val queryStmt: QueryStmt,
var properties: Map,
) : Statement() {
override val statementType = StatementType.INSERT
override val privilegeType = PrivilegeType.WRITE
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/InsertMode.kt
================================================
package io.github.melin.superior.common.relational.dml
import java.io.Serializable
enum class InsertMode : Serializable {
INTO,
INTO_REPLACE,
OVERWRITE,
OVERWRITE_HIVE_DIR,
OVERWRITE_DIR,
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/InsertMultiTable.kt
================================================
package io.github.melin.superior.common.relational.dml
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class InsertMultiTable(
val insertTables: List,
) : Statement() {
override val statementType = StatementType.UNKOWN
override val privilegeType = PrivilegeType.OTHER
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/InsertTable.kt
================================================
package io.github.melin.superior.common.relational.dml
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
import io.github.melin.superior.common.relational.table.ColumnRel
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.LinkedHashMap
data class InsertTable(
val mode: InsertMode,
val queryStmt: QueryStmt,
override val tableId: TableId,
var columnRels: List? = null,
) : AbsTableStatement() {
override val statementType = StatementType.INSERT
override val privilegeType = PrivilegeType.WRITE
override val sqlType = SqlType.DML
var properties: Map? = null
var fileFormat: String? = null
var partitionVals: LinkedHashMap? = null
var rows: ArrayList>? = null
val outputTables: ArrayList = arrayListOf()
var hints: LinkedHashMap>? = null
var mysqlReplace: Boolean = false
init {
if (!outputTables.contains(tableId)) {
outputTables.add(tableId)
}
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/MergeTable.kt
================================================
package io.github.melin.superior.common.relational.dml
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.common.relational.TableId
data class MergeTable(
var targetTable: TableId,
var inputTables: List = listOf(),
) : Statement() {
override val statementType = StatementType.MERGE
override val privilegeType = PrivilegeType.WRITE
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/QueryStmt.kt
================================================
package io.github.melin.superior.common.relational.dml
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.FunctionId
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.common.relational.TableId
data class QueryStmt(
var inputTables: List,
var limit: Int? = null,
var offset: Int? = null,
) : Statement() {
override val statementType = StatementType.SELECT
override val privilegeType = PrivilegeType.READ
override val sqlType = SqlType.DQL
val functionNames: HashSet = hashSetOf()
constructor() : this(listOf())
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/dml/UpdateTable.kt
================================================
package io.github.melin.superior.common.relational.dml
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
data class UpdateTable(
override val tableId: TableId,
var inputTables: List,
) : AbsTableStatement() {
override val statementType = StatementType.UPDATE
override val privilegeType = PrivilegeType.WRITE
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropCatalog.kt
================================================
package io.github.melin.superior.common.relational.drop
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
class DropCatalog(val catalogName: String) : Statement() {
override val statementType = StatementType.DROP_CATALOG
override val privilegeType = PrivilegeType.ADMIN
override val sqlType = SqlType.DDL
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropDatabase.kt
================================================
package io.github.melin.superior.common.relational.drop
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
class DropDatabase(val catalogName: String?, val databaseName: String, var ifExists: Boolean = false) : Statement() {
override val statementType = StatementType.DROP_DATABASE
override val privilegeType = PrivilegeType.DROP
override val sqlType = SqlType.DDL
val databaseNames: ArrayList = arrayListOf()
constructor(databaseName: String) : this(null, databaseName)
constructor(databaseName: String, ifExists: Boolean) : this(null, databaseName, ifExists)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropFunction.kt
================================================
package io.github.melin.superior.common.relational.drop
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.FunctionId
import io.github.melin.superior.common.relational.Statement
data class DropFunction(val functionId: FunctionId) : Statement() {
override val statementType = StatementType.DROP_FUNCTION
override val privilegeType = PrivilegeType.DROP
override val sqlType = SqlType.DDL
var argumentTypes: List? = null // starrocks
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropMaterializedView.kt
================================================
package io.github.melin.superior.common.relational.drop
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
data class DropMaterializedView(override val tableId: TableId, var ifExists: Boolean = false) : AbsTableStatement() {
override val statementType = StatementType.DROP_MATERIALIZED_VIEW
override val privilegeType = PrivilegeType.DROP
override val sqlType = SqlType.DDL
val tableIds: ArrayList = arrayListOf()
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropProcedure.kt
================================================
package io.github.melin.superior.common.relational.drop
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.ProcedureId
import io.github.melin.superior.common.relational.Statement
data class DropProcedure(val procedureId: ProcedureId) : Statement() {
override val statementType = StatementType.DROP_PROCEDURE
override val privilegeType = PrivilegeType.DROP
override val sqlType = SqlType.DDL
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropSchema.kt
================================================
package io.github.melin.superior.common.relational.drop
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
class DropSchema(
val databaseName: String?,
val schemaName: String,
) : Statement() {
override val statementType = StatementType.DROP_SCHEMA
override val privilegeType = PrivilegeType.DROP
override val sqlType = SqlType.DDL
constructor(schemaName: String) : this(null, schemaName)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropSequence.kt
================================================
package io.github.melin.superior.common.relational.drop
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
data class DropSequence(
override val tableId: TableId,
var ifExists: Boolean = false,
var isMaterialized: Boolean = false,
) : AbsTableStatement() {
override val statementType = StatementType.DROP_SEQUENCE
override val privilegeType = PrivilegeType.DROP
override val sqlType = SqlType.DDL
val tableIds: ArrayList = arrayListOf()
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropTable.kt
================================================
package io.github.melin.superior.common.relational.drop
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
data class DropTable(override val tableId: TableId, var ifExists: Boolean = false) : AbsTableStatement() {
override val statementType = StatementType.DROP_TABLE
override val privilegeType = PrivilegeType.DROP
override val sqlType = SqlType.DDL
val tableIds: ArrayList = arrayListOf()
var force: Boolean = false
var purge: Boolean = false
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/drop/DropView.kt
================================================
package io.github.melin.superior.common.relational.drop
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
data class DropView(override val tableId: TableId, var ifExists: Boolean = false) : AbsTableStatement() {
override val statementType = StatementType.DROP_VIEW
override val privilegeType = PrivilegeType.DROP
override val sqlType = SqlType.DDL
val tableIds: ArrayList = arrayListOf()
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/enums.kt
================================================
package io.github.melin.superior.common.relational
enum class SortType {
ASC,
DESC,
UNKOWN
}
enum class PartitionType {
RANGE,
LIST,
HASH,
KEY,
VALUES,
NORMAL,
EXPRESSION
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/io/AlterLoadTable.kt
================================================
package io.github.melin.superior.common.relational.io
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class AlterLoadTable(
val schemaName: String?,
val labelName: String,
) : Statement() {
override val statementType = StatementType.ALTER_LOAD_TABLE
override val privilegeType = PrivilegeType.ALTER
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/io/CancelLoadTable.kt
================================================
package io.github.melin.superior.common.relational.io
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class CancelLoadTable(
val schemaName: String?,
val labelName: String,
) : Statement() {
override val statementType = StatementType.CANCEL_LOAD_TABLE
override val privilegeType = PrivilegeType.DROP
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/io/ExportTable.kt
================================================
package io.github.melin.superior.common.relational.io
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.FunctionId
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
data class ExportTable(
override val tableId: TableId,
val path: String,
var properties: Map,
var partitionVals: LinkedHashMap,
var fileFormat: String? = null,
var compression: String? = null,
var maxFileSize: String? = null,
var overwrite: Boolean = false,
var single: Boolean = false,
var inputTables: ArrayList,
) : AbsTableStatement() {
override val statementType = StatementType.EXPORT_TABLE
override val privilegeType = PrivilegeType.READ
override val sqlType = SqlType.DML
val functionNames: HashSet = hashSetOf()
constructor(
tableId: TableId,
path: String,
properties: Map,
) : this(tableId, path, properties, linkedMapOf(), null, null, null, false, false, arrayListOf())
constructor(
tableId: TableId,
path: String,
properties: Map,
partitionVals: LinkedHashMap,
fileFormat: String? = null,
compression: String? = null,
maxFileSize: String? = null,
overwrite: Boolean = false,
single: Boolean = false,
) : this(
tableId,
path,
properties,
partitionVals,
fileFormat,
compression,
maxFileSize,
overwrite,
single,
arrayListOf()
)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/io/LoadTable.kt
================================================
package io.github.melin.superior.common.relational.io
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.Statement
data class LoadTable(
val schemaName: String?,
val labelName: String,
val tableNames: List,
) : Statement() {
override val statementType = StatementType.LOAD_TABLE
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DML
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/table/ColumnRel.kt
================================================
package io.github.melin.superior.common.relational.table
data class ColumnRel(
val columnName: String,
val typeName: String? = null,
val comment: String? = null,
var nullable: Boolean = true,
var defaultExpr: String? = null,
var primaryKey: Boolean = false,
val columnDefType: ColumnDefType = ColumnDefType.COMPUTED
) {
var columnLength = 0
var precision = 0
var scale = 0
var expression: String? = null // 计算表达式
var position: String? = null
var afterCol: String? = null
var jsonPath: String? = null // spark streaming sql json path
var computedExpr: String? = null // 计算列
var metadataKey: String? = null // 元数据列
constructor(
columnName: String,
typeName: String?,
comment: String?
) : this(columnName, typeName, comment, true, null)
constructor(
columnName: String,
typeName: String?,
comment: String?,
primaryKey: Boolean = false,
columnDefType: ColumnDefType
) : this(columnName, typeName, comment, true, null, primaryKey, columnDefType)
constructor(
columnName: String,
typeName: String?,
comment: String?,
columnDefType: ColumnDefType
) : this(columnName, typeName, comment, true, null, false, columnDefType)
}
enum class ColumnDefType {
PHYSICAL,
METADATA,
COMPUTED
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/table/RepairTable.kt
================================================
package io.github.melin.superior.common.relational.table
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
class RepairTable(override val tableId: TableId) : AbsTableStatement() {
override val statementType = StatementType.REPAIR_TABLE
override val privilegeType = PrivilegeType.ADMIN
override val sqlType = SqlType.DDL
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/relational/table/TruncateTable.kt
================================================
package io.github.melin.superior.common.relational.table
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
class TruncateTable(override val tableId: TableId, tableIds: ArrayList = ArrayList()) : AbsTableStatement() {
override val statementType = StatementType.TRUNCATE_TABLE
override val privilegeType = PrivilegeType.WRITE
override val sqlType = SqlType.DDL
init {
tableIds.add(tableId)
}
constructor(tableIds: ArrayList) : this(tableIds.first(), tableIds)
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/type/AbsDataTimeType.kt
================================================
package io.github.melin.superior.common.type
abstract class AbsDataTimeType : AbsType() {}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/type/AbsNumericType.kt
================================================
package io.github.melin.superior.common.type
abstract class AbsNumericType : AbsType() {
var character: String? = null
var collate: String? = null
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/type/AbsStringType.kt
================================================
package io.github.melin.superior.common.type
abstract class AbsStringType : AbsType() {
var character: String? = null
var collate: String? = null
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/type/AbsType.kt
================================================
package io.github.melin.superior.common.type
abstract class AbsType : Type {
override val alias: String? = null
override val alias2: String? = null
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/type/Type.kt
================================================
package io.github.melin.superior.common.type
interface Type {
val name: String
val alias: String?
val alias2: String? // 有些有多个别名,例如mysql integer有int 和 int4 两种
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/util/CommonUtils.kt
================================================
package com.github.melin.superior.sql.parser.util
import org.antlr.v4.runtime.ParserRuleContext
import org.antlr.v4.runtime.Token
import org.antlr.v4.runtime.tree.ParseTree
import org.antlr.v4.runtime.tree.TerminalNodeImpl
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2017/4/10. */
object CommonUtils {
val KEYWORD_REGEX = "'([A-Z_]+)'".toRegex()
fun findShowStatementKeyWord(keyWords: ArrayList, node: ParseTree) {
if (node is TerminalNodeImpl) {
val count = node.parent.childCount
for (i in 0 until count) {
val child = node.parent.getChild(i)
if (child is TerminalNodeImpl) {
keyWords.add(child.text.uppercase())
}
}
} else {
findShowStatementKeyWord(keyWords, node.getChild(0))
}
}
fun subsql(sql: String?, context: ParserRuleContext): String {
val currSql = StringUtils.substring(sql, context.start.startIndex, context.stop.stopIndex + 1)
return cleanLastSemi(currSql)
}
fun subsql(sql: String?, start: Token, stop: Token): String {
val currSql = StringUtils.substring(sql, start.stopIndex + 1, stop.stopIndex + 1)
return cleanLastSemi(currSql)
}
private fun cleanLastSemi(text: String): String {
if (StringUtils.endsWith(text, ";")) {
return StringUtils.substring(text, 0, text.length - 1)
}
return text
}
fun cleanQuote(value: String): String {
if (StringUtils.isBlank(value)) {
return value
}
var result = value
if (StringUtils.startsWith(result, "'") && StringUtils.endsWith(result, "'")) {
result = StringUtils.substring(result, 1, -1)
}
if (StringUtils.startsWith(result, "\"") && StringUtils.endsWith(result, "\"")) {
result = StringUtils.substring(result, 1, -1)
}
if (StringUtils.startsWith(value, "`") && StringUtils.endsWith(value, "`")) {
return StringUtils.substring(value, 1, -1)
}
return StringUtils.trim(result)
}
}
================================================
FILE: superior-common-parser/src/main/kotlin/io/github/melin/superior/common/util/DateUtils.kt
================================================
package com.github.melin.superior.sql.parser.util
import java.time.DateTimeException
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.*
object DateUtils {
fun getCurrentDateTime(): String {
try {
val ldt = LocalDateTime.ofInstant(Date().toInstant(), ZoneId.systemDefault())
val format = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")
return ldt.format(format)
} catch (ex: DateTimeException) {
throw RuntimeException(ex.message, ex)
}
}
}
================================================
FILE: superior-dameng-parser/pom.xml
================================================
4.0.0
io.github.melin.superior
superior-sql-parser
4.0.23
superior-dameng-parser
superior-dameng-parser
io.github.melin.superior
superior-common-parser
${project.version}
================================================
FILE: superior-dameng-parser/src/main/antlr4/io/github/melin/superior/parser/dameng/antlr4/DmSqlLexer.g4
================================================
lexer grammar DmSqlLexer;
// Keywords
ABORT: 'ABORT';
ABSOLUTE: 'ABSOLUTE';
ABSTRACT: 'ABSTRACT';
ACCESSED: 'ACCESSED';
ACCOUNT: 'ACCOUNT';
ACROSS: 'ACROSS';
ACTION: 'ACTION';
ADD: 'ADD';
ADMIN: 'ADMIN';
ADVANCED: 'ADVANCED';
AFTER: 'AFTER';
AGGREGATE: 'AGGREGATE';
ALL: 'ALL';
ALLOW_DATETIME: 'ALLOW_DATETIME';
ALLOW_IP: 'ALLOW_IP';
ALTER: 'ALTER';
ALWAYS: 'ALWAYS';
ANALYZE: 'ANALYZE';
AND: 'AND';
ANY: 'ANY';
APPLY: 'APPLY';
APR: 'APR';
ARCHIVE: 'ARCHIVE';
ARCHIVEDIR: 'ARCHIVEDIR';
ARCHIVELOG: 'ARCHIVELOG';
ARCHIVESTYLE: 'ARCHIVESTYLE';
ARRAY: 'ARRAY';
ARRAYLEN: 'ARRAYLEN';
AS: 'AS';
ASC: 'ASC';
ASCII: 'ASCII';
ASENSITIVE: 'ASENSITIVE';
ASSIGN: 'ASSIGN';
ASYNCHRONOUS: 'ASYNCHRONOUS';
ATTACH: 'ATTACH';
AT_KEYWORD: 'AT';
AUDIT: 'AUDIT';
AUG: 'AUG';
AUTHID: 'AUTHID';
AUTHORIZATION: 'AUTHORIZATION';
AUTO: 'AUTO';
AUTOEXTEND: 'AUTOEXTEND';
AUTONOMOUS_TRANSACTION: 'AUTONOMOUS_TRANSACTION';
AUTO_INCREMENT: 'AUTO_INCREMENT';
AUTO_UPDATE: 'AUTO_UPDATE';
AVG: 'AVG';
BACKED: 'BACKED';
BACKUP: 'BACKUP';
BACKUPDIR: 'BACKUPDIR';
BACKUPINFO: 'BACKUPINFO';
BACKUPSET: 'BACKUPSET';
BADFILE: 'BADFILE';
BAKFILE: 'BAKFILE';
BASE: 'BASE';
BATCH: 'BATCH';
BEFORE: 'BEFORE';
BEGIN: 'BEGIN';
BETWEEN: 'BETWEEN';
BIGDATEDIFF: 'BIGDATEDIFF';
BIGINT: 'BIGINT';
BINARY_KEYWORD: 'BINARY';
BIT: 'BIT';
BITMAP: 'BITMAP';
BLOB: 'BLOB';
BLOCK: 'BLOCK';
BODY: 'BODY';
BOOL: 'BOOL';
BOOLEAN: 'BOOLEAN';
BOTH: 'BOTH';
BRANCH: 'BRANCH';
BREADTH: 'BREADTH';
BREAK: 'BREAK';
BSTRING: 'BSTRING';
BTREE: 'BTREE';
BUFFER: 'BUFFER';
BUILD: 'BUILD';
BULK: 'BULK';
BULK_EXCEPTION: 'BULK_EXCEPTION';
BULK_ROWCOUNT: 'BULK_ROWCOUNT';
BY: 'BY';
BYDAY: 'BYDAY';
BYHOUR: 'BYHOUR';
BYMINUTE: 'BYMINUTE';
BYMONTH: 'BYMONTH';
BYMONTHDAY: 'BYMONTHDAY';
BYSECOND: 'BYSECOND';
BYTE: 'BYTE';
BYWEEKNO: 'BYWEEKNO';
BYYEARDAY: 'BYYEARDAY';
CACHE: 'CACHE';
CALCULATE: 'CALCULATE';
CALL: 'CALL';
CASCADE: 'CASCADE';
CASCADED: 'CASCADED';
CASE: 'CASE';
CASE_SENSITIVE: 'CASE_SENSITIVE';
CAST: 'CAST';
CATALOG: 'CATALOG';
CATCH: 'CATCH';
CHAIN: 'CHAIN';
CHANGE: 'CHANGE';
CHAR: 'CHAR';
CHARACTER: 'CHARACTER';
CHARACTERISTICS: 'CHARACTERISTICS';
CHECK: 'CHECK';
CHECKPOINT: 'CHECKPOINT';
CIPHER: 'CIPHER';
CLASS: 'CLASS';
CLOB: 'CLOB';
CLOSE: 'CLOSE';
CLUSTER: 'CLUSTER';
CLUSTERBTR: 'CLUSTERBTR';
COLLATE: 'COLLATE';
COLLATION: 'COLLATION';
COLLECT: 'COLLECT';
COLUMN: 'COLUMN';
COLUMNS: 'COLUMNS';
COMMENT: 'COMMENT';
COMMIT: 'COMMIT';
COMMITTED: 'COMMITTED';
COMMITWORK: 'COMMITWORK';
COMPILE: 'COMPILE';
COMPLETE: 'COMPLETE';
COMPRESS: 'COMPRESS';
COMPRESSED: 'COMPRESSED';
CONDITIONAL: 'CONDITIONAL';
CONNECT: 'CONNECT';
CONNECT_BY_IS_CYCLE: 'CONNECT_BY_IS_CYCLE';
CONNECT_BY_IS_LEAF: 'CONNECT_BY_IS_LEAF';
CONNECT_BY_ROOT: 'CONNECT_BY_ROOT';
CONNECT_IDLE_TIME: 'CONNECT_IDLE_TIME';
CONNECT_TIME: 'CONNECT_TIME';
CONST: 'CONST';
CONSTANT: 'CONSTANT';
CONSTRAINT: 'CONSTRAINT';
CONSTRAINTS: 'CONSTRAINTS';
CONSTRUCTOR: 'CONSTRUCTOR';
CONSTR_OP: 'CONSTR_OP';
CONTAINS: 'CONTAINS';
CONTEXT: 'CONTEXT';
CONTINUE: 'CONTINUE';
CONVERT: 'CONVERT';
COPY: 'COPY';
CORRESPONDING: 'CORRESPONDING';
CORRUPT: 'CORRUPT';
COUNT: 'COUNT';
COUNTER: 'COUNTER';
CPU_PER_CALL: 'CPU_PER_CALL';
CPU_PER_SESSION: 'CPU_PER_SESSION';
CREATE: 'CREATE';
CROSS: 'CROSS';
CRYPTO: 'CRYPTO';
CTLFILE: 'CTLFILE';
CUBE: 'CUBE';
CUMULATIVE: 'CUMULATIVE';
CURRENT: 'CURRENT';
CURRENT_SCHEMA: 'CURRENT_SCHEMA';
CURRENT_USER: 'CURRENT_USER';
CURSOR: 'CURSOR';
CYCLE: 'CYCLE';
DAILY: 'DAILY';
DANGLING: 'DANGLING';
DATA: 'DATA';
DATABASE: 'DATABASE';
DATAFILE: 'DATAFILE';
DATE: 'DATE';
DATEADD: 'DATEADD';
DATEDIFF: 'DATEDIFF';
DATEPART: 'DATEPART';
DATETIME: 'DATETIME';
DAY: 'DAY';
DBFILE: 'DBFILE';
DDL: 'DDL';
DDL_CLONE: 'DDL_CLONE';
DEBUG: 'DEBUG';
DEC: 'DEC';
DECIMAL: 'DECIMAL';
DECLARE: 'DECLARE';
DECODE: 'DECODE';
DEFAULT: 'DEFAULT';
DEFERRABLE: 'DEFERRABLE';
DEFERRED: 'DEFERRED';
DEFINER: 'DEFINER';
DELETE: 'DELETE';
DELETING: 'DELETING';
DELIMITED: 'DELIMITED';
DELTA: 'DELTA';
DEMAND: 'DEMAND';
DENSE_RANK: 'DENSE_RANK';
DEPTH: 'DEPTH';
DEREF: 'DEREF';
DESC: 'DESC';
DETACH: 'DETACH';
DETERMINISTIC: 'DETERMINISTIC';
DEVICE: 'DEVICE';
DIAGNOSTICS: 'DIAGNOSTICS';
DICTIONARY: 'DICTIONARY';
DIRECTORY: 'DIRECTORY';
DISABLE: 'DISABLE';
DISCONNECT: 'DISCONNECT';
DISKGROUP: 'DISKGROUP';
DISKSPACE: 'DISKSPACE';
DISTINCT: 'DISTINCT';
DISTRIBUTED: 'DISTRIBUTED';
DML: 'DML';
DO: 'DO';
DOMAIN: 'DOMAIN';
DOUBLE: 'DOUBLE';
DOWN: 'DOWN';
DROP: 'DROP';
DUMP: 'DUMP';
EACH: 'EACH';
EDITIONABLE: 'EDITIONABLE';
ELSE: 'ELSE';
ELSEIF: ('ELSEIF' | 'ELSIF');
EMPTY: 'EMPTY';
ENABLE: 'ENABLE';
ENCRYPT: 'ENCRYPT';
ENCRYPTION: 'ENCRYPTION';
END: 'END';
EQU: 'EQU';
ERROR: 'ERROR';
ERRORS: 'ERRORS';
ESCAPE: 'ESCAPE';
EVALNAME: 'EVALNAME';
EVENTINFO: 'EVENTINFO';
EVENTS: 'EVENTS';
EVERY: 'EVERY';
EXCEPT: 'EXCEPT';
EXCEPTION: 'EXCEPTION';
EXCEPTIONS: 'EXCEPTIONS';
EXCEPTION_INIT: 'EXCEPTION_INIT';
EXCHANGE: 'EXCHANGE';
EXCLUDE: 'EXCLUDE';
EXCLUDING: 'EXCLUDING';
EXCLUSIVE: 'EXCLUSIVE';
EXECUTE: 'EXECUTE';
EXISTS: 'EXISTS';
EXIT: 'EXIT';
EXPIRE: 'EXPIRE';
EXPLAIN: 'EXPLAIN';
EXTENDS: 'EXTENDS';
EXTERN: 'EXTERN';
EXTERNAL: 'EXTERNAL';
EXTERNALLY: 'EXTERNALLY';
EXTRACT: 'EXTRACT';
FAILED_LOGIN_ATTEMPS: 'FAILED_LOGIN_ATTEMPS';
FAILED_LOGIN_ATTEMPTS: 'FAILED_LOGIN_ATTEMPTS';
FALSE: 'FALSE';
FAST: 'FAST';
FEB: 'FEB';
FETCH: 'FETCH';
FIELDS: 'FIELDS';
FILE: 'FILE';
FILEGROUP: 'FILEGROUP';
FILESIZE: 'FILESIZE';
FILLFACTOR: 'FILLFACTOR';
FINAL: 'FINAL';
FINALLY: 'FINALLY';
FIRST: 'FIRST';
FLASHBACK: 'FLASHBACK';
FLOAT: 'FLOAT';
FOLLOWING: 'FOLLOWING';
FOR: 'FOR';
FORALL: 'FORALL';
FORCE: 'FORCE';
FOREIGN: 'FOREIGN';
FORMAT: 'FORMAT';
FOUND: 'FOUND';
FREQ: 'FREQ';
FREQUENCE: 'FREQUENCE';
FRI: 'FRI';
FROM: 'FROM';
FULL: 'FULL';
FULLY: 'FULLY';
FUNCTION: 'FUNCTION';
GENERATE: 'GENERATE';
GENERATED: 'GENERATED';
GET: 'GET';
GLOBAL: 'GLOBAL';
GLOBALLY: 'GLOBALLY';
GOTO: 'GOTO';
GRANT: 'GRANT';
GREAT: 'GREAT';
GROUP: 'GROUP';
GROUPING: 'GROUPING';
HASH: 'HASH';
HASHPARTMAP: 'HASHPARTMAP';
HAVING: 'HAVING';
HEXTORAW: 'HEXTORAW';
HIDDEN_KEYWORD: 'HIDDEN';
HIGH: 'HIGH';
HOLD: 'HOLD';
HOUR: 'HOUR';
HOURLY: 'HOURLY';
HUGE: 'HUGE';
IDENTIFIED: 'IDENTIFIED';
IDENTIFIER_KEYWORD: 'IDENTIFIER';
IDENTITY: 'IDENTITY';
IDENTITY_INSERT: 'IDENTITY_INSERT';
IF: 'IF';
IFNULL: 'IFNULL';
IGNORE: 'IGNORE';
IGNORE_ROW_ON_DUPKEY_INDEX: 'IGNORE_ROW_ON_DUPKEY_INDEX';
IMAGE: 'IMAGE';
IMMEDIATE: 'IMMEDIATE';
IN: 'IN';
INCLUDE: 'INCLUDE';
INCLUDING: 'INCLUDING';
INCREASE: 'INCREASE';
INCREMENT: 'INCREMENT';
INDEX: 'INDEX';
INDEXES: 'INDEXES';
INDICES: 'INDICES';
INITIAL: 'INITIAL';
INITIALIZED: 'INITIALIZED';
INITIALLY: 'INITIALLY';
INLINE: 'INLINE';
INNER: 'INNER';
INNERID: 'INNERID';
INPUT: 'INPUT';
INSENSITIVE: 'INSENSITIVE';
INSERT: 'INSERT';
INSERTING: 'INSERTING';
INSTANCE: 'INSTANCE';
INSTANTIABLE: 'INSTANTIABLE';
INSTEAD: 'INSTEAD';
INT: 'INT';
INTEGER: 'INTEGER';
INTENT: 'INTENT';
INTERSECT: 'INTERSECT';
INTERVAL: 'INTERVAL';
INTO: 'INTO';
INVISIBLE: 'INVISIBLE';
IS: 'IS';
ISOLATION: 'ISOLATION';
JAN: 'JAN';
JAVA: 'JAVA';
JOB: 'JOB';
JOIN: 'JOIN';
JSON: 'JSON';
JSON_TABLE: 'JSON_TABLE';
JUL: 'JUL';
JUN: 'JUN';
KEEP: 'KEEP';
KEY: 'KEY';
KEYS: 'KEYS';
LABEL: 'LABEL';
LARGE: 'LARGE';
LAST: 'LAST';
LAST2: 'LAST2';
LAX: 'LAX';
LEAD: 'LEADING';
LEFT: 'LEFT';
LEFTARG: 'LEFTARG';
LESS: 'LESS';
LEVEL: 'LEVEL';
LEVELS: 'LEVELS';
LEXER: 'LEXER';
LIKE: 'LIKE';
LIMIT: 'LIMIT';
LINK: 'LINK';
LIST: 'LIST';
LNNVL: 'LNNVL';
LOB: 'LOB';
LOCAL: 'LOCAL';
LOCALLY: 'LOCALLY';
LOCAL_OBJECT: 'LOCAL_OBJECT';
LOCATION: 'LOCATION';
LOCK: 'LOCK';
LOCKED: 'LOCKED';
LOG: 'LOG';
LOGFILE: 'LOGFILE';
LOGGING: 'LOGGING';
LOGIC: 'LOGIC';
LOGIN: 'LOGIN';
LOGOFF: 'LOGOFF';
LOGON: 'LOGON';
LOGOUT: 'LOGOUT';
LONG: 'LONG';
LONGVARBINARY: 'LONGVARBINARY';
LONGVARCHAR: 'LONGVARCHAR';
LOOP: 'LOOP';
LSN: 'LSN';
MANUAL: 'MANUAL';
MAP: 'MAP';
MAPPED: 'MAPPED';
MAR: 'MAR';
MATCH: 'MATCH';
MATCHED: 'MATCHED';
MATERIALIZED: 'MATERIALIZED';
MAX: 'MAX';
MAXPIECESIZE: 'MAXPIECESIZE';
MAXSIZE: 'MAXSIZE';
MAXVALUE: 'MAXVALUE';
MAX_RUN_DURATION: 'MAX_RUN_DURATION';
MAY: 'MAY';
MEMBER: 'MEMBER';
MEMORY: 'MEMORY';
MEM_SPACE: 'MEM_SPACE';
MERGE: 'MERGE';
MICRO: 'MICRO';
MIN: 'MIN';
MINEXTENTS: 'MINEXTENTS';
MINUS: 'MINUS';
MINUTE: 'MINUTE';
MINUTELY: 'MINUTELY';
MINVALUE: 'MINVALUE';
MIRROR: 'MIRROR';
MOD: 'MOD';
MODE: 'MODE';
MODIFY: 'MODIFY';
MON: 'MON';
MONEY: 'MONEY';
MONITORING: 'MONITORING';
MONTH: 'MONTH';
MONTHLY: 'MONTHLY';
MOUNT: 'MOUNT';
MOVE: 'MOVE';
MOVEMENT: 'MOVEMENT';
MULTISET: 'MULTISET';
NATIONAL: 'NATIONAL';
NATURAL: 'NATURAL';
NCHAR: 'NCHAR';
NCHARACTER: 'NCHARACTER';
NESTED_PATH: 'NESTED_PATH';
NEVER: 'NEVER';
NEW: 'NEW';
NEXT: 'NEXT';
NO: 'NO';
NOARCHIVELOG: 'NOARCHIVELOG';
NOAUDIT: 'NOAUDIT';
NOBRANCH: 'NOBRANCH';
NOCACHE: 'NOCACHE';
NOCOPY: 'NOCOPY';
NOCYCLE: 'NOCYCLE';
NODE: 'NODE';
NOLOCK: 'NOLOCK';
NOLOGGING: 'NOLOGGING';
NOMAXVALUE: 'NOMAXVALUE';
NOMINVALUE: 'NOMINVALUE';
NOMONITORING: 'NOMONITORING';
NONE: 'NONE';
NONEDITIONABLE: 'NONEDITIONABLE';
NOORDER: 'NOORDER';
NOPARALLEL: 'NOPARALLEL';
NORMAL: 'NORMAL';
NOROWDEPENDENCIES: 'NOROWDEPENDENCIES';
NOSORT: 'NOSORT';
NOT: 'NOT';
NOTFOUND: 'NOT_FOUND';
NOT_ALLOW_DATETIME: 'NOT_ALLOW_DATETIME';
NOT_ALLOW_IP: 'NOT_ALLOW_IP';
NOV: 'NOV';
NOVALIDATE: 'NOVALIDATE';
NOWAIT: 'NOWAIT';
NULL: 'NULL';
NULLS: 'NULLS';
NUMBER: 'NUMBER';
NUMERIC: 'NUMERIC';
OBJECT: 'OBJECT';
OCT: 'OCT';
OF: 'OF';
OFF: 'OFF';
OFFLINE: 'OFFLINE';
OFFSET: 'OFFSET';
OIDINDEX: 'OIDINDEX';
OLD: 'OLD';
ON: 'ON';
ONCE: 'ONCE';
ONLINE: 'ONLINE';
ONLY: 'ONLY';
OPEN: 'OPEN';
OPERATOR: 'OPERATOR';
OPTIMIZE: 'OPTIMIZE';
OPTION: 'OPTION';
OR: 'OR';
ORDER: 'ORDER';
ORDINALITY: 'ORDINALITY';
OUT: 'OUT';
OUTER: 'OUTER';
OVER: 'OVER';
OVERLAPS: 'OVERLAPS';
OVERLAY: 'OVERLAY';
OVERRIDE: 'OVERRIDE';
OVERRIDING: 'OVERRIDING';
PACKAGE: 'PACKAGE';
PAD: 'PAD';
PAGE: 'PAGE';
PARALLEL: 'PARALLEL';
PARALLEL_ENABLE: 'PARALLEL_ENABLE';
PARMS: 'PARMS';
PARTIAL: 'PARTIAL';
PARTITION: 'PARTITION';
PARTITIONS: 'PARTITIONS';
PASSING: 'PASSING';
PASSWORD: 'PASSWORD';
PASSWORD_GRACE_TIME: 'PASSWORD_GRACE_TIME';
PASSWORD_LIFE_TIME: 'PASSWORD_LIFE_TIME';
PASSWORD_LOCK_TIME: 'PASSWORD_LOCK_TIME';
PASSWORD_POLICY: 'PASSWORD_POLICY';
PASSWORD_REUSE_MAX: 'PASSWORD_REUSE_MAX';
PASSWORD_REUSE_TIME: 'PASSWORD_REUSE_TIME';
PATH: 'PATH';
PENDANT: 'PENDANT';
PERCENT: 'PERCENT';
PIPE: 'PIPE';
PIPELINED: 'PIPELINED';
PIVOT: 'PIVOT';
PLACING: 'PLACING';
PRAGMA: 'PRAGMA';
PREBUILT: 'PREBUILT';
PRECEDING: 'PRECEDING';
PRECISION: 'PRECISION';
PRESERVE: 'PRESERVE';
PRETTY: 'PRETTY';
PRIMARY: 'PRIMARY';
PRINT: 'PRINT';
PRIOR: 'PRIOR';
PRIVATE: 'PRIVATE';
PRIVILEGE: 'PRIVILEGE';
PRIVILEGES: 'PRIVILEGES';
PROCEDURE: 'PROCEDURE';
PROFILE: 'PROFILE';
PROTECTED: 'PROTECTED';
PT_BULK_ROWCOUNT: 'PT_BULK_ROWCOUNT';
PT_ROWCOUNT: 'PT_ROWCOUNT';
PT_ROWCOUNT2: 'PT_ROWCOUNT2';
PUBLIC: 'PUBLIC';
PURGE: 'PURGE';
QUERY: 'QUERY';
QUERY_REWRITE_INTEGRITY: 'QUERY_REWRITE_INTEGRITY';
QUOTA: 'QUOTA';
RAISE: 'RAISE';
RANDOMLY: 'RANDOMLY';
RANGE: 'RANGE';
RAWTOHEX: 'RAWTOHEX';
READ: 'READ';
READONLY: 'READONLY';
READ_PER_CALL: 'READ_PER_CALL';
READ_PER_SESSION: 'READ_PER_SESSION';
REAL: 'REAL';
REBUILD: 'REBUILD';
RECORD: 'RECORD';
RECORDS: 'RECORDS';
RECURSIVE: 'RECURSIVE';
REDUCED: 'REDUCED';
REF: 'REF';
REFERENCE: 'REFERENCE';
REFERENCES: 'REFERENCES';
REFERENCING: 'REFERENCING';
REFRESH: 'REFRESH';
REJECT: 'REJECT';
RELATED: 'RELATED';
RELATIVE: 'RELATIVE';
RENAME: 'RENAME';
REPEAT: 'REPEAT';
REPEATABLE: 'REPEATABLE';
REPLACE: 'REPLACE';
REPLAY: 'REPLAY';
REPLICATE: 'REPLICATE';
RESPECT: 'RESPECT';
RESIZE: 'RESIZE';
RESTORE: 'RESTORE';
RESTRICT: 'RESTRICT';
RESTRICT_REFERENCES: 'RESTRICT_REFERENCES';
RESULT: 'RESULT';
RESULT_CACHE: 'RESULT_CACHE';
RETURN: 'RETURN';
RETURNING: 'RETURNING';
REUSE: 'REUSE';
REVERSE: 'REVERSE';
REVOKE: 'REVOKE';
REWRITE: 'REWRITE';
RIGHT: 'RIGHT';
RIGHTARG: 'RIGHTARG';
ROLE: 'ROLE';
ROLLBACK: 'ROLLBACK';
ROLLFILE: 'ROLLFILE';
ROLLUP: 'ROLLUP';
ROOT: 'ROOT';
ROW: 'ROW';
ROWCOUNT: 'ROWCOUNT';
ROWCOUNT2: 'ROWCOUNT2';
ROWDEPENDENCIES: 'ROWDEPENDENCIES';
ROWID: 'ROWID';
ROWNUM: 'ROWNUM';
ROWS: 'ROWS';
ROWTYPE: 'ROWTYPE';
RULE: 'RULE';
SALT: 'SALT';
SAMPLE: 'SAMPLE';
SAT: 'SAT';
SAVE: 'SAVE';
SAVEPOINT: 'SAVEPOINT';
SBYTE: 'SBYTE';
SCHEMA: 'SCHEMA';
SCHEMABINDING: 'SCHEMABINDING';
SCN: 'SCN';
SCOPE: 'SCOPE';
SCROLL: 'SCROLL';
SEALED: 'SEALED';
SEARCH: 'SEARCH';
SECOND: 'SECOND';
SECONDLY: 'SECONDLY';
SECTION: 'SECTION';
SEED: 'SEED';
SELECT: 'SELECT';
SELF: 'SELF';
SENSITIVE: 'SENSITIVE';
SEP: 'SEP';
SEQUENCE: 'SEQUENCE';
SERERR: 'SERERR';
SERIALIZABLE: 'SERIALIZABLE';
SERVER: 'SERVER';
SESSION: 'SESSION';
SESSION_PER_USER: 'SESSION_PER_USER';
SET: 'SET';
SETS: 'SETS';
SHADOW: 'SHADOW';
SHARE: 'SHARE';
SHORT: 'SHORT';
SHUTDOWN: 'SHUTDOWN';
SIBLINGS: 'SIBLINGS';
SIMPLE: 'SIMPLE';
SINCE: 'SINCE';
SIZE: 'SIZE';
SIZEOF: 'SIZEOF';
SKIP_KEYWORD: 'SKIP';
SMALLINT: 'SMALLINT';
SNAPSHOT: 'SNAPSHOT';
SOME: 'SOME';
SOUND: 'SOUND';
SPACE_KEYWORD: 'SPACE';
SPAN: 'SPAN';
SPATIAL: 'SPATIAL';
SPEED: 'SPEED';
SPFILE: 'SPFILE';
SPLIT: 'SPLIT';
SQL: 'SQL';
STANDBY: 'STANDBY';
START: 'START';
STARTUP: 'STARTUP';
STAT: 'STAT';
STATEMENT: 'STATEMENT';
STATIC: 'STATIC';
STDDEV: 'STDDEV';
STOP: 'STOP';
STORAGE: 'STORAGE';
STORE: 'STORE';
STRICT: 'STRICT';
STRING: 'STRING';
STRIPING: 'STRIPING';
STRUCT: 'STRUCT';
STYLE: 'STYLE';
SUBPARTITION: 'SUBPARTITION';
SUBPARTITIONS: 'SUBPARTITIONS';
SUBSCRIBE: 'SUBSCRIBE';
SUBSTITUTABLE: 'SUBSTITUTABLE';
SUBSTRING: 'SUBSTRING';
SUBTYPE: 'SUBTYPE';
SUCCESSFUL: 'SUCCESSFUL';
SUM: 'SUM';
SUN: 'SUN';
SUSPEND: 'SUSPEND';
SWITCH: 'SWITCH';
SYNC: 'SYNC';
SYNCHRONOUS: 'SYNCHRONOUS';
SYNONYM: 'SYNONYM';
SYSTEM: 'SYSTEM';
SYS_CONNECT_BY_PATH: 'SYS_CONNECT_BY_PATH';
TABLE: 'TABLE';
TABLESPACE: 'TABLESPACE';
TABLESPACESET: 'TABLESPACESET';
TASK: 'TASK';
TEMPLATE: 'TEMPLATE';
TEMPORARY: 'TEMPORARY';
TEXT: 'TEXT';
THAN: 'THAN';
THEN: 'THEN';
THREAD: 'THREAD';
THROUGH: 'THROUGH';
THROW: 'THROW';
THU: 'THU';
TIES: 'TIES';
TIME: 'TIME';
TIMER: 'TIMER';
TIMES: 'TIMES';
TIMESTAMP: 'TIMESTAMP';
TIMESTAMPADD: 'TIMESTAMPADD';
TIMESTAMPDIFF: 'TIMESTAMPDIFF';
TIME_ZONE: 'TIME_ZONE';
TINYINT: 'TINYINT';
TO: 'TO';
TOP: 'TOP';
TRACE: 'TRACE';
TRACKING: 'TRACKING';
TRAIL: 'TRAILING';
TRANSACTION: 'TRANSACTION';
TRANSACTIONAL: 'TRANSACTIONAL';
TRIGGER: 'TRIGGER';
TRIGGERS: 'TRIGGERS';
TRIM: 'TRIM';
TRUE: 'TRUE';
TRUNCATE: 'TRUNCATE';
TRUNCSIZE: 'TRUNCSIZE';
TRXID: 'TRXID';
TRY: 'TRY';
TUE: 'TUE';
TYPE: 'TYPE';
TYPEDEF: 'TYPEDEF';
TYPEOF: 'TYPEOF';
UINT: 'UINT';
ULONG: 'ULONG';
UNBOUNDED: 'UNBOUNDED';
UNCOMMITTED: 'UNCOMMITTED';
UNCONDITIONAL: 'UNCONDITIONAL';
UNDER: 'UNDER';
UNION: 'UNION';
UNIQUE: 'UNIQUE';
UNLIMITED: 'UNLIMITED';
UNLOCK: 'UNLOCK';
UNPIVOT: 'UNPIVOT';
UNTIL: 'UNTIL';
UNUSABLE: 'UNUSABLE';
UP: 'UP';
UPDATE: 'UPDATE';
UPDATING: 'UPDATING';
USAGE: 'USAGE';
USER: 'USER';
USE_HASH: 'USE_HASH';
USE_MERGE: 'USE_MERGE';
USE_NL: 'USE_NL';
USE_NL_WITH_INDEX: 'USE_NL_WITH_INDEX';
USHORT: 'USHORT';
USING: 'USING';
VALUE: 'VALUE';
VALUES: 'VALUES';
VARBINARY_KEYWORD: 'VARBINARY';
VARCHAR: 'VARCHAR';
VARCHAR2: 'VARCHAR2';
VARIANCE: 'VARIANCE';
VARRAY: 'VARRAY';
VARYING: 'VARYING';
VERIFY: 'VERIFY';
VERSIONS: 'VERSIONS';
VERSIONS_ENDTIME: 'VERSIONS_ENDTIME';
VERSIONS_ENDTRXID: 'VERSIONS_ENDTRXID';
VERSIONS_OPERATION: 'VERSIONS_OPERATION';
VERSIONS_STARTTIME: 'VERSIONS_STARTTIME';
VERSIONS_STARTTRXID: 'VERSIONS_STARTTRXID';
VERTICAL: 'VERTICAL';
VIEW: 'VIEW';
VIRTUAL: 'VIRTUAL';
VISIBLE: 'VISIBLE';
VOID: 'VOID';
VSIZE: 'VSIZE';
WAIT: 'WAIT';
WED: 'WED';
WEEK: 'WEEK';
WEEKLY: 'WEEKLY';
WHEN: 'WHEN';
WHENEVER: 'WHENEVER';
WHERE: 'WHERE';
WHILE: 'WHILE';
WITH: 'WITH';
WITHIN: 'WITHIN';
WITHOUT: 'WITHOUT';
WORK: 'WORK';
WRAPPED: 'WRAPPED';
WRAPPER: 'WRAPPER';
WRITE: 'WRITE';
XML: 'XML';
XMLAGG: 'XMLAGG';
XMLATTRIBUTES: 'XMLATTRIBUTES';
XMLELEMENT: 'XMLELEMENT';
XMLPARSE: 'XMLPARSE';
XMLTABLE: 'XMLTABLE';
YEAR: 'YEAR';
YEARLY: 'YEARLY';
ZONE: 'ZONE';
// Skip
WHILE_SPACE: [ \t\r\n]+ -> skip;
WHILE_COMMENT: '/*' (COMMENT | .)*? '*/' -> channel(HIDDEN);
LINE_COMMENT: '--' ~[\r\n]* -> channel(HIDDEN);
// Operators
OP_ASSIGN: ':=';
OP_ADD_ASSIGN: '+=';
OP_SUB_ASSIGN: '-=';
OP_MULT_ASSIGN: '*=';
OP_DIV_ASSIGN: '/=';
OP_MOD_ASSIGN: '%=';
OP_AND_ASSIGN: '&=';
OP_XOR_ASSIGN: '^=';
OP_OR_ASSIGN: '|=';
OP_CONSTR: '||';
OP_CAST: '::';
OP_SHIFT_LEFT: '<<';
OP_SHIFT_RIGHT: '>>';
OPR_NE: ('!='| '<>');
OPR_LE: '<=';
OPR_GE: '>=';
OPR_EQ: '==';
OPR_AEQ: '=>';
OPR_INC: '++';
OPR_DEC: '--';
//OPR_EQ_RIGHT_JOIN: '=*';
OP_SHIFT_RIGHT_ASSIGN: '>>=';
OP_SHIFT_LEFT_ASSIGN: '<<=';
OP_EQUAL: '=';
OP_NOT: '!';
OP_PLUS: '+';
OP_MINUS: '-';
OP_STAR: '*';
OP_DIVIDE: '/';
OP_MOD: '%';
OP_GREATER: '>';
OP_LESS: '<';
OP_BIT_NOT: '~';
OP_BIT_OR: '|';
OP_BIT_AND: '&';
OP_BIT_XOR: '^';
// Symbols
BOUNDARY: '..';
DOT: '.';
UNDERLINE: '_';
AT: '@';
SHARP: '#';
DOLLAR: '$';
LR_BRACKET: '(';
RR_BRACKET: ')';
LR_SQUARE_BRACKET: '[';
RR_SQUARE_BRACKET: ']';
LR_BRACES: '{';
RR_BRACES: '}';
COMMA: (',' | '\uff0c');
SEMI: (';' | '\uff1b');
COLON: ':';
PLACEHOLDER: '?';
OP_U_OPRT: OP_CHARS+?;
// Var
LT_GLOBAL_VAR: '@''@' IDENTIFIER;
LT_IDENTIFIER: ( IDENTIFIERX | IDENTIFIER | LT_DQUOTE_STRING );
// Const
LT_STRING: 'N'? '\'' (~'\'' | '\'\'')* '\'';
LT_BITSTRING: [B] '\'' [^']* '\'';
LT_INTEGER: DIGIT+;
LT_BINTEGER: '0' [X] (DIGIT|[A-F])+;
//LT_BIGINTEGER: DIGIT {20,};
//LT_DECIMAL: ( (DIGIT* '.' DIGIT+)|(DIGIT+ '.' DIGIT*) );
LT_DECIMAL: (DIGIT* '.' DIGIT+) ;
//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};
LT_REAL: (DIGIT+ | LT_DECIMAL)('E'([+-]? DIGIT+)?);
// frament
fragment DIGIT: [0-9];
//fragment DIGIT_PARAM: '@' DIGIT+;
fragment CLETTER_H: [\u0080-\u00FF];
fragment CLETTER_T: [\u0000-\u00FF];
fragment CLETTER: [\u4e00-\u9fa5];
fragment LETTER1: (CLETTER | [_A-Z$#]);
fragment LETTER_OR_DIGIT1: (CLETTER | [_A-Z0-9$#]);
fragment LETTER2: (CLETTER_H | [_A-Z$#]);
fragment LETTER_OR_DIGIT2: (CLETTER_H | [_A-Z0-9$#]);
fragment IDENTIFIERX: LETTER1 LETTER_OR_DIGIT1*;
fragment IDENTIFIER: LETTER2 LETTER_OR_DIGIT2*;
fragment LT_DQUOTE_STRING: '"' ~'"'+ '"';
//fragment LT_BQUOTE_STRING: '`' ~'`'+ '`';
//fragment LT_BRACKET_STRING: '[' (~']' | ']' ']')* ']';
fragment NOLETERDIGIT: [^_A-Z#$0-9];
fragment OP_CHARS: [<>=+\-&|*%/^?@!~`];
fragment BINARY_FLOAT_INFINITY: 'BINARY_FLOAT_INFINITY';
fragment BINARY_FLOAT_NAN: 'BINARY_FLOAT_NAN';
fragment BINARY_DOUBLE_INFINITY: 'BINARY_DOUBLE_INFINITY';
fragment BINARY_DOUBLE_NAN: 'BINARY_DOUBLE_NAN';
================================================
FILE: superior-dameng-parser/src/main/antlr4/io/github/melin/superior/parser/dameng/antlr4/DmSqlParser.g4
================================================
parser grammar DmSqlParser;
options { tokenVocab=DmSqlLexer; }
dmprogram :
sql_clauses (SEMI sql_clauses)* SEMI? EOF
;
sql_clauses :
ddlsql
| dmlsql
| privsql
| othersql
| utilsql
| explainsql
| declare_block
;
ddlsql :
alter_proc_stmt
| alter_func_stmt
| alter_package_stmt
| alter_table_stmt
| alter_index_stmt
| comment_stmt
| alter_trigger_stmt
| alter_view_stmt
| alter_materialized_view_stmt
| refresh_materialized_view_stmt
| create_tablespace_stmt
| create_func_stmt
| create_proc_stmt
| create_trigger_stmt
| create_view_stmt
| create_materialized_view_stmt
| create_materialized_view_log_stmt
| alter_database_stmt
| alter_tablespace_stmt
| create_user_stmt
| alter_user_stmt
| create_profile_stmt
| alter_profile_stmt
| create_role_stmt
| create_sequence_stmt
| create_contextindex_stmt
| drop_contextindex_stmt
| alter_contextindex_stmt
| create_audit_rule_stmt
| create_dblink_stmt
| create_package_stmt
| create_package_body_stmt
| create_type_stmt
| create_type_body_stmt
| create_synonym_stmt
| create_crypto_stmt
| alter_crypto_stmt
| alter_session_stmt
| create_domain_stmt
| create_character_set_stmt
| create_collation_stmt
| alter_system_set_stmt
| create_context_stmt
| create_directory_stmt
| create_tablespace_set_stmt
| alter_tablespace_set_stmt
| create_operator_stmt
| drop_operator_stmt
| flashback_tab_stmt
;
dmlsql :
call_proc_stmt
| delete_stmt
| insert_stmt
| select_stmt ur_option?
| update_stmt
| merge_into_stmt
| trunc_table_stmt
| create_table_stmt
| drop_stmt
| begin_trans_stmt
| commit_trans_stmt
| rollback_stmt
| savepoint_stmt
| create_index_stmt
| set_trans_stmt
| lock_table_stmt
| set_identins_stmt
| set_session_stmt
| stat_on_org_stmt
| create_partition_group_stmt
| fetch_stmt
| open_stmt
| close_cursor_stmt
;
privsql :
grant_stmt
| revoke_stmt
;
othersql :
connect_stmt
| disconnect_stmt
| set_schema_stmt
| backup_stmt
| restore_stmt
;
utilsql :
alter_diskgroup_stmt
| shutdown_stmt
| repeat_interval_stmt
| create_schema_stmt
| assign_stmt
;
explainsql :
EXPLAIN (dmlsql | assign_stmt) (COMMA (dmlsql | assign_stmt))*
| EXPLAIN (AS raw_id)? FOR (dmlsql | ddlsql | privsql |othersql)
;
shutdown_stmt :
SHUTDOWN ABORT
| SHUTDOWN IMMEDIATE
| SHUTDOWN NORMAL
| SHUTDOWN TRANSACTIONAL local?
| STOP INSTANCE
;
alter_diskgroup_stmt :
alter_tag DISKGROUP LT_STRING pathname CORRUPT
;
local :
LOCAL
;
dmsubprogram :
label_list_options? decl_var_cur_list_options? BEGIN plbody except_option? blk_end_option
;
declare_block :
label_list_options? decl_var_cur_list_1? BEGIN plbody except_option? blk_end_option
;
decl_var_cur_list_options :
DECLARE
| DECLARE decl_var_cur_list
| decl_var_cur_list
;
decl_var_cur_list_1 :
DECLARE
| DECLARE decl_var_cur_list
;
decl_var_cur_list :
( decl_variable | decl_except | pragma_def | (decl_cursor SEMI) | decl_plsql_type | package_body_def | subpg_decl_stmt )+
;
decl_plsql_type :
TYPE variable_name IS plsql_type_def SEMI
| SUBTYPE variable_name IS sub_plsql_datatype not_null? SEMI
;
plsql_type_def :
RECORD '(' rec_item_def_list ')'
| REF CURSOR
| REF CURSOR RETURN plsql_datatype
| ARRAY plsql_datatype rank_specifiers
| REF CURSOR '(' param_def_list ')'
| REF CURSOR '(' param_def_list ')' RETURN plsql_datatype
| ARRAY plsql_datatype '[' lt_int_lst ']'
| plsql_datatype
| TABLE OF plsql_datatype not_null?
| TABLE OF plsql_datatype not_null? INDEX BY plsql_datatype
| VARRAY '(' LT_INTEGER ')' OF plsql_datatype not_null?
;
lt_int_lst :
LT_INTEGER
| lt_int_lst COMMA LT_INTEGER
;
rec_item_def_list :
rec_item_def (COMMA rec_item_def)*
;
rec_item_def :
id plsql_datatype opt_rank_specifier2 not_null? default_clause_option?
;
decl_variable :
variable_name_list plsql_datatype not_null? default_clause_option? SEMI
| variable_name_list AS plsql_datatype not_null? default_clause_option? SEMI
| variable_name_list CONSTANT plsql_datatype not_null? default_clause_option? SEMI
;
not_null :
NOT NULL
;
plsql_datatype :
datatype
| qualified_name dblink_clause? '%' TYPE
| qualified_name dblink_clause? '%' ROWTYPE
| REF qualified_name
| CURSOR
;
default_clause_option :
DEFAULT default_exp
| assign_op default_exp
;
variable_name_list :
variable_name (COMMA variable_name)*
;
decl_except :
variable_name_list EXCEPTION FOR '-' LT_INTEGER SEMI
| variable_name_list EXCEPTION FOR '-' LT_INTEGER COMMA LT_STRING SEMI
;
pragma_def :
PRAGMA pragma SEMI
;
pragma :
EXCEPTION_INIT '(' except_name COMMA '-' LT_INTEGER ')'
| AUTONOMOUS_TRANSACTION
;
plbody :
(plsql SEMI)+
;
ss_plbody :
plblock
;
label :
label_demiliter_l label_name label_demiliter_r
;
label_list :
label+
;
label_list_options :
label_list
;
label_demiliter_l :
OP_SHIFT_LEFT
;
label_demiliter_r :
OP_SHIFT_RIGHT
;
plsql :
dmlsql
| if_stmt
| assign_stmt
| goto_stmt
| while_stmt
| loop_stmt
| repeat_stmt
| for_stmt
| return_stmt
| plblock
| raise_stmt
| exit_stmt
| print_stmt
| execute_stmt
| continue_stmt
| case_stmt
| null_stmt
| label plsql
| forall_stmt
| pipe_row_stmt
;
ur_option :
WITH id
;
flashback_trig_enable :
ENABLE TRIGGERS
| DISABLE TRIGGERS
;
scn_or_lsn :
SCN
| LSN
;
full_table_name_list :
full_table_name (COMMA full_table_name)*
;
flashback_tab_stmt :
FLASHBACK TABLE full_table_name_list TO BEFORE DROP rename?
| FLASHBACK TABLE full_table_name_list TO BEFORE TRUNCATE
| FLASHBACK TABLE full_table_name_list TO TIMESTAMP exp flashback_trig_enable?
| FLASHBACK TABLE full_table_name_list TO scn_or_lsn trxid flashback_trig_enable?
;
rename :
RENAME TO id
;
alter_system_set_stmt :
alter_tag SYSTEM SET LT_STRING '=' raw_exp defer? scope?
;
defer :
DEFERRED
;
scope :
MEMORY
| BOTH
| SPFILE
;
alter_session_stmt :
alter_tag SESSION sess_id? SET QUERY_REWRITE_INTEGRITY assign_op exp
| alter_tag SESSION sess_id? SET EVENTS LT_STRING
| alter_tag SESSION sess_id? SET TIME_ZONE assign_op set_time_zone_string
| alter_tag SESSION sess_id? SET LT_STRING '=' raw_exp purge?
| alter_tag SESSION sess_id? SET CASE_SENSITIVE assign_op exp
| alter_tag SESSION sess_id? SET CASE_SENSITIVE assign_op DEFAULT
| alter_tag SESSION sess_id? SET CURRENT_SCHEMA '=' qualified_name
| alter_tag SESSION sess_id? SET sess_attr '=' sess_attr_val
| alter_tag SESSION sess_id? ENABLE PARALLEL parallel_mode
| alter_tag SESSION sess_id? DISABLE PARALLEL parallel_mode
| alter_tag SESSION sess_id? FORCE PARALLEL parallel_mode parallel_degree?
;
parallel_mode :
DML
| QUERY
| DDL
;
parallel_degree :
PARALLEL LT_INTEGER
;
purge :
PURGE
;
sess_id :
LT_INTEGER
| LT_DECIMAL
;
set_time_zone_string :
LOCAL
| LT_STRING
;
sess_attr :
raw_id
;
sess_attr_val :
raw_id
| LT_STRING
;
set_schema_stmt :
SET SCHEMA qualified_name
;
plblock :
decl_var_cur_list_1? BEGIN plbody except_option? blk_end_option
;
except_option :
EXCEPTION except_handler_list finally_option?
| FINALLY finally_tail
;
finally_option :
FINALLY finally_tail
;
finally_tail :
plbody
;
except_handler_list :
except_handler+
;
except_handler :
WHEN except_list THEN plbody
;
except_name :
variable_name
;
except_list :
qualified_name (OR qualified_name)*
;
if_stmt :
if_stmt_clause elseif_lst_option? else_option? END IF
| ss_if_stmt_clause ss_elseif_lst_option? ss_else_option?
;
if_stmt_clause :
if_condition_clause if_then_clause
;
if_condition_clause :
IF bool_exp
;
if_then_clause :
THEN plbody
;
elseif_lst_option :
elseif_clause elseif_lst_option?
;
elseif_clause :
ELSEIF bool_exp THEN plbody
;
else_option :
ELSE plbody
;
ss_if_stmt_clause :
if_condition_clause ss_plbody
;
ss_elseif_lst_option :
ss_elseif_clause ss_elseif_lst_option?
;
ss_elseif_clause :
ELSEIF bool_exp ss_plbody
;
ss_else_option :
ELSE ss_plbody
;
case_stmt :
CASE plsearched_when_list else_option? END case_option? label_name_options?
| CASE bool_exp plsearched_when_list else_option? END case_option? label_name_options?
;
plsearched_when_clause :
WHEN bool_exp THEN plbody
;
plsearched_when_list :
plsearched_when_clause+
;
case_option :
CASE
;
assign_stmt :
assign_obj2 assign_op bool_exp
| SET assign_obj assign_op bool_exp
;
assign_obj :
assignment_obj
;
assign_obj2 :
pexp_pfx2
| stm_param_name
;
assign_op :
ASSIGN
| OP_ASSIGN
| '='
;
goto_stmt :
GOTO id
;
while_stmt :
WHILE bool_exp LOOP plbody end_loop_label_null
;
loop_stmt :
LOOP plbody end_loop_label_null
;
repeat_stmt :
REPEAT plbody UNTIL bool_exp
;
for_stmt :
FOR id in_option for_condition LOOP plbody end_loop_label_null
;
forall_stmt :
forall_start for_condition forall_save_exception_option? forall_dml_stmt
| forall_start forall_index_values OF pexp forall_between_option? forall_save_exception_option? forall_dml_stmt
;
forall_between_option :
BETWEEN exp AND exp
;
forall_save_exception_option :
SAVE EXCEPTIONS
;
forall_index_values :
INDICES
| VALUES
;
forall_start :
FORALL id IN
;
forall_dml_stmt :
delete_stmt
| insert_stmt
| update_stmt
| merge_into_stmt
| query_exp
| execute_stmt
;
in_option :
IN REVERSE?
;
for_condition :
exp '..' exp
| exp
;
pipe_row_stmt :
PIPE ROW '(' exp ')'
;
exit_stmt :
EXIT
| EXIT WHEN bool_exp
| EXIT id
| EXIT id WHEN bool_exp
;
continue_stmt :
CONTINUE
| CONTINUE WHEN bool_exp
| CONTINUE id
| CONTINUE id WHEN bool_exp
;
null_stmt :
NULL
;
print_stmt :
PRINT exp
;
execute_stmt :
EXECUTE IMMEDIATE exp bulk_or_single_into? using_clause? dyn_return?
;
dyn_return :
return_option bulk_or_single_into?
;
using_clause :
USING using_exp_list
;
using_exp_list :
using_exp (COMMA using_exp)*
;
using_exp :
param_in_out_option? exp
;
alter_proc_stmt :
alter_tag PROCEDURE full_proc_name COMPILE cascade_opt? debug_tag?
;
alter_func_stmt :
alter_tag FUNCTION full_fun_name COMPILE cascade_opt? debug_tag?
;
alter_package_stmt :
alter_tag pkg_type full_proc_name COMPILE declare_opt? cascade_opt? debug_tag?
;
pkg_type :
PACKAGE
| TYPE
| CLASS
;
declare_opt :
DECLARE
;
alter_table_stmt :
alter_tag TABLE full_table_name alter_table_action
;
alter_tag :
ALTER
;
alter_index_stmt :
alter_tag INDEX full_index_name alter_index_action
;
full_index_name :
qualified_name
;
alter_index_action :
RENAME TO index_name
| visible_clause
| rebuild_clause
| UNUSABLE
| MONITORING USAGE
| NOMONITORING USAGE
;
rebuild_clause :
REBUILD storage_tag? index_no_sort? online_options? exclusive_options? asynchronous_options?
;
exclusive_options :
SHARE
| EXCLUSIVE
;
asynchronous_options :
ASYNCHRONOUS
| ASYNCHRONOUS LT_INTEGER
;
visible_clause :
VISIBLE
| INVISIBLE
;
column_def_list :
column_def (COMMA column_def_list)*
;
lock :
NO LOCK
;
alter_table_partition_action :
ADD range_partition lock?
| ADD list_partition
| ADD hash_partition
| DROP PARTITION exist? full_partition_name
| DROP PARTITION exist? FOR '(' exp_list ')'
| EXCHANGE PARTITION full_partition_name WITH TABLE full_table_name including_indexes?
| EXCHANGE SUBPARTITION full_partition_name WITH TABLE full_table_name including_indexes?
| SPLIT PARTITION full_partition_name AT_KEYWORD '(' range_partition_exp_list ')' INTO '(' split_partition_list ')'
| SPLIT PARTITION full_partition_name VALUES '(' list_partition_exp_list ')' INTO '(' split_partition_list ')'
| SPLIT PARTITION full_partition_name INTO '(' list_partition_list COMMA hash_partition ')'
| SPLIT PARTITION full_partition_name INTO '(' range_partition_list COMMA hash_partition ')'
| MERGE PARTITIONS partition_no? COMMA partition_no? INTO PARTITION full_partition_name
| MERGE PARTITIONS full_partition_name COMMA full_partition_name INTO PARTITION full_partition_name
| SET SUBPARTITION TEMPLATE template_info
| DROP SUBPARTITION exist? full_partition_name
| DROP SUBPARTITION exist? FOR '(' exp_list ')'
| MODIFY PARTITION full_partition_name ADD add_subpartition_desc
| MODIFY SUBPARTITION full_partition_name ADD add_subpartition_desc
| MODIFY PARTITION full_partition_name ADD VALUES '(' list_partition_value_list ')'
| MODIFY PARTITION full_partition_name DROP VALUES '(' list_partition_value_list ')'
| RENAME PARTITION full_partition_name TO full_partition_name
| RENAME SUBPARTITION full_partition_name TO full_partition_name
| MODIFY SUBPARTITION full_partition_name ADD VALUES '(' list_partition_value_list ')'
| MODIFY SUBPARTITION full_partition_name DROP VALUES '(' list_partition_value_list ')'
| MOVE PARTITION full_partition_name TABLESPACE tablespace_name
| MOVE SUBPARTITION full_partition_name TABLESPACE tablespace_name
| MOVE TABLESPACE tablespace_name
| LOCK PARTITIONS
| LOCK ROOT
;
template_info :
'(' template_item_1? ')'
| template_item_2
;
template_item_2 :
SUBPARTITIONS LT_INTEGER storage_hash_tag?
| LT_INTEGER storage_hash_tag?
;
template_item_1 :
range_subpartition_list
| hash_subpartition_list
| list_subpartition_list
;
including_indexes :
INCLUDING INDEXES
| EXCLUDING INDEXES
;
truncate_partition_name :
full_partition_name
| '(' full_partition_name ')'
;
cons_enable :
ENABLE
| DISABLE
;
reuse_storage_option :
REUSE STORAGE
| DROP STORAGE
;
alter_table_action :
ADD column_tag? not_exist? '(' column_def_list ')'
| ALTER column_tag? column_name SET DEFAULT default_exp
| ALTER column_tag? column_name SET DEFAULT ON NULL default_exp
| ALTER column_tag? column_name DROP DEFAULT
| ADD CONSTRAINT constraint_name_options? table_constraint_clause check_option_def_true? cons_enable?
| ADD table_constraint_clause check_option_def_true? cons_enable?
| DROP constraint_name_def restrict_cascade?
| ALTER column_tag? column_name RENAME TO column_name
| RENAME COLUMN column_name TO column_name
| RENAME TO table_name
| MODIFY mdf_column_def
| MODIFY CONSTRAINT constraint_name ENABLE
| MODIFY CONSTRAINT constraint_name DISABLE restrict_cascade?
| REBUILD MODIFY mdf_column_def
| MODIFY '(' mdf_column_def_list ')'
| ADD column_tag? not_exist? column_def
| DROP column_tag? exist? '(' drop_column_list ')'
| DROP column_tag? exist? column_name restrict_cascade?
| ENABLE ALL TRIGGERS
| DISABLE ALL TRIGGERS
| MODIFY constraint_name_def TO table_constraint_clause check_option_def_true? restrict_cascade?
| MODIFY space_limit_1
| alter_table_partition_action
| DROP IDENTITY
| DROP AUTO_INCREMENT
| ADD column_tag? not_exist? column_name identity_clause
| ENABLE ata_lock_option
| DISABLE ata_lock_option
| ENABLE CONSTRAINT constraint_name check_option_def_true?
| DISABLE CONSTRAINT constraint_name restrict_cascade?
| ALTER column_tag? column_name SET not_null_spec
| MODIFY ERROR TO ctab_error_option
| MODIFY LOG TO ctab_log_option
| ALTER column_tag? '(' column_list ')' SET STAT
| ALTER column_tag? '(' column_list ')' SET STAT NONE
| ALTER column_tag? column_name SET STAT NONE
| WITH COUNTER
| WITHOUT COUNTER
| LOGGING
| NOLOGGING
| REBUILD COLUMNS
| TRUNCATE PARTITION truncate_partition_name reuse_storage_option?
| TRUNCATE PARTITION FOR '(' exp_list ')' reuse_storage_option?
| TRUNCATE SUBPARTITION truncate_partition_name reuse_storage_option?
| TRUNCATE SUBPARTITION FOR '(' exp_list ')' reuse_storage_option?
| ALTER column_tag? column_name SET not_tag? VISIBLE
| ENABLE ROW MOVEMENT
| DISABLE ROW MOVEMENT
| MODIFY PATH pathname
| LOCATION '(' pathname ')'
| DEFAULT DIRECTORY id
| DEFAULT DIRECTORY id LOCATION '(' pathname ')'
| ENABLE USING LONG ROW
| WITH DELTA
| WITHOUT DELTA
| FORCE COLUMN STORAGE
| REBUILD hfs_rebuild_level
| REFRESH STAT
| SET STAT storage_stat_flag? storage_stat_cols?
| WITH ADVANCED LOG
| WITHOUT ADVANCED LOG
| TRUNCATE ADVANCED LOG
| ADD LOGIC LOG
| DROP LOGIC LOG
| DROP PRIMARY KEY restrict_cascade?
| DROP PARTITION GROUP full_table_name
| read_only_flag_not_null
| MOVE PARTITION full_partition_name TO raft_name fast_flag?
| MOVE TO full_grp_name fast_flag?
| increment_set
| ALTER column_tag? column_name ADD user_clause
| ALTER column_tag? column_name DROP user_clause
| RENAME constraint_name_def TO constraint_name
| PARALLEL LT_INTEGER
;
fast_flag :
FAST
;
storage_stat_flag :
NONE
| ASYNCHRONOUS
| SYNCHRONOUS
;
storage_stat_cols :
ON '(' column_list ')'
| EXCEPT '(' column_list ')'
;
hfs_rebuild_level :
SECTION
| TABLE
;
ata_lock_option :
PAGE LOCK
| ROW LOCK
| PAGE ROW LOCK
| ROW PAGE LOCK
;
mdf_column_def_list :
mdf_column_def (COMMA mdf_column_def)*
;
mdf_column_def :
column_def_low
| virtual_column_def
| column_name column_def_4_option?
;
column_def :
column_def_low
| virtual_column_def
;
column_def_ex :
column_def comment_clause?
;
column_def_low :
column_name datatype charset_option? collate_clause_option? column_def_4_option? storage_tag? encrypt_clause_options? compress_clause_opt?
;
virtual_column_datatype :
datatype
;
virtual_column_generated :
GENERATED ALWAYS
;
virtual_column_virtual :
VIRTUAL
;
virtual_column_visible :
VISIBLE
;
virtual_column_def :
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?
;
charset_option :
CHARACTER SET qualified_name
;
column_def_4_option :
identity_clause
| column_constraint_def
| auto_update_clause
| default_clause_with_on_null_opt (identity_clause | column_constraint_def | auto_update_clause)?
| identity_clause default_clause_with_on_null_opt
| identity_clause column_constraint_def
| identity_clause auto_update_clause
| column_constraint_def default_clause_with_on_null_opt
| column_constraint_def auto_update_clause
| column_constraint_def identity_clause
| auto_update_clause default_clause_with_on_null_opt
| auto_update_clause column_constraint_def
| auto_update_clause identity_clause
| default_clause_with_on_null_opt auto_update_clause column_constraint_def
| default_clause_with_on_null_opt column_constraint_def auto_update_clause
| default_clause_with_on_null_opt identity_clause column_constraint_def
| default_clause_with_on_null_opt column_constraint_def identity_clause
| default_clause_with_on_null_opt identity_clause auto_update_clause
| default_clause_with_on_null_opt auto_update_clause identity_clause
| identity_clause auto_update_clause column_constraint_def
| identity_clause column_constraint_def auto_update_clause
| identity_clause auto_update_clause default_clause_with_on_null_opt
| identity_clause default_clause_with_on_null_opt auto_update_clause
| identity_clause default_clause_with_on_null_opt column_constraint_def
| identity_clause column_constraint_def default_clause_with_on_null_opt
| column_constraint_def default_clause_with_on_null_opt auto_update_clause
| column_constraint_def auto_update_clause default_clause_with_on_null_opt
| column_constraint_def default_clause_with_on_null_opt identity_clause
| column_constraint_def identity_clause default_clause_with_on_null_opt
| column_constraint_def identity_clause auto_update_clause
| column_constraint_def auto_update_clause identity_clause
| auto_update_clause column_constraint_def default_clause_with_on_null_opt
| auto_update_clause default_clause_with_on_null_opt column_constraint_def
| auto_update_clause identity_clause column_constraint_def
| auto_update_clause column_constraint_def identity_clause
| auto_update_clause identity_clause default_clause_with_on_null_opt
| auto_update_clause default_clause_with_on_null_opt identity_clause
| default_clause_with_on_null_opt identity_clause auto_update_clause column_constraint_def
| default_clause_with_on_null_opt identity_clause column_constraint_def auto_update_clause
| default_clause_with_on_null_opt auto_update_clause identity_clause column_constraint_def
| default_clause_with_on_null_opt auto_update_clause column_constraint_def identity_clause
| default_clause_with_on_null_opt column_constraint_def identity_clause auto_update_clause
| default_clause_with_on_null_opt column_constraint_def auto_update_clause identity_clause
| identity_clause default_clause_with_on_null_opt auto_update_clause column_constraint_def
| identity_clause default_clause_with_on_null_opt column_constraint_def auto_update_clause
| identity_clause auto_update_clause default_clause_with_on_null_opt column_constraint_def
| identity_clause auto_update_clause column_constraint_def default_clause_with_on_null_opt
| identity_clause column_constraint_def default_clause_with_on_null_opt auto_update_clause
| identity_clause column_constraint_def auto_update_clause default_clause_with_on_null_opt
| auto_update_clause default_clause_with_on_null_opt identity_clause column_constraint_def
| auto_update_clause default_clause_with_on_null_opt column_constraint_def identity_clause
| auto_update_clause identity_clause default_clause_with_on_null_opt column_constraint_def
| auto_update_clause identity_clause column_constraint_def default_clause_with_on_null_opt
| auto_update_clause column_constraint_def identity_clause default_clause_with_on_null_opt
| auto_update_clause column_constraint_def default_clause_with_on_null_opt identity_clause
| column_constraint_def default_clause_with_on_null_opt identity_clause auto_update_clause
| column_constraint_def default_clause_with_on_null_opt auto_update_clause identity_clause
| column_constraint_def identity_clause default_clause_with_on_null_opt auto_update_clause
| column_constraint_def identity_clause auto_update_clause default_clause_with_on_null_opt
| column_constraint_def auto_update_clause identity_clause default_clause_with_on_null_opt
| column_constraint_def auto_update_clause default_clause_with_on_null_opt identity_clause
;
auto_update_clause :
ON UPDATE update_exp
;
update_exp :
exp
;
identity_clause :
IDENTITY '(' exp COMMA exp ')'
| IDENTITY
| AUTO_INCREMENT
;
default_clause_with_on_null_opt :
default_clause
| DEFAULT ON NULL default_exp
;
default_clause :
DEFAULT default_exp
;
default_exp :
exp
;
column_constraint_def :
column_constraints constraint_attributes_options?
;
constraint_name_def_options :
constraint_name_def
;
constraint_name_def :
CONSTRAINT constraint_name
;
column_constraints :
column_constraint+
;
column_constraint :
constraint_name_def_options? column_constraint_action cons_enable?
;
column_constraint_action :
not_null_spec
| NOT VISIBLE
| unique_spec using_index_clause?
| refs_spec
| check_constraint_def
;
not_null_spec :
not_tag? NULL
;
unique_spec :
UNIQUE
| PRIMARY KEY
| CLUSTER PRIMARY KEY
| NOT CLUSTER PRIMARY KEY
| CLUSTER KEY
| CLUSTER UNIQUE KEY
;
refs_spec :
refs_spec_action (WITH INDEX)?
;
refs_spec_action :
foreign_key? REFERENCES pendant_tag? refd_table_and_columns match_option? ref_triggered_action?
;
foreign_key :
FOREIGN KEY
;
refd_table_and_columns :
full_table_name
| full_table_name '(' ref_column_list ')'
;
ref_column_list :
column_list
;
column_list :
column_name compress_level? compress_type? (COMMA column_name compress_level? compress_type?)*
;
column_list2 :
exp compress_level? compress_type? (COMMA exp compress_level? compress_type?)*
;
full_column_list :
full_column_name (COMMA full_column_name)*
;
column_list_list :
'(' column_list ')' as_alias? storage_tag?
| '(' column_list ')' as_alias? storage_tag? COMMA column_list_list
;
drop_column_list :
column_name restrict_cascade? (COMMA column_name restrict_cascade?)*
;
match_option :
MATCH match_type
;
match_type :
FULL
| PARTIAL
| SIMPLE
;
ref_triggered_action :
update_rule
| delete_rule
| update_rule delete_rule
| delete_rule update_rule
;
update_rule :
ON UPDATE ref_action
;
delete_rule :
ON DELETE ref_action
;
ref_action :
CASCADE
| SET NULL
| SET DEFAULT
| NO ACTION
| RESTRICT
;
check_constraint_def :
CHECK '(' check_condition ')'
;
check_condition :
bool_exp
;
restrict_cascade :
RESTRICT
| CASCADE CONSTRAINTS?
;
cascade_opt :
CASCADE
;
constraint_name_options :
constraint_name
;
check_option_def_true :
NOT? CHECK
;
constraint_attributes_options :
constraint_attributes
;
constraint_attributes :
constraint_check_time
| deferrable_option
| constraint_check_time deferrable_option
| deferrable_option constraint_check_time
;
deferrable_option :
DEFERRABLE
;
constraint_check_time :
INITIALLY DEFERRED
| INITIALLY IMMEDIATE
;
table_constraint_clause :
table_constraint constraint_attributes_options?
;
table_constraint :
unique_spec '(' column_list ')' using_index_clause?
| foreign_key_clause
| check_constraint_def
;
using_index_clause :
USING INDEX TABLESPACE (id | DEFAULT)
;
foreign_key_clause :
FOREIGN KEY '(' ref_column_list ')' refs_spec
;
alter_trigger_stmt :
alter_tag TRIGGER full_trigger_name (alter_trigger_option | RENAME TO trigger_name)
;
alter_trigger_option :
ENABLE
| DISABLE
| COMPILE debug_tag?
| COMPILE AUTO
;
alter_table_partition_action_options :
alter_table_partition_action
;
refresh_materialized_view_stmt :
REFRESH MATERIALIZED VIEW full_view_name force? refresh_complete_del?
| REFRESH MATERIALIZED VIEW full_view_name COMPLETE refresh_complete_del?
| REFRESH MATERIALIZED VIEW full_view_name FAST
;
complete_del_null :
USING DEFAULT
| USING TRUNCATE
| USING DELETE
;
refresh_complete_del :
complete_del_null
;
alter_materialized_view_stmt :
alter_tag MATERIALIZED VIEW full_view_name alter_table_partition_action_options? mv_refresh_clause? query_rewrite?
;
alter_view_stmt :
alter_tag VIEW full_view_name alter_view_action
;
alter_view_action :
COMPILE
| ADD CONSTRAINT constraint_name_options? view_constraint_clause DISABLE cons_novalidate?
| ADD view_constraint_clause DISABLE cons_novalidate?
| DROP constraint_name_def
;
cons_novalidate :
NOVALIDATE
;
view_constraint_clause :
view_constraint
;
view_constraint :
view_unique_spec '(' column_list ')'
| FOREIGN KEY '(' ref_column_list ')' view_refs_spec
;
view_unique_spec :
UNIQUE
| PRIMARY KEY
;
view_refs_spec :
view_refs_spec_action
;
view_refs_spec_action :
foreign_key? REFERENCES refd_table_and_columns
;
call_proc_stmt :
raw_call_proc_stmt
| call_proc_stmt_2
;
raw_call_proc_stmt :
member_access2
| member2
| invocation_expression2
;
call_proc_stmt_2 :
CALL raw_call_proc_stmt
| exec_proc_stmt
;
exec_proc_stmt :
EXECUTE full_proc_name dblink_clause?
| EXECUTE full_proc_name dblink_clause? raw_exp_list
| EXECUTE full_proc_name dblink_clause? param_list
;
dblink_clause :
'@' id
;
dblink_clause2 :
'@' qualified_name
;
param_list :
param (COMMA param)*
;
param :
param_name OPR_AEQ bool_exp
;
raw_exp_list :
raw_exp (COMMA raw_exp)*
;
exp_list_2 :
exp (COMMA exp)+
;
exp_list :
exp
| exp_list_2
;
ins_exp_list :
(exp | DEFAULT) (COMMA(exp | DEFAULT))*
;
lt_exp :
op=('-' | '+') lt_exp
| LT_INTEGER
| LT_DECIMAL
| LT_REAL
| LT_STRING
| member_access LT_STRING
| member LT_STRING
| LT_BITSTRING
| INTERVAL '+' LT_STRING interval_qualifier
| INTERVAL '-' LT_STRING interval_qualifier
| INTERVAL LT_STRING interval_qualifier
;
range_partition_exp :
lt_exp
| MAXVALUE
| null_value
| invocation_expression
;
range_partition_exp_list :
range_partition_exp (COMMA range_partition_exp)*
;
list_partition_exp :
lt_exp
| null_value
| invocation_expression
;
list_partition_exp_list :
list_partition_exp (COMMA list_partition_exp)*
;
list_partition_value_list :
list_partition_exp_list
| DEFAULT
;
close_cursor_stmt :
CLOSE assign_obj2
;
close_cursor_statement :
CLOSE CURSOR assign_obj
;
begin_trans_stmt :
BEGIN TRANSACTION
;
commit_trans_stmt :
commit_head commit_tail?
;
commit_head :
COMMIT work_tag?
| COMMITWORK
;
commit_tail :
AND CHAIN
| AND NO CHAIN
| WRITE
| WRITE commit_wait_immed_option
| commit_wait_immed_option
;
commit_wait_immed_option :
WAIT
| NOWAIT
| IMMEDIATE
| WAIT IMMEDIATE
| NOWAIT IMMEDIATE
| IMMEDIATE WAIT
| BATCH WAIT
| IMMEDIATE NOWAIT
| BATCH NOWAIT
| AUTO
;
connect_stmt :
CONNECT user_name password
;
password :
id
| LT_BINTEGER
| LT_DECIMAL
| LT_INTEGER
| LT_REAL
;
ts_storage :
ON id
| ON LT_INTEGER
| ON LT_INTEGER FOR RESTORE
;
ts_storage_clause :
STORAGE '(' ts_storage ')'
;
create_tablespace_stmt :
CREATE TABLESPACE not_exist? tablespace_name DATAFILE file_list cache? copy_num? region_size? striping_clause? redundancy_clause? with_huge_clause? ts_storage_clause?
| 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?
| 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?
| CREATE HUGE TABLESPACE not_exist? tablespace_name PATH pathname copy_num? region_size? striping_clause? redundancy_clause? ts_storage_clause?
;
ctss_with_clause :
WITH '(' id_list ')'
;
create_tablespace_set_stmt :
CREATE TABLESPACE SET id ctss_with_clause?
;
alter_tablespace_set_stmt :
alter_tag TABLESPACE SET id ADD '(' id_list ')'
| alter_tag TABLESPACE SET id DELETE '(' id_list ')'
;
cache :
CACHE '=' id
;
alter_tablespace_stmt :
alter_tag TABLESPACE tablespace_name alter_tablespace_action
| alter_tag HUGE TABLESPACE tablespace_name ADD PATH pathname
;
keep :
KEEP
;
alter_tablespace_action :
RENAME TO tablespace_name
| RENAME DATAFILE pathname_list TO pathname_list
| ADD DATAFILE file_list
| DROP DATAFILE pathname
| ONLINE
| OFFLINE
| CACHE '=' id
| RESIZE DATAFILE pathname TO LT_INTEGER on_raft?
| DATAFILE pathname_list autoextend?
| CORRUPT
| OPTIMIZE LT_INTEGER
| MOVE TO raft_name read_only_flag? keep?
| ADD HUGE PATH pathname region_size?
;
file_list :
file (COMMA file)*
;
pathname_list :
pathname (COMMA pathname)*
;
integer_list :
LT_INTEGER (COMMA LT_INTEGER)*
;
file :
pathname mirror? SIZE LT_INTEGER autoextend?
;
mirror :
MIRROR pathname
;
autoextend_nextsize :
NEXT LT_INTEGER
;
autoextend_maxsize :
MAXSIZE LT_INTEGER
| MAXSIZE UNLIMITED
;
autoextend :
AUTOEXTEND OFF
| AUTOEXTEND ON autoextend_nextsize? autoextend_maxsize?
;
on_raft :
ON id
;
archfile :
archflag? archstyle_options? archdir?
;
archflag :
ARCHIVELOG
| NOARCHIVELOG
;
archstyle_options :
ARCHIVESTYLE archstyle
;
archstyle :
LT_STRING
;
archdir :
ARCHIVEDIR pathname
;
bakfile :
BACKUPDIR pathname
;
parameters_option_list :
PARMS '(' parameter_option_list ')'
;
parameter_option_list :
parameter_option (COMMA parameter_option)*
;
parameter_option :
id DELIMITED BY exp
| id exp
;
pathname :
LT_STRING
;
pathname_options :
pathname
;
backup_stmt :
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?
;
back_range_option :
DATABASE backup_options?
| TABLESPACE tablespace_name backup_options?
| TABLE full_table_name
| ARCHIVE LOG back_archive_spec_null
| ARCHIVELOG back_archive_spec_null
;
back_archive_spec_null :
archive_spec? not_backed_up? backup_delete_archive?
;
not_backed_up :
NOT BACKED UP
| NOT BACKED UP LT_INTEGER TIMES
| NOT BACKED UP SINCE TIME LT_STRING
;
archive_spec :
ALL
| FROM LSN spec_lsn
| UNTIL LSN spec_lsn
| LSN BETWEEN spec_lsn AND spec_lsn
| FROM TIME LT_STRING
| UNTIL TIME LT_STRING
| TIME BETWEEN LT_STRING AND LT_STRING
;
spec_lsn :
LT_INTEGER
;
backup_delete_archive :
DELETE INPUT
;
backup_options :
FULL
| FULL DDL_CLONE
| DDL_CLONE
| FULL SHADOW
| SHADOW
| INCREMENT FROM LSN LT_INTEGER
| INCREMENT cumulative? base_on_backup?
;
cumulative :
CUMULATIVE
;
with_bak_dir_list :
WITH BACKUPDIR pathname_list
;
base_on_backup :
BASE ON BACKUPSET pathname
;
backup_to_options :
TO backup_name
;
backup_path_null :
device_type? parms_command?
| BAKFILE pathname
| BACKUPSET pathname_options? device_type? parms_command?
;
device_type :
DEVICE TYPE media_name
;
parms_command :
PARMS LT_STRING
;
media_name :
id
;
backup_desc_options :
BACKUPINFO backup_desc
;
backup_desc :
LT_STRING
;
backup_maxsize :
MAXSIZE LT_INTEGER
| MAXPIECESIZE LT_INTEGER
;
backup_limit :
LIMIT READ SPEED LT_INTEGER
| LIMIT WRITE SPEED LT_INTEGER
| LIMIT READ SPEED LT_INTEGER WRITE SPEED LT_INTEGER
;
backup_identified :
IDENTIFIED BY password
| IDENTIFIED BY password ENCRYPT WITH cipher_name
| IDENTIFIED BY password WITH ENCRYPTION LT_INTEGER
| IDENTIFIED BY password WITH ENCRYPTION LT_INTEGER ENCRYPT WITH cipher_name
;
backup_compressed :
COMPRESSED
| COMPRESSED LEVEL LT_INTEGER
;
backup_without :
WITHOUT LOG
| WITHOUT MIRROR
| WITHOUT LOG WITHOUT MIRROR
;
backup_tsk_thread_num_null :
tsk_thread_num?
;
backup_parallel_dir :
PARALLEL pathname
| PARALLEL
| PARALLEL LT_INTEGER
| PARALLEL READ SIZE LT_INTEGER
| PARALLEL LT_INTEGER READ SIZE LT_INTEGER
;
backup_trace_file_level :
TRACE FILE pathname
| TRACE LEVEL LT_INTEGER
| TRACE FILE pathname TRACE LEVEL LT_INTEGER
| TRACE LEVEL LT_INTEGER TRACE FILE pathname
;
restore_stmt :
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?
| RESTORE TABLE full_table_name_options? res_struct? res_without_index_constraint? FROM restore_from restore_identified? restore_trace_file_level?
| 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?
| 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?
;
restore_datafile_lst :
DATAFILE pathname_list
| DATAFILE integer_list
;
restore_mapped_file :
mapped_file
;
mapped_file :
MAPPED FILE LT_STRING
;
res_struct :
STRUCT
;
tsk_thread_num :
TASK THREAD LT_INTEGER
;
restore_tsk_thread_num_null :
tsk_thread_num?
;
restore_parallel :
NOT PARALLEL
;
full_table_name_options :
full_table_name
;
res_without_index_constraint :
WITH INDEX
| WITH INDEX WITH CONSTRAINT
| WITH INDEX WITHOUT CONSTRAINT
| WITHOUT INDEX
| WITHOUT INDEX WITH CONSTRAINT
| WITHOUT INDEX WITHOUT CONSTRAINT
| WITH CONSTRAINT
| WITHOUT CONSTRAINT
;
restore_from :
pathname
| BACKUP backup_name
| BACKUPSET pathname device_type? parms_command?
;
res_until :
UNTIL TIME LT_STRING
| UNTIL LSN LT_INTEGER
| UNTIL TIME LT_STRING UNTIL LSN LT_INTEGER
| UNTIL LSN LT_INTEGER UNTIL TIME LT_STRING
;
restore_file_list_options :
restore_file_list
;
mirror_file_list_options :
mirror_file_list
;
restore_trace_file_level :
TRACE FILE pathname
| TRACE LEVEL LT_INTEGER
| TRACE FILE pathname TRACE LEVEL LT_INTEGER
| TRACE LEVEL LT_INTEGER TRACE FILE pathname
;
restore_file_list :
restore_file (COMMA restore_file)*
;
restore_file :
DBFILE LT_INTEGER TO pathname
;
mirror_file_list :
mirror_file (COMMA mirror_file)*
;
mirror_file :
MIRROR LT_INTEGER TO pathname
;
with_bak_arch_dir_list :
WITH BACKUPDIR pathname_list
| WITH ARCHIVEDIR pathname_list
| WITH BACKUPDIR pathname_list WITH ARCHIVEDIR pathname_list
;
restore_identified :
IDENTIFIED BY password
| IDENTIFIED BY password ENCRYPT WITH cipher_name
;
create_func_stmt :
CREATE replace_option? FUNCTION not_exist? full_func_name (func_def_inner | (WRAPPED LT_STRING))
;
func_aggr_clause :
AGGREGATE USING plsql_datatype
;
pipelined_options :
PIPELINED
;
replace_option :
OR REPLACE
;
edit_options :
EDITIONABLE
| NONEDITIONABLE
;
encryption_option :
WITH ENCRYPTION
;
calc_option :
FOR CALCULATE
;
func_action :
is_as dmsubprogram
| EXTERNAL pathname inner_fun_name? USING platform_type
| func_aggr_clause
| PIPELINED is_as dmsubprogram
| PIPELINED USING plsql_datatype
;
func_call_options :
func_call_option_list
;
func_call_option_list :
func_call_option+
;
func_call_option :
invoker_rights_clause
| deterministic_clause
| PARALLEL_ENABLE
| result_cache_clause
;
invoker_rights_clause_options :
invoker_rights_clause
;
invoker_rights_clause :
AUTHID DEFINER
| AUTHID CURRENT_USER
;
deterministic_clause_options :
deterministic_clause
;
deterministic_clause :
DETERMINISTIC
;
func_call_option2_options :
func_call_option_list2
;
func_call_option_list2 :
func_call_option2+
;
func_call_option2 :
deterministic_clause
| result_cache_clause
| PARALLEL_ENABLE
;
result_cache_clause :
RESULT_CACHE
;
inner_fun_name :
qualified_name
;
platform_type :
id
;
param_def_list_option :
'(' ')'
| '(' param_def_list ')'
;
param_def_list :
param_def
| param_def COMMA param_def_list
;
param_def :
param_name param_in_out_option? plsql_datatype default_clause_option?
;
param_in_out_option :
IN
| OUT
| IN OUT
| OUT IN
| OUT NOCOPY
| IN OUT NOCOPY
| OUT IN NOCOPY
;
is_as :
IS
| AS
;
stat_on_org_stmt :
STAT stat_para stat_size? ON qualified_name '(' column_list ')' global_tag?
| STAT stat_para stat_size? ON INDEX qualified_name global_tag?
| STAT ON qualified_name global_tag?
;
stat_size :
SIZE LT_INTEGER
;
stat_para :
LT_INTEGER
| LT_DECIMAL
| LT_REAL
;
stat_summarize :
COLUMN LT_INTEGER LT_REAL LT_INTEGER LT_REAL
| COLUMN stm_param stm_param stm_param stm_param
;
mstat_ex :
BY without_into_select
;
indexid :
LT_INTEGER
;
global_tag :
GLOBAL
;
bm_join_index_clause :
from_clause WHERE search_condition
;
parallel_stmt :
NOPARALLEL
| PARALLEL
| PARALLEL LT_INTEGER
;
create_index_stmt :
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?
;
with_inner :
WITH INNER
;
index_no_sort :
NOSORT
;
online_options :
ONLINE
;
unusable_options :
UNUSABLE
;
reverse_options :
REVERSE
;
index_column_list :
index_column_name (COMMA index_column_name)*
;
index_column_name :
exp asc_desc_option?
;
storage_hash_tag :
STORE IN storage_hash
;
storage_hash :
'(' id_list ')'
;
storage_tag :
storage_tag_nn
| tablespace_clause
| tablespace_clause storage_tag_nn
| storage_tag_nn tablespace_clause
;
storage_tag_nn :
STORAGE '(' storage_list ')'
;
tablespace_clause :
TABLESPACE id local_option?
;
object_table_substitution_clause :
object_table_substitution
;
object_table_substitution :
SUBSTITUTABLE AT_KEYWORD ALL LEVELS
| NOT SUBSTITUTABLE AT_KEYWORD ALL LEVELS
;
oid_clause :
OBJECT IDENTIFIER_KEYWORD IS oid_gen_type
;
oid_gen_type :
SYSTEM GENERATED
| PRIMARY KEY
;
oid_index_clause :
OIDINDEX id
| OIDINDEX id oid_tablespace_clause
| OIDINDEX oid_tablespace_clause
;
oid_tablespace_clause :
'(' oid_tablespace_name? ')'
;
oid_tablespace_name :
TABLESPACE id
;
local_option :
LOCAL
;
storage_list :
storage (COMMA storage)*
;
storage_hashpartmap :
HASHPARTMAP '(' LT_INTEGER ')'
;
storage :
INITIAL LT_INTEGER
| NEXT LT_INTEGER
| MINEXTENTS LT_INTEGER
| ON PRIMARY
| ON id
| FILLFACTOR LT_INTEGER
| CACHE '=' id
| BRANCH LT_INTEGER
| BRANCH '(' LT_INTEGER COMMA LT_INTEGER ')'
| NOBRANCH
| CLUSTERBTR
| SECTION '(' LT_INTEGER ')'
| STAT storage_stat_flag? storage_stat_cols?
| FILESIZE '(' LT_INTEGER ')'
| WITH COUNTER
| WITHOUT COUNTER
| WITH DELTA
| WITHOUT DELTA
| USING LONG ROW
| storage_hashpartmap
;
id_list :
PRIMARY
| id
| id COMMA id_list
| PRIMARY COMMA id_list
;
create_proc_stmt :
CREATE replace_option? PROCEDURE not_exist? full_proc_name2 (WITH ENCRYPTION)? param_def_list_option? invoker_rights_clause_options? func_action
| CREATE replace_option? PROCEDURE not_exist? full_proc_name2 WRAPPED LT_STRING
;
create_package_stmt :
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
| CREATE replace_option? edit_options? pkg_cls_flag not_exist? full_proc_name2 WRAPPED LT_STRING
;
pkg_cls_flag :
PACKAGE
| CLASS
;
blk_end_option :
blk_end_option_low
;
blk_end_option_low :
END
| END id
;
package_def_list_options :
package_def_list
;
package_def_list :
package_def+
;
package_def :
decl_variable
| decl_cursor SEMI
| decl_except
| pragma_def
| PRAGMA RESTRICT_REFERENCES '(' restrict_param_lst ')' SEMI
| decl_plsql_type
| method_inherit_options? method_attr_options? member_static? PROCEDURE id param_def_list_option? SEMI
| method_inherit_options? method_attr_options? member_static? FUNCTION id param_def_list_option? RETURN plsql_datatype func_call_option2_options? pipelined_options? SEMI
| 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
;
restrict_param_lst :
id_list
| DEFAULT COMMA id_list
;
create_package_body_stmt :
create_pkg_body_header encryption_option? is_as package_body_def_list package_body_init_option? blk_end_option
| create_pkg_body_header encryption_option? is_as package_body_init_option? blk_end_option
| create_pkg_body_header WRAPPED LT_STRING
;
create_pkg_body_header :
CREATE replace_option? edit_options? pkg_cls_body_flag full_proc_name2
;
pkg_cls_body_flag :
PACKAGE BODY
| CLASS BODY
;
package_body_init_option :
decl_var_cur_list_1? BEGIN plbody except_option?
;
package_body_def_list :
package_def
| package_body_def
| package_def package_body_def_list
| package_body_def package_body_def_list
;
package_body_def :
method_inherit_options? method_attr_options? member_static? PROCEDURE id param_def_list_option? check_exec_options? is_as dmsubprogram SEMI
| 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
;
package_body_def2 :
PROCEDURE id param_def_list_option? check_exec_options? is_as dmsubprogram SEMI
| FUNCTION id param_def_list_option? RETURN plsql_datatype deterministic_clause_options? pipelined_options? check_exec_options? is_as dmsubprogram SEMI
;
check_exec_options :
EXECUTE CHECK
| EXECUTE NOT CHECK
;
subpg_decl_stmt :
method_inherit_options? method_attr_options? member_static? PROCEDURE id param_def_list_option? SEMI
| method_inherit_options? method_attr_options? member_static? FUNCTION id param_def_list_option? RETURN plsql_datatype SEMI
;
create_type_stmt :
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?
| CREATE replace_option? TYPE full_proc_name2 encryption_option? invoker_rights_clause_options? force_option? is_as plsql_type_def
| CREATE replace_option? TYPE full_proc_name2 WRAPPED LT_STRING
;
force_option :
FORCE
;
object_option :
is_as OBJECT
| UNDER full_proc_name
;
under_option :
UNDER full_proc_name
;
object_def_list_options :
object_def_list
;
object_def_list :
object_def (COMMA object_def)*
;
object_def :
variable_name_list plsql_datatype
| method_inherit_options? method_attr_options? member_static? PROCEDURE id param_def_list_option?
| method_inherit_options? method_attr_options? member_static? FUNCTION id param_def_list_option? RETURN plsql_datatype deterministic_clause_options? pipelined_options?
| method_inherit_options? method_attr_options? member_static? FUNCTION id param_def_list_option? RETURN plsql_datatype deterministic_clause_options? PIPELINED USING plsql_datatype
| method_inherit_options? CONSTRUCTOR FUNCTION id param_def_list_option? RETURN SELF AS RESULT
| PRAGMA RESTRICT_REFERENCES '(' restrict_param_lst ')'
;
member_static :
MEMBER
| STATIC
;
method_inherit_options :
method_inherit_option
;
method_inherit_option :
overriding_option
| final_inst_list
| overriding_option final_inst_list
;
final_inst_list_options :
final_inst_list
;
final_inst_list :
final_inst
| final_inst final_inst_list
;
final_inst :
FINAL
| INSTANTIABLE
| NOT FINAL
| NOT INSTANTIABLE
;
overriding_option :
OVERRIDING
| NOT OVERRIDING
;
method_attr_options :
method_attr
;
method_attr :
MAP
| ORDER
;
create_type_body_stmt :
CREATE replace_option? TYPE BODY full_proc_name2 encryption_option? is_as object_body_def_list END
| CREATE replace_option? TYPE BODY full_proc_name2 WRAPPED LT_STRING
;
object_body_def_list :
object_body_def
| object_body_def object_body_def_list
;
object_body_def :
method_inherit_options? method_attr_options? member_static? PROCEDURE id param_def_list_option? is_as dmsubprogram SEMI
| 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
| method_inherit_options? CONSTRUCTOR FUNCTION id param_def_list_option? RETURN SELF AS RESULT is_as dmsubprogram SEMI
;
create_context_stmt :
CREATE replace_option? CONTEXT not_exist? namespace USING full_object_name initialized?
;
namespace :
id
;
initialized :
ACCESSED LOCALLY
| ACCESSED GLOBALLY
| INITIALIZED EXTERNALLY
| INITIALIZED GLOBALLY
;
create_directory_stmt :
CREATE replace_option? DIRECTORY not_exist? id AS LT_STRING
;
create_crypto_stmt :
CREATE CRYPTO crypto_name pathname
;
alter_crypto_stmt :
alter_tag CRYPTO crypto_name alter_crypto_action
;
alter_crypto_action :
RENAME TO crypto_name
| ADD BLOCK ENCRYPT CIPHER cipher_name INNERID LT_INTEGER BLOCK SIZE LT_INTEGER KEY SIZE LT_INTEGER
| ADD ENCRYPT CIPHER cipher_name INNERID LT_INTEGER KEY SIZE LT_INTEGER
| ADD HASH CIPHER cipher_name INNERID LT_INTEGER HASH SIZE LT_INTEGER
| MODIFY CIPHER cipher_name RENAME TO cipher_name
| DROP CIPHER cipher_name
| ADD CRYPTO HASH LT_STRING
| DROP CRYPTO HASH LT_STRING
;
comment_stmt :
comment_tag ON TABLE full_table_name IS LT_STRING
| comment_tag ON COLUMN full_column_name IS LT_STRING
| comment_tag ON VIEW full_view_name IS LT_STRING
;
comment_tag :
COMMENT
;
create_partition_group_stmt :
CREATE PARTITION GROUP full_table_name PARTITION BY horizon_partition_act_datatype storage_act_datatype?
;
storage_act_datatype :
STORAGE '(' pg_storage_lst ')'
| STORAGE '(' ON full_column_list ')'
;
pg_storage_lst :
pg_storage (COMMA pg_storage)*
;
pg_storage :
ON '(' full_column_list ')'
| storage_hashpartmap
;
create_table_stmt :
CREATE table_temp_option? table_type_option? TABLE not_exist? create_table_action
| CREATE HUGE TABLE not_exist? create_table_action
| CREATE SNAPSHOT TABLE not_exist? full_table_name FROM full_table_name
;
ctab_append_attr_clause :
ctab_append_attr_list
;
ctab_append_attr_list :
ctab_append_attr+
;
cobjtab_append_attr_clause :
cobjtab_append_attr_list
;
cobjtab_append_attr_list :
cobjtab_append_attr
| cobjtab_append_attr cobjtab_append_attr_list
;
ctab_append_attr :
on_commit_option_nn
| logging_option_nn
| partition_clause_nn
| space_limit_nn
| storage_tag_nn
| tablespace_clause
;
cobjtab_append_attr :
oid_clause
| oid_index_clause
;
create_table_action :
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?
| full_table_name '(' table_element_list ')' FROM DEFAULT DIRECTORY id LOCATION '(' pathname ')'
| full_table_name '(' table_element_list ')' FROM DATAFILE? pathname parameters_option_list?
| full_table_name '(' table_element_list ')' FROM DATAFILE DEFAULT DIRECTORY id LOCATION '(' pathname ')' parameters_option_list?
| 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?
| 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?
| 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?
| 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?
;
ctab_log_options :
LOG ctab_log_option
;
ctab_log_option :
ALL
| NONE
| LOB NONE
| LAST
;
ctab_error_options :
WHEN ERROR ctab_error_option
;
advance_log_clause :
WITH ADVANCED LOG
;
add_log_clause :
ADD LOGIC LOG
;
ctab_error_option :
TRUNCATE
| DISABLE
;
ctab_row_movement_clause :
ENABLE ROW MOVEMENT
| DISABLE ROW MOVEMENT
;
range_distribute_act :
VALUES LESS THAN '(' range_partition_exp_list ')' ON id
| VALUES EQU OR LESS THAN '(' range_partition_exp_list ')' ON id
;
range_distribute_act_lst :
range_distribute_act
| range_distribute_act_lst COMMA range_distribute_act
;
list_distribute_act :
VALUES '(' list_partition_value_list ')' ON id
;
list_distribute_act_list :
list_distribute_act (COMMA list_distribute_act)*
;
distribute_by_option :
DISTRIBUTED
| DISTRIBUTED FULLY
| DISTRIBUTED RANDOMLY
| DISTRIBUTED BY '(' column_list ')'
| DISTRIBUTED BY HASH '(' column_list ')'
| DISTRIBUTED BY RANGE '(' column_list ')' '(' range_distribute_act_lst ')'
| DISTRIBUTED BY LIST '(' column_list ')' '(' list_distribute_act_list ')'
;
distribute_by :
distribute_by_option
;
increment_set :
AUTO_INCREMENT '=' LT_INTEGER
| AUTO_INCREMENT LT_INTEGER
;
increment :
increment_set
;
rowdependencies_clause :
ROWDEPENDENCIES
| NOROWDEPENDENCIES
;
pg_sub_partition :
SUBPARTITION BY '(' column_list ')'
;
table_type_option :
VERTICAL
| EXTERNAL
;
table_temp_option :
GLOBAL TEMPORARY
| LOCAL TEMPORARY
| TEMPORARY
| SHARE TEMPORARY
;
objtab_elem_constraint :
'(' objtab_element_cons_list ')'
;
objtab_element_cons_list :
objtab_element_cons (COMMA objtab_element_cons_list)*
;
objtab_element_cons :
objcol_constraint
| table_constraint_def
;
objcol_constraint :
column_name charset_option? collate_clause_option? column_def_4_option? storage_tag? encrypt_clause_options? compress_clause_opt?
;
table_element_list :
table_element (COMMA table_element)*
;
table_element :
column_def_ex
| table_constraint_def
;
table_constraint_def :
constraint_name_def_options? table_constraint_clause cons_enable?
;
on_commit_option :
on_commit_option_nn
;
on_commit_option_nn :
ON COMMIT del_res ROWS
;
logging_option :
logging_option_nn
;
logging_option_nn :
LOGGING
| NOLOGGING
;
partition_clause :
partition_clause_nn
;
partition_clause_nn :
PARTITION BY partition_act
;
horizon_partition_clause :
PARTITION BY horizon_partition_act
;
compress_tag_hdr :
COMPRESS compress_level? compress_type?
;
compress_clause_opt :
compress_tag_hdr
;
compress_tag :
compress_tag_hdr
| compress_tag_hdr '(' column_list ')'
| compress_tag_hdr EXCEPT '(' column_list ')'
;
compress_level :
LEVEL LT_INTEGER
;
compress_type :
FOR LT_STRING
;
range_partition :
PARTITION full_partition_name VALUES LESS THAN '(' range_partition_exp_list ')' storage_tag? subpartition_desc_option?
| PARTITION full_partition_name VALUES EQU OR LESS THAN '(' range_partition_exp_list ')' storage_tag? subpartition_desc_option?
;
range_partition_list :
range_partition (COMMA range_partition)*
;
hash_partition :
PARTITION full_partition_name storage_tag? subpartition_desc_option?
;
hash_partition_list :
hash_partition (COMMA hash_partition)*
;
list_partition :
PARTITION full_partition_name VALUES '(' list_partition_value_list ')' storage_tag? subpartition_desc_option?
;
list_partition_list :
list_partition (COMMA list_partition)*
;
split_partition_list :
hash_partition (COMMA hash_partition)*
;
partition_act :
horizon_partition_act
| vertical_partition_act
;
vertical_partition_act :
COLUMN '(' column_list ')' as_alias?
| COLUMN '(' column_list_list ')'
;
interval_item :
INTERVAL '(' exp ')'
;
horizon_partition_act_datatype :
RANGE '(' datatype_list ')' subpartion_template_list_datatype_options? '(' range_partition_list ')'
| HASH '(' datatype_list ')' subpartion_template_list_datatype_options? PARTITIONS (LT_INTEGER | DEFAULT) storage_hash_tag?
| HASH '(' datatype_list ')' subpartion_template_list_datatype_options? '(' hash_partition_list ')'
| LIST '(' datatype_list ')' subpartion_template_list_datatype_options? '(' list_partition_list ')'
;
horizon_partition_act :
RANGE '(' column_list ')' interval_item? subpartion_template_list_options? '(' range_partition_list ')' lock_partitions_clause?
| HASH '(' column_list ')' subpartion_template_list_options? PARTITIONS (LT_INTEGER | DEFAULT) storage_hash_tag? lock_partitions_clause?
| HASH '(' column_list ')' subpartion_template_list_options? '(' hash_partition_list ')' lock_partitions_clause?
| LIST '(' column_list ')' subpartion_template_list_options? '(' list_partition_list ')' lock_partitions_clause?
| REFERENCE '(' constraint_name ')'
;
lock_partitions_clause :
LOCK ROOT
| LOCK PARTITIONS
;
subpartion_template_list_datatype_options :
subpartion_template_list_datatype
;
subpartion_template_list_datatype :
subpartion_template_datatype (COMMA subpartion_template_datatype)*
;
subpartion_template_list_options :
subpartion_template_list
;
subpartion_template_list :
subpartion_template (COMMA subpartion_template)*
;
subpartion_template_datatype :
range_subpartion_template_datatype
| hash_subpartion_template_datatype
| list_subpartion_template_datatype
;
range_subpartion_template_datatype :
SUBPARTITION BY RANGE '(' datatype_list ')'
| SUBPARTITION BY RANGE '(' datatype_list ')' SUBPARTITION TEMPLATE '(' range_subpartition_list ')'
;
hash_subpartion_template_datatype :
SUBPARTITION BY HASH '(' datatype_list ')' ((SUBPARTITION TEMPLATE)? hash_subpartions_template_datatype_option)?
| SUBPARTITION BY HASH '(' datatype_list ')' SUBPARTITION TEMPLATE '(' hash_subpartition_list ')'
;
hash_subpartions_template_datatype_option :
SUBPARTITIONS (LT_INTEGER | DEFAULT) storage_hash_tag?
;
list_subpartion_template_datatype :
SUBPARTITION BY LIST '(' datatype_list ')'
| SUBPARTITION BY LIST '(' datatype_list ')' SUBPARTITION TEMPLATE '(' list_subpartition_list ')'
;
subpartion_template :
range_subpartion_template
| hash_subpartion_template
| list_subpartion_template
;
range_subpartion_template :
SUBPARTITION BY RANGE '(' column_list ')'
| SUBPARTITION BY RANGE '(' column_list ')' SUBPARTITION TEMPLATE '(' range_subpartition_list ')'
;
hash_subpartion_template :
SUBPARTITION BY HASH '(' column_list ')' ((SUBPARTITION TEMPLATE)? hash_subpartions_template_option)?
| SUBPARTITION BY HASH '(' column_list ')' SUBPARTITION TEMPLATE '(' hash_subpartition_list ')'
;
hash_subpartions_template_option :
SUBPARTITIONS (LT_INTEGER | DEFAULT) storage_hash_tag?
;
list_subpartion_template :
SUBPARTITION BY LIST '(' column_list ')' (SUBPARTITION TEMPLATE '(' list_subpartition_list ')')?
;
range_subpartition :
SUBPARTITION full_partition_name VALUES LESS THAN '(' range_partition_exp_list ')' storage_tag?
| SUBPARTITION full_partition_name VALUES EQU OR LESS THAN '(' range_partition_exp_list ')' storage_tag?
;
hash_subpartition :
SUBPARTITION full_partition_name storage_tag?
;
list_subpartition :
SUBPARTITION full_partition_name VALUES '(' list_partition_value_list ')' storage_tag?
;
range_subpartition_list :
range_subpartition (COMMA range_subpartition)*
;
hash_subpartition_list :
hash_subpartition (COMMA hash_subpartition)*
;
list_subpartition_list :
list_subpartition (COMMA list_subpartition)*
;
subpartition_hash_desc :
hash_subpartition subpartition_desc_option?
;
subpartition_range_desc :
range_subpartition subpartition_desc_option?
;
subpartition_list_desc :
list_subpartition subpartition_desc_option?
;
subpartition_hash_desc_list :
subpartition_hash_desc (COMMA subpartition_hash_desc)*
;
subpartition_range_desc_list :
subpartition_range_desc (COMMA subpartition_range_desc)*
;
subpartition_list_desc_list :
subpartition_list_desc (COMMA subpartition_list_desc)*
;
subpartition_desc :
'(' subpartition_range_desc_list ')'
| '(' subpartition_hash_desc_list ')'
| '(' subpartition_list_desc_list ')'
| SUBPARTITIONS LT_INTEGER storage_hash_tag?
;
subpartition_desc_option :
subpartition_desc
;
add_subpartition_desc :
subpartition_range_desc_list
| subpartition_hash_desc_list
| subpartition_list_desc_list
;
partition_no :
RANGE LT_INTEGER
| LT_INTEGER
;
comment_clause :
COMMENT LT_STRING
;
encrypt_clause_options :
encrypt_clause
;
encrypt_clause :
NO ENCRYPT
| ENCRYPT
| ENCRYPT encrypt_cipher
| ENCRYPT encrypt_cipher hash_cipher
| FULL ENCRYPT WITH full_cipher_name
;
encrypt_cipher :
WITH full_cipher_name
| WITH full_cipher_name encrypt_type
| encrypt_type
;
crypto_name :
id
;
cipher_name :
id
;
full_cipher_name :
id
;
encrypt_type :
MANUAL
| MANUAL manual_clause
| AUTO
| AUTO BY password
| AUTO BY WRAPPED LT_STRING
;
manual_clause :
user_clause
| BY password user_clause_options?
| BY WRAPPED LT_STRING user_clause_options?
;
user_clause_options :
user_clause
;
user_clause :
USER '(' user_list_option? ')'
;
user_list_option :
user_list
;
user_list :
user_name (COMMA user_list)*
;
hash_cipher :
HASH WITH full_cipher_name
| HASH WITH full_cipher_name hash_type
;
hash_type :
SALT
| NO SALT
;
space_limit :
space_limit_nn
;
space_limit_nn :
DISKSPACE LIMIT LT_INTEGER
| DISKSPACE UNLIMITED
;
space_limit_1 :
DISKSPACE LIMIT LT_INTEGER
| DISKSPACE UNLIMITED
;
space_limit2 :
DISKSPACE LIMIT LT_INTEGER
| DISKSPACE UNLIMITED
;
del_res :
DELETE
| PRESERVE
;
trig_enable :
ENABLE
| DISABLE
;
at_raft :
EXECUTE AT_KEYWORD id
| EXECUTE AT_KEYWORD LT_INTEGER
;
create_trigger_stmt :
CREATE replace_option? TRIGGER full_trigger_name2 (WITH ENCRYPTION)? before_after
((trig_del_ins_upd_list local? ON full_table_name2) | (trig_event_list local? ON event_object at_raft?))
trig_referencing_def_options? trig_for_each_option? trig_when_option? trig_enable? dmsubprogram
| CREATE replace_option? TRIGGER full_trigger_name2 WRAPPED LT_STRING
;
before_after :
BEFORE
| AFTER
| INSTEAD OF
;
trig_del_ins_upd_list :
(trig_del_ins_upd (OF column_list)?) (OR (trig_del_ins_upd (OF column_list)?))*
;
trig_del_ins_upd :
DELETE
| INSERT
| UPDATE
;
update_of_option :
UPDATE nowait?
| UPDATE OF full_column_list nowait?
;
nowait :
NOWAIT
| WAIT LT_INTEGER
| SKIP_KEYWORD LOCKED
| LT_INTEGER SKIP_KEYWORD LOCKED
;
trig_event_list :
trig_event (OR trig_event)*
;
trig_event :
CREATE
| ALTER
| DROP
| AUDIT
| NOAUDIT
| GRANT
| REVOKE
| TRUNCATE
| ANALYZE
| LOGIN
| LOGON
| LOGOUT
| LOGOFF
| SERERR
| BACKUP DATABASE
| RESTORE DATABASE
| TIMER
| STARTUP
| SHUTDOWN
| COMMENT
| DDL
| CHECKPOINT
;
event_object :
qualified_name '.' SCHEMA
| SCHEMA
| DATABASE
;
trig_referencing_def_options :
trig_referencing_def
;
trig_referencing_def :
REFERENCING trig_referencing_list
;
trig_referencing_list :
trig_referencing_old
| trig_referencing_new
| trig_referencing_old trig_referencing_new
;
trig_referencing_old :
OLD row_tag? as_tag? trig_old_name
;
trig_referencing_new :
NEW row_tag? as_tag? trig_new_name
;
trig_for_each_option :
FOR EACH ROW
| FOR EACH STATEMENT
| trig_timer_rate
;
trig_timer_rate :
FOR ONCE AT_KEYWORD DATETIME LT_STRING max_run_duration? exec_ep_seqno?
| rate_over_day rate_in_day duaring_date? max_run_duration? exec_ep_seqno?
| repeat_interval duaring_date? max_run_duration? exec_ep_seqno?
;
exec_ep_seqno :
EXECUTE AT_KEYWORD LT_INTEGER
;
rate_over_day :
month_rate
| week_rate
| day_rate
;
month_rate :
FOR EACH LT_INTEGER MONTH day_in_month
| FOR EACH LT_INTEGER MONTH day_in_month_week
;
day_in_month :
DAY LT_INTEGER
;
day_in_month_week :
DAY LT_INTEGER OF WEEK LT_INTEGER
| DAY LT_INTEGER OF WEEK LAST
;
week_rate :
FOR EACH LT_INTEGER WEEK day_of_week_list
;
day_of_week_list :
LT_INTEGER (COMMA LT_INTEGER)*
;
day_rate :
FOR EACH LT_INTEGER DAY
;
rate_in_day :
once_in_day
| times_in_day
;
once_in_day :
AT_KEYWORD TIME LT_STRING
;
times_in_day :
duaring_time? FOR EACH LT_INTEGER MINUTE
| duaring_time? FOR EACH LT_INTEGER SECOND
;
duaring_time :
FROM TIME LT_STRING
| FROM TIME LT_STRING TO TIME LT_STRING
;
duaring_date :
FROM DATETIME LT_STRING
| FROM DATETIME LT_STRING TO DATETIME LT_STRING
;
trig_when_option :
WHEN '(' trig_when_condition ')'
;
trig_when_condition :
bool_exp
;
repeat_interval_stmt :
repeat_interval
;
max_run_duration :
MAX_RUN_DURATION LT_INTEGER
;
repeat_interval :
frequency_clause (SEMI interval_clause_single*)?
;
frequency_clause :
FREQ '=' frequency_define
;
frequency_define :
predefined_frequency
;
predefined_frequency :
YEARLY
| MONTHLY
| WEEKLY
| DAILY
| HOURLY
| MINUTELY
| SECONDLY
;
interval_clause_list :
interval_clause_single (SEMI interval_clause_single)*
;
interval_clause_single :
interval_clause
| bymonth_clause
| byweekno_clause
| byyearday_clause
| bymonthday_clause
| byday_clause
| byhour_clause
| byminute_clause
| bysecond_clause
;
interval_clause :
INTERVAL '=' intervalnum
;
intervalnum :
LT_INTEGER
;
bymonth_clause :
BYMONTH '=' monthlist
;
monthlist :
month
| monthlist COMMA month
;
month :
numeric_month
| char_month
;
numeric_month :
LT_INTEGER
;
char_month :
JAN
| FEB
| MAR
| APR
| MAY
| JUN
| JUL
| AUG
| SEP
| OCT
| NOV
| DEC
;
byweekno_clause :
BYWEEKNO '=' weekno_list
;
weekno_list :
weekno (COMMA weekno)*
;
weekno :
lt_integer_negative
;
byyearday_clause :
BYYEARDAY '=' yearday_list
;
yearday_list :
yearday (COMMA yearday)*
;
yearday :
lt_integer_negative
;
bymonthday_clause :
BYMONTHDAY '=' monthday_list
;
monthday_list :
monthday (COMMA monthday)*
;
monthday :
lt_integer_negative
;
byday_clause :
BYDAY '=' byday_list
;
byday_list :
byday (COMMA byday)*
;
byday :
weekdaynum_options? day
;
weekdaynum_options :
weekdaynum
;
weekdaynum :
lt_integer_negative
;
day :
MON
| TUE
| WED
| THU
| FRI
| SAT
| SUN
;
byhour_clause :
BYHOUR '=' hour_list
;
hour_list :
hour (COMMA hour)*
;
hour :
LT_INTEGER
;
byminute_clause :
BYMINUTE '=' minute_list
;
minute_list :
minute (COMMA minute)*
;
minute :
LT_INTEGER
;
bysecond_clause :
BYSECOND '=' second_list
;
second_list :
second (COMMA second)*
;
second :
LT_INTEGER
;
query_rewrite :
ENABLE QUERY REWRITE
| DISABLE QUERY REWRITE
;
build_clause :
BUILD IMMEDIATE
| BUILD DEFERRED
;
mv_refresh_option :
ON DEMAND
| ON COMMIT
| WITH PRIMARY KEY
| WITH ROWID
| START WITH exp
| NEXT exp
| FAST
| COMPLETE
| FORCE
| complete_del_null
;
mv_refresh_option_list :
mv_refresh_option+
;
mv_refresh_clause :
REFRESH mv_refresh_option_list
| NEVER REFRESH
;
mv_log_purge_syn_asyn_clause :
SYNCHRONOUS
| ASYNCHRONOUS
;
mv_log_purge_clause :
PURGE REPEAT exp
| PURGE START WITH exp REPEAT exp
| PURGE IMMEDIATE mv_log_purge_syn_asyn_clause?
| PURGE START WITH exp NEXT exp
| PURGE START WITH exp
| PURGE NEXT exp
;
mv_log_with_syntax_item :
PRIMARY KEY
| ROWID
| SEQUENCE
;
mv_log_with_syntax_item_list :
mv_log_with_syntax_item
| mv_log_with_syntax_item COMMA mv_log_with_syntax_item
| mv_log_with_syntax_item COMMA mv_log_with_syntax_item COMMA mv_log_with_syntax_item
;
mv_log_including_new_values :
INCLUDING NEW VALUES
| EXCLUDING NEW VALUES
;
mv_log_with_clause_null :
mv_log_including_new_values?
| WITH mv_log_with_syntax_item_list? column_list_options? mv_log_including_new_values?
;
create_materialized_view_log_stmt :
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?
;
prebuilt_table_clause_null :
ON PREBUILT TABLE
| ON PREBUILT TABLE WITHOUT REDUCED PRECISION
| ON PREBUILT TABLE WITH REDUCED PRECISION
;
create_materialized_view_stmt :
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
| 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
| CREATE MATERIALIZED VIEW FOR full_table_name mv_refresh_clause? AS select_stmt
| CREATE MATERIALIZED VIEW full_view_name2 FOR full_table_name prebuilt_table_clause_null mv_refresh_clause? query_rewrite? AS select_stmt
;
create_view_stmt :
CREATE replace_option? force? VIEW not_exist? create_view_stmt_body
;
create_view_stmt_body :
full_view_name2 column_list3_options? with_schemabinding? AS (without_into_select2 with_check_or_readonly_option? | joined_table | TABLE full_tv_name)
;
column_list3_options :
'(' column_list3 ')'
;
column_list3 :
column_name compress_level? compress_type?
| column_list3 COMMA column_name compress_level? compress_type?
| column_list3 COMMA view_constraint_def
| column_name view_column_constraint_def
| column_list3 COMMA column_name view_column_constraint_def
;
view_column_constraint_def :
view_column_constraints constraint_attributes_options?
;
view_column_constraints :
view_column_constraint
;
view_column_constraint :
constraint_name_def_options? view_column_constraint_action DISABLE cons_novalidate?
;
view_column_constraint_action :
view_unique_spec
| view_refs_spec
;
view_constraint_def :
constraint_name_def_options? view_constraint_clause DISABLE cons_novalidate?
;
with_schemabinding :
WITH SCHEMABINDING
;
column_list_options :
'(' column_list ')'
;
with_check_or_readonly_option :
WITH check_level_option? CHECK OPTION
| WITH READ ONLY
;
check_level_option :
LOCAL
| CASCADED
;
decl_cursor :
cursor_declaration_2
;
delete_stmt :
with_option? DELETE delete_stmt_body
;
delete_stmt_body :
from_tag? from_tv where_current_option return_into_obj? limit_option? check_limit_option? log_errors?
| from_tag? full_tv_name delete_multi_tv_option where_current_option return_into_obj? limit_option? check_limit_option? log_errors?
;
delete_multi_tv_option :
FROM from_tv_list
| USING from_tv_list
;
check_limit_option :
CHECK LIMIT LT_INTEGER
;
where_current_option :
where_clause?
| WHERE CURRENT OF qualified_name
| WHERE CURRENT OF CURSOR
;
where_clause :
WHERE search_condition
;
start_with_clause_null :
START WITH search_condition
;
connect_by_item :
CONNECT BY nocycle_flag? search_condition
;
connect_by_clause :
connect_by_item+
;
hierarchical_query_clause :
connect_by_clause start_with_clause_null?
| start_with_clause_null connect_by_clause
;
nocycle_flag :
NOCYCLE
;
search_condition :
bool_exp
;
disconnect_stmt :
DISCONNECT disconnect_option
;
disconnect_option :
CURRENT
| ALL
;
drop_stmt :
DROP drop_db_object drop_stmt_body_1
| drop_stmt_2
;
drop_stmt_body_1 :
full_object_name restrict_cascade? purge_option? is_detach?
| LOG ON full_table_name
;
drop_stmt_2 :
DROP drop_id_db_object full_object_name restrict_cascade? is_detach?
| DROP PUBLIC drop_db_object full_object_name restrict_cascade? is_detach?
| DROP PUBLIC drop_id_db_object full_object_name restrict_cascade? is_detach?
| DROP TABLESPACE exist? tablespace_name
| DROP HUGE TABLESPACE exist? full_object_name
| DROP PARTITION GROUP full_object_name force_option?
;
drop_id_db_object :
id_db_object exist?
;
id_db_object :
ROLE
| TYPE
| SEQUENCE
| DIRECTORY
| PACKAGE
| LINK
| PROFILE
;
drop_db_object :
db_object exist?
;
exist :
IF EXISTS
;
not_exist :
IF NOT EXISTS
;
db_object :
FUNCTION
| INDEX
| PROCEDURE
| TABLE
| TRIGGER
| VIEW
| MATERIALIZED VIEW
| USER
| SCHEMA
| LOGIN
| AUDIT RULE
| CRYPTO
| PACKAGE BODY
| TYPE BODY
| SYNONYM
| CLASS
| CLASS BODY
| DOMAIN
| CHARACTER SET
| COLLATION
| CONTEXT
| TABLESPACE SET
;
is_detach :
DETACH
;
purge_option :
PURGE
;
alter_database_stmt :
alter_tag DATABASE alter_database_action
| alter_tag DATABASE ADD NODE LOGFILE file_list
| alter_tag DATABASE ADD NODE
| alter_tag SYSTEM alter_system_action
;
alter_system_action :
ARCHIVE LOG CURRENT
| SWITCH LOGFILE
;
alter_database_action :
ADD LOGFILE file_list
| RENAME LOGFILE pathname_list TO pathname_list
| RESIZE LOGFILE pathname TO LT_INTEGER
| MOUNT
| OPEN force?
| SUSPEND
| NORMAL force?
| PRIMARY force?
| STANDBY force?
| ADD ARCHIVELOG LT_STRING
| DELETE ARCHIVELOG LT_STRING
| MODIFY ARCHIVELOG LT_STRING
| ARCHIVELOG
| NOARCHIVELOG
| ARCHIVELOG CURRENT
| ENABLE BLOCK CHANGE TRACKING
| DISABLE BLOCK CHANGE TRACKING
;
force :
NO FORCE
| FORCE
;
tablespace_name :
id
;
raft_name :
id
;
fetch_into :
INTO assignment_obj_list
;
bulk_or_single_into :
fetch_into
| BULK COLLECT INTO assignment_obj_list
;
fetch_stmt :
FETCH fetch_tail
;
fetch_statement :
FETCH CURSOR fetch_tail
;
fetch_tail :
fetch_option? assign_obj bulk_or_single_into? fetch_limit_option?
;
fetch_limit_option :
LIMIT exp
;
fetch_option :
fetch_direct_option from_tag?
;
fetch_direct_option :
NEXT
| PRIOR
| FIRST
| LAST2
| ABSOLUTE top_exp
| RELATIVE top_exp
;
log_errors_into :
INTO full_tv_name
;
log_errors_expression :
'(' exp ')'
;
log_errors_unlimited :
REJECT LIMIT UNLIMITED
| REJECT LIMIT LT_INTEGER
;
log_errors :
LOG ERRORS log_errors_into? log_errors_expression? log_errors_unlimited
;
insert_stmt :
INSERT insert_stmt_body
;
insert_stmt_body :
into_tag? full_tv_name alias_option? insert_tail return_into_obj? log_errors?
| into_tag? select_with_paran alias_option? insert_tail return_into_obj? log_errors?
| multi_insert_stmt_body
;
full_column_list_options :
'(' full_column_list ')'
;
ins_value_options :
VALUES ins_value
;
insert_into_single :
INTO full_tv_name alias_option? full_column_list_options? ins_value_options?
;
multi_insert_into_list :
insert_into_single+
;
multi_insert_tag :
ALL
| FIRST
;
insert_into_single_condition :
WHEN bool_exp THEN multi_insert_into_list
;
multi_insert_into_condition_list :
insert_into_single_condition+
;
multi_insert_into_else :
ELSE multi_insert_into_list
;
multi_insert_stmt_body :
ALL multi_insert_into_list without_into_select2 log_errors?
| multi_insert_tag? multi_insert_into_condition_list multi_insert_into_else? without_into_select2 log_errors?
;
insert_tail :
insert_action
| '(' full_column_list ')' insert_action
;
insert_action :
VALUES ins_value
| without_into_select2
| DEFAULT VALUES
| call_proc_stmt_2
| VALUES record_var_values
| TABLE full_tv_name
;
record_var_values :
record_var_value (COMMA record_var_value)*
;
record_var_value :
member
| invocation_expression
| element_access
| member_access
;
ins_value :
'(' ')'
| '(' ins_value_list ')'
| ins_value COMMA '(' ins_value_list ')'
;
open_stmt :
OPEN open_tail
;
open_statement :
OPEN CURSOR open_tail
;
open_tail :
assign_obj2
| assign_obj2 FOR without_into_select
| assign_obj2 FOR exp using_clause?
;
return_stmt :
RETURN
| RETURN bool_exp
;
raise_stmt :
RAISE exp
| RAISE
;
rollback_stmt :
ROLLBACK work_tag? commit_tail? to_savepoint?
;
to_savepoint :
TO SAVEPOINT savepoint_name
| TO savepoint_name
;
savepoint_stmt :
SAVEPOINT savepoint_name
;
select_stmt :
without_into_select2
;
all_distinct_option :
ALL
| DISTINCT
| UNIQUE
;
all_distinct_option_2 :
ALL
| DISTINCT
| UNIQUE
;
corresponding_clause :
CORRESPONDING
| CORRESPONDING BY '(' column_list ')'
;
top_option :
TOP top_exp PERCENT? (WITH TIES)?
| TOP top_exp COMMA top_exp
;
limit_option :
limit_clause
| row_limiting_clause
;
limit_clause :
LIMIT top_exp ((OFFSET | COMMA) top_exp)?
| OFFSET top_exp LIMIT top_exp
;
limit_not_empty :
limit_clause
| row_limiting_clause
;
row_limiting_clause :
FETCH first_next_desc row_num_desc ONLY
| FETCH first_next_desc top_exp row_num_desc ONLY
| FETCH first_next_desc row_num_desc WITH TIES
| FETCH first_next_desc top_exp row_num_desc WITH TIES
| FETCH first_next_desc top_exp PERCENT row_num_desc ONLY
| FETCH first_next_desc top_exp PERCENT row_num_desc WITH TIES
| OFFSET top_exp row_num_desc
| OFFSET top_exp row_num_desc FETCH first_next_desc row_num_desc ONLY
| OFFSET top_exp row_num_desc FETCH first_next_desc top_exp row_num_desc ONLY
| OFFSET top_exp row_num_desc FETCH first_next_desc row_num_desc WITH TIES
| OFFSET top_exp row_num_desc FETCH first_next_desc top_exp row_num_desc WITH TIES
| OFFSET top_exp row_num_desc FETCH first_next_desc top_exp PERCENT row_num_desc ONLY
| OFFSET top_exp row_num_desc FETCH first_next_desc top_exp PERCENT row_num_desc WITH TIES
;
row_num_desc :
ROW
| ROWS
;
first_next_desc :
FIRST
| NEXT
;
select_item_list :
select_item (COMMA select_item)*
;
select_item :
exp (alias | AS alias_2)
| bool_exp
| '*'
;
as_alias :
AS alias_2
;
select_tail :
from_clause? where_clause? hierarchical_query_clause? (group_by_clause having_clause? | having_clause group_by_clause?)?
;
from_clause :
FROM from_tv_list
;
from_tv_list :
from_tv (COMMA from_tv)*
;
from_tv :
normal_tv joined_table_element*
| '(' normal_tv joined_table_element+ ')'
;
joined_table :
normal_tv joined_table_element+
| '(' normal_tv joined_table_element+ ')'
;
trxid :
LT_INTEGER
;
flashback_query_low :
WHEN TIMESTAMP exp
| WHEN TRXID trxid
| AS OF TIMESTAMP exp
| AS OF scn_or_lsn trxid
| VERSIONS BETWEEN TIMESTAMP exp AND exp
| VERSIONS BETWEEN TRXID trxid AND trxid
| VERSIONS BETWEEN scn_or_lsn trxid_option AND trxid_option
| AFTER OF TIMESTAMP exp
| AFTER OF scn_or_lsn trxid
;
trxid_option :
trxid
| MINVALUE
| MAXVALUE
;
range_from_to :
TOP LT_INTEGER
| FROM LT_INTEGER TO LT_INTEGER
;
sample_exp :
LT_DECIMAL
| LT_INTEGER
| LT_REAL
;
pivot_sfun :
invocation_expression as_alias?
| invocation_expression alias
;
pivot_sfun_lst :
pivot_sfun (COMMA pivot_sfun)*
;
pivot_for_clause :
FOR '(' exp_list_2 ')'
| FOR exp
;
pivot_in_clause1_expr :
exp as_alias?
| exp alias
| '(' exp_list_2 ')' as_alias?
| '(' exp_list_2 ')' alias
| ANY
;
pivot_in_clause_low_1 :
pivot_in_clause1_expr
| pivot_in_clause_low_1 COMMA pivot_in_clause1_expr
;
pivot_in_clause_low_2 :
without_into_select
;
pivot_in_clause_low :
pivot_in_clause_low_1
| pivot_in_clause_low_2
;
pivot_xml :
XML
;
pivot_clause_low :
PIVOT pivot_xml? '(' pivot_sfun_lst pivot_for_clause IN '(' pivot_in_clause_low? ')' ')'
;
unpivot_val_col_lst :
exp
| '(' exp_list_2 ')'
;
include_clause :
INCLUDE NULLS
| EXCLUDE NULLS
;
unpivot_in_clause_expr :
exp AS exp
| exp
| '(' exp_list_2 ')' AS '(' exp_list_2 ')'
| '(' exp_list_2 ')' AS exp
| '(' exp_list_2 ')'
;
unpivot_in_clause_low :
unpivot_in_clause_expr (COMMA unpivot_in_clause_expr)*
;
unpivot_clause_low :
UNPIVOT include_clause? '(' unpivot_val_col_lst pivot_for_clause IN '(' unpivot_in_clause_low ')' ')'
;
sample_clause_low :
SAMPLE '(' sample_exp ')'
| SAMPLE '(' sample_exp ')' SEED '(' sample_exp ')'
| SAMPLE BLOCK '(' sample_exp ')'
| SAMPLE BLOCK '(' sample_exp ')' SEED '(' sample_exp ')'
;
normal_tv_name :
full_tv_name
| '(' full_tv_name ')'
;
normal_tv_tail :
normal_tv_tail_low (WITH '(' NOLOCK ')')?
| WITH '(' NOLOCK ')' normal_tv_tail_low?
;
normal_tv_tail_low :
normal_tv_tail_low2 normal_alias?
| normal_alias
;
normal_alias :
AS alias_2
| alias
;
normal_tv_tail_low2 :
normal_tv_tail_low3+
;
normal_tv_tail_low3 :
normal_alias? (pivot_clause_low | unpivot_clause_low)
| flashback_query_low
| sample_clause_low
;
normal_tv_derived_table_options :
normal_tv_derived_table_low
;
normal_tv_derived_table_low :
normal_tv_tail_low2 (normal_alias column_list_options?)?
| normal_alias column_list_options?
;
normal_tv_derived_table :
select_with_paran
| select_with_paran_with_alias
;
select_with_paran_with_alias :
select_with_paran normal_tv_derived_table_low
| '(' select_with_paran_with_alias ')' normal_alias ?
;
from_table_exp :
TABLE '(' exp ')'
| '(' from_table_exp ')'
;
from_table_select_with_paran :
TABLE select_with_paran
| '(' from_table_select_with_paran ')'
;
normal_tv :
normal_tv_name normal_tv_tail?
| ARRAY pexp_pfx range_from_to? (as_alias | alias)?
| from_table_exp range_from_to? alias
| from_table_select_with_paran range_from_to? (as_alias | alias)?
| XMLTABLE '(' exp xml_passing? xmlcoldef_lst_options? ')' alias_option?
| JSON_TABLE '(' argument COMMA LT_STRING on_error? jsoncol_lst ')' (as_alias | alias)?
| normal_tv_derived_table
| full_tv_name '(' column_list2 ')' normal_tv_derived_table_options?
;
xml_passing :
PASSING exp
;
xmlcoldef_lst_options :
COLUMNS xmlcoldef_lst
;
xmlcoldef_lst :
xmlcoldef (COMMA xmlcoldef)*
;
xmlcoldef :
column_name datatype PATH exp
;
on_error :
NULL ON ERROR
| ERROR ON ERROR
| DEFAULT exp ON ERROR
;
jsoncol_lst :
COLUMNS '(' jsoncoldef_lst ')'
;
jsoncoldef_lst :
jsoncoldef (COMMA jsoncoldef)*
;
jsoncoldef :
json_exists_col
| json_qurey_col
| json_value_col
| json_nested_col
| ordinality_col
;
json_exists_col :
column_name datatype EXISTS PATH LT_STRING on_error?
;
json_qurey_col :
column_name datatype FORMAT JSON PATH LT_STRING on_error?
;
json_value_col :
column_name datatype PATH LT_STRING on_error?
;
json_nested_col :
NESTED_PATH LT_STRING jsoncol_lst
;
ordinality_col :
column_name FOR ORDINALITY
;
joined_table_element :
cross_join
| qualified_join
| cross_outer_apply_join
;
cross_outer_apply_clause :
CROSS APPLY
| OUTER APPLY
;
cross_outer_apply_join :
cross_outer_apply_clause normal_tv
| cross_outer_apply_clause '(' joined_table ')'
;
cross_join :
CROSS JOIN normal_tv
| CROSS JOIN '(' joined_table ')'
;
partition_out_join :
PARTITION BY '(' exp_list ')'
;
qualified_join :
NATURAL JOIN normal_tv
| NATURAL JOIN '(' joined_table ')'
| NATURAL join_type JOIN normal_tv
| NATURAL join_type JOIN '(' joined_table ')'
| JOIN from_tv qualified_joinspec
| partition_out_join? join_type join_hint? JOIN from_tv partition_out_join? qualified_joinspec
;
qualified_joinspec :
ON join_condition
| named_columns_join
;
named_columns_join :
USING '(' column_list ')'
;
join_hint :
HASH
| MERGE
;
join_type :
INNER
| outer_join_type (INNER | OUTER)?
;
outer_join_type :
LEFT
| RIGHT
| FULL
;
join_condition :
bool_exp
;
group_by_clause :
GROUP BY group_item
;
group_item :
exp_rollup_cube_item
| exp_rollup_cube_item2
;
exp_rollup_cube_item2 :
exp_rollup_cube_item COMMA exp_rollup_cube_item
| exp_rollup_cube_item2 COMMA exp_rollup_cube_item
;
exp_rollup_cube_item :
exp
| '(' ')'
| '(' exp_list_2 ')'
| ROLLUP '(' grouping_set_items ')'
| CUBE '(' grouping_set_items ')'
| GROUPING SETS '(' grouping_set_items ')'
;
grouping_set_items :
grouping_set_item
| grouping_set_items COMMA grouping_set_item
;
grouping_set_item :
exp
| '(' ')'
| '(' exp_list_2 ')'
;
having_clause :
HAVING search_condition
;
without_into_select :
(simple_select | select_with_paran) (sel_clause_app for_xml_path?)?
;
sel_clause_app :
order_by ((for_update limit_option?) | (limit_not_empty for_update_options?))?
| for_update order_by? limit_option?
| limit_not_empty order_by? for_update_options?
;
select_clause :
query_exp
| select_with_paran
;
simple_select :
select_clause ( (UNION | EXCEPT | MINUS | INTERSECT) all_distinct_option? corresponding_clause? select_clause)*
;
select_with_paran :
'(' without_into_select ')'
| '(' select_with_paran ')'
;
query_exp :
with_option? SELECT all_distinct_option? top_option? select_item_list bulk_or_single_into? select_tail for_xml_path?
;
for_xml_path :
FOR XML PATH '(' LT_STRING ')'
;
with_tag :
WITH
| WITH RECURSIVE
;
with_option :
with_tag with_clause
;
with_clause :
with_function_list
| with_view_list
| with_function_list with_view_list
;
with_function_list :
with_function_list_element+
;
func_def_inner :
encryption_option? calc_option? param_def_list_option? RETURN plsql_datatype func_call_options? func_action
;
with_function_list_element :
FUNCTION id func_def_inner SEMI
;
with_view_list :
with_view_list_element (COMMA with_view_list_element)*
;
depth_type_option :
DEPTH FIRST BY
| BREADTH FIRST BY
;
search_clause :
SEARCH depth_type_option order_by_list SET full_column_name
;
cycle_clause :
CYCLE full_column_list SET full_column_name TO default_exp DEFAULT default_exp
;
with_view_list_element :
id column_list_options? AS select_with_paran search_clause? cycle_clause?
;
assignment_obj_list :
assignment_obj (COMMA assignment_obj)*
;
assignment_obj :
pexp_pfx
| stm_param_name
;
order_by_options :
order_by
;
order_by :
ORDER BY order_by_list
| ORDER SIBLINGS BY order_by_list
;
asc_desc_option :
ASC
| DESC
;
nulls_last_option :
NULLS FIRST
| NULLS LAST
;
collate_option :
COLLATE id
;
order_by_list :
order_by_item (COMMA order_by_item)*
;
order_by_item :
bool_exp collate_option? asc_desc_option? nulls_last_option?
;
for_update_options :
for_update
;
for_update :
FOR READ ONLY
| FOR update_of_option
;
set_session_stmt :
SET SESSION CHARACTERISTICS AS trans_mode_lst
;
set_trans_stmt :
SET TRANSACTION trans_mode_lst
| SET TIME ZONE exp
| START TRANSACTION trans_mode_lstl?
;
trans_mode_lstl :
trans_mode_lst
;
trans_mode_lst :
trans_mode (COMMA trans_mode)*
;
trans_mode :
trans_rw_option
| ISOLATION LEVEL trans_level_option
| DIAGNOSTICS SIZE LT_INTEGER
;
time_zone_exp_new :
AT LOCAL
| AT TIME ZONE exp
;
trans_rw_option :
READ ONLY
| READ WRITE
;
trans_level_option :
READ COMMITTED
| SERIALIZABLE
| REPEATABLE READ
| READ UNCOMMITTED
;
lock_table_stmt :
LOCK TABLE full_tv_name IN lock_mode_option MODE
| LOCK TABLE full_tv_name IN lock_mode_option MODE NOWAIT
;
lock_mode_option :
SHARE
| EXCLUSIVE
| INTENT SHARE
| INTENT EXCLUSIVE
| SHARE INTENT EXCLUSIVE
| ROW SHARE
| SHARE UPDATE
| ROW EXCLUSIVE
| SHARE ROW EXCLUSIVE
;
set_identins_stmt :
SET IDENTITY_INSERT full_table_name set_identins_option
;
set_identins_option :
OFF
| ON
| ON WITH REPLACE NULL
;
trunc_table_stmt :
TRUNCATE TABLE full_table_name reuse_storage_option? cascade_opt?
| TRUNCATE TABLE full_table_name PARTITION truncate_partition_name reuse_storage_option? cascade_opt?
;
update_stmt :
with_option? UPDATE update_stmt_body
;
update_stmt_body :
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?
;
update_tv_list :
from_tv_list
;
return_item :
exp
;
return_item_list :
return_item (COMMA return_item)*
;
return_option :
RETURN
| RETURNING
;
return_into_obj :
return_option return_item_list INTO assignment_obj_list
| return_option return_item_list BULK COLLECT INTO assignment_obj_list
;
collect_into_rset :
INTO assignment_obj
;
alias_option :
alias
| AS alias_2
;
set_value_list :
set_value_node (COMMA set_value_node)*
;
set_value_node :
full_column_name assign_op DEFAULT
| full_column_name assign_op exp
| '(' set_col_list ')' assign_op select_with_paran
| '(' set_col_list ')' assign_op record_var_value
| ROW assign_op record_var_value
;
set_col_list :
full_column_name (COMMA full_column_name)*
;
update_from_clause :
from_clause
;
merge_into_stmt :
MERGE merge_into_stmt_body
;
merge_into_stmt_body :
INTO full_tv_name alias_option? USING from_tv ON bool_exp merge_into_sub_clause log_errors?
| INTO select_with_paran alias_option? USING from_tv ON bool_exp merge_into_sub_clause log_errors?
;
merge_into_sub_clause :
merge_update_clause merge_insert_clause
| merge_insert_clause merge_update_clause
| merge_update_clause
| merge_insert_clause
;
merge_update_clause :
WHEN MATCHED THEN UPDATE SET set_value_list where_clause?
| WHEN MATCHED THEN UPDATE SET set_value_list where_clause? DELETE where_clause?
;
merge_insert_clause :
WHEN NOT MATCHED THEN INSERT full_column_list_options? VALUES '(' ins_value_list ')' where_clause?
;
create_profile_stmt :
CREATE PROFILE not_exist? profile_name resource_limit_options?
;
alter_profile_stmt :
alter_tag PROFILE profile_name resource_limit_options?
;
create_user_stmt :
CREATE USER not_exist? user_name
| 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?
;
default_ts_name :
default_ts_name_lst
;
default_ts_name_lst :
default_ts_name_node+
;
default_ts_name_node :
default_ts_name_low
| temp_ts_name
| default_idx_ts_name
| default_ts_group_name_low
;
default_idx_ts_name :
DEFAULT INDEX TABLESPACE tablespace_name
;
default_ts_name_low :
DEFAULT TABLESPACE tablespace_name
| DEFAULT TABLESPACE NULL
;
temp_ts_name :
TEMPORARY TABLESPACE tablespace_name
;
default_ts_group_name_low :
DEFAULT TABLESPACE GROUP tablespace_name
| DEFAULT TABLESPACE GROUP NULL
;
on_schema :
ON SCHEMA id
;
replace_old_pwd :
REPLACE password
;
alter_user_stmt :
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?
| alter_tag USER user_name GRANT CONNECT THROUGH user_name
| alter_tag USER user_name REVOKE CONNECT THROUGH user_name
;
user_encrypt_options :
user_encrypt_option
;
user_encrypt_option :
ENCRYPT BY password
| ENCRYPT BY WRAPPED LT_STRING
;
authent_type_options :
IDENTIFIED authent_type
;
hash_cipher_option :
hash_cipher
;
authent_type :
BY password hash_cipher_option? force_format?
| EXTERNALLY as?
| BY WRAPPED LT_STRING hash_cipher_option?
;
force_format :
FORCE FORMAT
;
as :
AS LT_STRING
;
pwd_policy :
PASSWORD_POLICY LT_INTEGER
;
account_lock :
ACCOUNT LOCK
| ACCOUNT UNLOCK
;
read_only_flag :
READ ONLY
| NOT READ ONLY
;
read_only_flag_not_null :
READ ONLY
| READ WRITE
;
resource :
LIMIT resource_limit_list
| PROFILE profile_name
| DROP PROFILE
;
expire :
PASSWORD EXPIRE
;
resource_limit_options :
LIMIT resource_limit_list
;
resource_limit_list :
resource_limit_list_with_comma
| resource_limit_list_with_empty
;
resource_limit_list_with_comma :
resource_limit
| resource_limit COMMA resource_limit_list_with_comma
;
resource_limit_list_with_empty :
resource_limit resource_limit
| resource_limit resource_limit_list_with_empty
;
resource_limit :
SESSION_PER_USER resource_limit_value
| CONNECT_IDLE_TIME resource_limit_value
| FAILED_LOGIN_ATTEMPS resource_limit_value
| FAILED_LOGIN_ATTEMPTS resource_limit_value
| PASSWORD_LIFE_TIME resource_limit_value
| PASSWORD_REUSE_TIME resource_limit_value
| PASSWORD_REUSE_MAX resource_limit_value
| PASSWORD_LOCK_TIME resource_limit_value
| PASSWORD_GRACE_TIME resource_limit_value
| CPU_PER_CALL resource_limit_value
| CPU_PER_SESSION resource_limit_value
| MEM_SPACE resource_limit_value
| READ_PER_CALL resource_limit_value
| READ_PER_SESSION resource_limit_value
| CONNECT_TIME resource_limit_value
;
resource_limit_value :
UNLIMITED
| DEFAULT
| LT_INTEGER
;
create_audit_rule_stmt :
CREATE AUDIT RULE rule_name audit_rule_action by_login_or_all whenever_stmt_options? allow_ip_list? allow_dt_list? op_freq?
;
rule_name :
id
;
audit_rule_action :
STARTUP
| SHUTDOWN
| DATABASE
| LOGIN
| CONNECT
| ROLLBACK
| COMMIT
| USER
| ROLE
| SCHEMA
| TABLE
| VIEW
| INDEX
| PROCEDURE
| TRIGGER
| SEQUENCE
| CONTEXT
| GRANT
| REVOKE
| AUDIT
| NOAUDIT
| INSERT TABLE
| UPDATE TABLE
| DELETE TABLE
| SELECT TABLE
| LOCK TABLE
| EXECUTE PROCEDURE
| SELECT ON full_object_name
| INSERT ON full_object_name
| UPDATE ON full_object_name
| DELETE ON full_object_name
| EXECUTE ON full_object_name
| PACKAGE
| PACKAGE BODY
| SYNONYM
| TYPE
| TYPE BODY
| PROFILE
;
by_login_or_all :
BY login_name
| BY ALL
;
allow_ip_list :
ALLOW_IP NULL
| ALLOW_IP ip_list
;
not_allow_ip_list :
NOT_ALLOW_IP NULL
| NOT_ALLOW_IP ip_list
;
ip_list :
id
| id COMMA ip_list
;
allow_dt_list :
ALLOW_DATETIME NULL
| ALLOW_DATETIME dt_list
;
not_allow_dt_list :
NOT_ALLOW_DATETIME NULL
| NOT_ALLOW_DATETIME dt_list
;
dt_list :
dt
| dt COMMA dt_list
;
dt :
id id TO id id
;
op_freq :
INTERVAL LT_INTEGER TIMES LT_INTEGER
;
quota_val :
LT_INTEGER
| LT_INTEGER LT_IDENTIFIER
;
quota_ts_node :
QUOTA quota_val ON tablespace_name
| QUOTA UNLIMITED ON tablespace_name
;
quota_ts_lst :
quota_ts_node
| quota_ts_lst quota_ts_node
;
quota_ts :
quota_ts_lst
| QUOTA UNLIMITED
| QUOTA LT_INTEGER
;
create_role_stmt :
CREATE ROLE not_exist? role_name
;
create_dblink_stmt :
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?
| 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?
| 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?
| 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?
;
db_type_str :
LT_STRING
;
dblink_option_lst_options :
OPTION '(' dblink_option_lst ')'
;
dblink_option_lst :
dblink_option (COMMA dblink_option)*
;
dblink_option :
id '=' exp
;
create_synonym_stmt :
CREATE replace_option? PUBLIC SYNONYM not_exist? full_synonym_name FOR full_obj_name
| CREATE replace_option? SYNONYM not_exist? full_synonym_name FOR full_obj_name
;
full_synonym_name :
qualified_name
;
full_obj_name :
qualified_name dblink_clause?
;
create_domain_stmt :
CREATE DOMAIN not_exist? qualified_name as_tag? datatype charset_option? domain_default_option? domain_constraints_option?
;
domain_default_option :
default_clause
;
domain_constraints_option :
domain_constraints_def
;
domain_constraints_def :
domain_constraints constraint_attributes_options?
;
domain_constraints :
domain_constraint+
;
domain_constraint :
domain_constraint_name_def_options? column_constraint_action
;
domain_constraint_name_def_options :
domain_constraint_name_def
;
domain_constraint_name_def :
CONSTRAINT domain_constraint_name
;
domain_constraint_name :
qualified_name
;
create_character_set_stmt :
CREATE CHARACTER SET not_exist? character_set_name as_tag? character_set_source collate_clause_option?
;
character_set_source :
GET existing_character_set_name
;
existing_character_set_name :
character_set_name
;
character_set_name :
qualified_name
;
collate_clause_option :
COLLATE collation_name
| COLLATION FROM DEFAULT
;
collation_name :
qualified_name
;
create_collation_stmt :
CREATE COLLATION not_exist? collation_name FOR existing_character_set_name FROM existing_collation_name pad_option?
;
existing_collation_name :
collation_name
;
pad_option :
NO PAD
| PAD SPACE_KEYWORD
;
create_sequence_stmt :
CREATE SEQUENCE not_exist? sequence_name sequence_option_list_options?
| alter_tag SEQUENCE sequence_name sequence_option_list_options?
;
sequence_option_list_options :
sequence_option_list
;
sequence_option_list :
sequence_option
| sequence_option sequence_option_list
;
sequence_option :
increment_option
| start_option
| current_option
| maxvalue_option
| minvalue_option
| cycle_option
| cache_option
| order_option
| seq_local_option
;
sequence_name :
qualified_name
;
increment_option :
INCREMENT BY exp
;
start_option :
START WITH exp
;
current_option :
CURRENT VALUE exp
;
maxvalue_option :
MAXVALUE exp
| NOMAXVALUE
;
minvalue_option :
MINVALUE exp
| NOMINVALUE
;
cycle_option :
CYCLE
| NOCYCLE
;
cache_option :
CACHE exp
| NOCACHE
;
order_option :
ORDER
| NOORDER
;
seq_local_option :
GLOBAL
| LOCAL
;
whenever_stmt_options :
WHENEVER whenever_stmt
;
whenever_stmt :
SUCCESSFUL
| NOT SUCCESSFUL
;
grant_stmt :
grant_tag grant_stmt_body
;
grant_tag :
GRANT
;
grant_stmt_body :
grant_privs ON full_object_name TO grantees with_grant_option? by_grantor?
| grant_privs ON db_object full_object_name TO grantees with_grant_option? by_grantor?
| grant_privs ON qualified_name full_object_name TO grantees with_grant_option? by_grantor?
| db_priv_list TO grantees with_admin_option? by_grantor?
| grant_privs TO grantees with_admin_option? by_grantor?
;
revoke_stmt :
REVOKE revoke_stmt_body
;
revoke_stmt_body :
grant_privs ON full_object_name FROM grantees revoke_action? by_grantor?
| GRANT OPTION FOR grant_privs ON full_object_name FROM grantees revoke_action? by_grantor?
| grant_privs ON db_object full_object_name FROM grantees revoke_action? by_grantor?
| GRANT OPTION FOR grant_privs ON db_object full_object_name FROM grantees revoke_action? by_grantor?
| grant_privs ON qualified_name qualified_name FROM grantees revoke_action? by_grantor?
| GRANT OPTION FOR grant_privs ON qualified_name qualified_name FROM grantees revoke_action? by_grantor?
| db_priv_list FROM grantees by_grantor?
| ADMIN OPTION FOR db_priv_list FROM grantees by_grantor?
| grant_privs FROM grantees by_grantor?
| ADMIN OPTION FOR role_name_list FROM grantees by_grantor?
;
grant_privs :
ALL
| ALL PRIVILEGES
| grant_priv_list
;
grant_priv_list :
grant_priv
| grant_priv COMMA grant_priv_list
;
grant_priv_off :
OFF
;
grant_priv :
SELECT grant_priv_off?
| INSERT grant_priv_off?
| DELETE grant_priv_off?
| UPDATE grant_priv_off?
| REFERENCES grant_priv_off?
| EXECUTE grant_priv_off?
| SELECT FOR DUMP grant_priv_off?
| SELECT '(' column_list ')'
| UPDATE '(' column_list ')'
| INSERT '(' column_list ')'
| REFERENCES '(' column_list ')'
| ALTER grant_priv_off?
| INDEX grant_priv_off?
| role_name
| FLASHBACK grant_priv_off?
;
revoke_action :
RESTRICT
| CASCADE
;
db_priv_list :
db_priv
| db_priv COMMA db_priv_list
;
db_priv :
ALTER DATABASE
| BACKUP DATABASE
| RESTORE DATABASE
| CREATE USER
| ALTER USER
| DROP USER
| CREATE ROLE
| DROP ROLE
| ADMIN ANY ROLE
| ADMIN ANY DATABASE PRIVILEGE
| GRANT ANY OBJECT PRIVILEGE
| CREATE SCHEMA
| DROP SCHEMA
| CREATE ANY SCHEMA
| DROP ANY SCHEMA
| CREATE TABLE
| DROP TABLE
| CREATE ANY TABLE
| ALTER ANY TABLE
| ALTER TABLE
| DROP ANY TABLE
| INSERT TABLE
| INSERT ANY TABLE
| UPDATE TABLE
| UPDATE ANY TABLE
| DELETE TABLE
| DELETE ANY TABLE
| SELECT TABLE
| SELECT ANY TABLE
| REFERENCES TABLE
| REFERENCES ANY TABLE
| GRANT TABLE
| GRANT ANY TABLE
| CREATE VIEW
| DROP VIEW
| CREATE ANY VIEW
| ALTER ANY VIEW
| ALTER VIEW
| DROP ANY VIEW
| INSERT VIEW
| INSERT ANY VIEW
| UPDATE VIEW
| UPDATE ANY VIEW
| DELETE VIEW
| DELETE ANY VIEW
| SELECT VIEW
| SELECT ANY VIEW
| GRANT VIEW
| GRANT ANY VIEW
| CREATE PROCEDURE
| DROP PROCEDURE
| CREATE ANY PROCEDURE
| DROP ANY PROCEDURE
| EXECUTE PROCEDURE
| EXECUTE ANY PROCEDURE
| GRANT PROCEDURE
| GRANT ANY PROCEDURE
| CREATE SEQUENCE
| DROP SEQUENCE
| ALTER ANY SEQUENCE
| ALTER SEQUENCE
| CREATE ANY SEQUENCE
| DROP ANY SEQUENCE
| SELECT SEQUENCE
| SELECT ANY SEQUENCE
| GRANT SEQUENCE
| GRANT ANY SEQUENCE
| DROP TRIGGER
| CREATE TRIGGER
| CREATE ANY TRIGGER
| DROP ANY TRIGGER
| ALTER ANY TRIGGER
| ALTER TRIGGER
| CREATE INDEX
| DROP INDEX
| CREATE ANY INDEX
| ALTER ANY INDEX
| ALTER INDEX
| DROP ANY INDEX
| CREATE CONTEXT INDEX
| DROP CONTEXT INDEX
| CREATE ANY CONTEXT INDEX
| ALTER ANY CONTEXT INDEX
| ALTER CONTEXT INDEX
| DROP ANY CONTEXT INDEX
| CREATE PACKAGE
| DROP PACKAGE
| CREATE ANY PACKAGE
| DROP ANY PACKAGE
| EXECUTE PACKAGE
| EXECUTE ANY PACKAGE
| GRANT PACKAGE
| GRANT ANY PACKAGE
| CREATE LINK
| DROP LINK
| CREATE ANY LINK
| DROP ANY LINK
| CREATE SYNONYM
| DROP SYNONYM
| CREATE ANY SYNONYM
| DROP ANY SYNONYM
| CREATE PUBLIC SYNONYM
| DROP PUBLIC SYNONYM
| CREATE REPLICATE
| ALTER REPLICATE
| DROP REPLICATE
| AUDIT DATABASE
| LABEL DATABASE
| VERIFY DATABASE
| CREATE TABLESPACE
| DROP TABLESPACE
| ALTER TABLESPACE
| CREATE MATERIALIZED VIEW
| DROP MATERIALIZED VIEW
| CREATE ANY MATERIALIZED VIEW
| DROP ANY MATERIALIZED VIEW
| ALTER ANY MATERIALIZED VIEW
| ALTER MATERIALIZED VIEW
| SELECT MATERIALIZED VIEW
| SELECT ANY MATERIALIZED VIEW
| CREATE ANY DOMAIN
| DROP ANY DOMAIN
| CREATE DOMAIN
| DROP DOMAIN
| GRANT ANY DOMAIN
| GRANT DOMAIN
| USAGE ANY DOMAIN
| USAGE DOMAIN
| CREATE ANY CHARACTER SET
| DROP ANY CHARACTER SET
| CREATE CHARACTER SET
| DROP CHARACTER SET
| GRANT ANY CHARACTER SET
| GRANT CHARACTER SET
| USAGE ANY CHARACTER SET
| USAGE CHARACTER SET
| CREATE ANY COLLATION
| DROP ANY COLLATION
| CREATE COLLATION
| DROP COLLATION
| GRANT ANY COLLATION
| GRANT COLLATION
| USAGE ANY COLLATION
| USAGE COLLATION
| CREATE ANY CONTEXT
| DROP ANY CONTEXT
| GRANT ANY CONTEXT
| SELECT ANY DICTIONARY
| ADMIN REPLAY
| ADMIN BUFFER
| COMMENT ANY TABLE
| DUMP ANY TABLE
| DUMP TABLE
| ADMIN JOB
| CREATE ANY DIRECTORY
| DROP ANY DIRECTORY
| CREATE SESSION
| CREATE PROFILE
| ALTER PROFILE
| DROP PROFILE
| CREATE PARTITION GROUP
| DROP PARTITION GROUP
| CREATE ANY PARTITION GROUP
| DROP ANY PARTITION GROUP
| USAGE PARTITION GROUP
| USAGE ANY PARTITION GROUP
| CREATE OPERATOR
| DROP OPERATOR
| CREATE ANY OPERATOR
| DROP ANY OPERATOR
| FLASHBACK TABLE
| FLASHBACK ANY TABLE
| UNLIMITED TABLESPACE
| SUBSCRIBE
;
by_grantor :
BY user_name
;
grantees :
user_role_name
| user_role_name COMMA grantees
;
create_schema_stmt :
CREATE SCHEMA full_schema_name? (AUTHORIZATION user_name)? SEMI? (grant_and_ddl SEMI?)*
;
oprt_arg :
LEFTARG opr_dtype
| RIGHTARG opr_dtype
;
oprt_arg_lst :
oprt_arg (COMMA oprt_arg)*
;
create_operator_stmt :
CREATE OPERATOR qualified_u_oprt '(' FUNCTION full_func_name COMMA oprt_arg_lst ')'
;
drop_operator_stmt :
DROP OPERATOR exist? qualified_u_oprt '(' opr_datatype_lst ')'
;
grant_and_ddl :
grant_stmt
| create_func_stmt
| create_index_stmt
| create_proc_stmt
| create_table_stmt
| create_trigger_stmt
| create_view_stmt
| create_materialized_view_stmt
| create_materialized_view_log_stmt
| alter_table_stmt
| create_sequence_stmt
| create_contextindex_stmt
| create_synonym_stmt
| create_package_stmt
| create_package_body_stmt
| create_dblink_stmt
| create_type_stmt
| create_type_body_stmt
| create_domain_stmt
| create_character_set_stmt
| create_collation_stmt
| create_context_stmt
| comment_stmt
| create_partition_group_stmt
| create_operator_stmt
| drop_operator_stmt
;
top_exp :
LT_INTEGER
| stm_param
| member
| '(' exp ')'
| null_value
;
u_oprt :
OP_U_OPRT
;
qualified_u_oprt :
u_oprt
| qualified_name ('.' u_oprt)?
;
exp_u_oprt :
u_oprt
| OPERATOR '(' qualified_u_oprt ')'
;
raw_exp :
'-' raw_exp
| LT_INTEGER
| LT_BINTEGER
| LT_DECIMAL
| LT_REAL
| LT_STRING
| member_access LT_STRING
| member LT_STRING
| LT_BITSTRING
| member_access
| member
| null_value
| stm_param
| INTERVAL ('+' | '-') LT_STRING interval_qualifier
| INTERVAL LT_STRING interval_qualifier
| global_var
;
exp :
op=('~'|'+'|'-') exp
| exp_u_oprt exp
| BINARY_KEYWORD exp
| PRIOR exp
| select_with_paran
| '(' exp '-' exp ')' interval_qualifier?
| exp op=('*' | '/' | '%' | MOD) exp
| exp op=('+' | '-' | '|' |'^' | '&') exp
| exp exp_u_oprt exp
| '(' exp exp_u_oprt ')'
| exp op=(OP_CONSTR | OP_SHIFT_LEFT | OP_SHIFT_RIGHT) exp
| boolean_case
| if_exp
| null_value
| stm_param
| USER
| USER '(' ')'
| INTERVAL ('+'| '-')? LT_STRING interval_qualifier
| DATEPART '(' datepart_op COMMA exp ')'
| IFNULL '(' bool_exp COMMA bool_exp ')'
| datead_fun '(' datepart_op COMMA exp COMMA exp ')'
| REPEAT '(' exp COMMA exp ')'
| REPLICATE '(' exp COMMA exp ')'
| OVERLAY '(' exp PLACING exp FROM exp (FOR exp)? ')'
| decode_case
| pexp_pfx '%' (ROWCOUNT | ROWCOUNT2 | IS OPEN | FOUND | NOT FOUND)
| global_var
| NEXT VALUE FOR pexp_pfx
| CONNECT_BY_ROOT (qualified_name | '(' exp ')')
| ARRAYLEN '(' exp ')'
| CHAR '(' exp ')'
| REVERSE '(' exp ')'
| ROWNUM
| sizeof_expression
| pexp
| TRUE
| FALSE
| invocation_expression OVER '(' afun_partition_by? order_by_options? afun_windowing? ')'
| exp ignore_nulls_clause OVER '(' afun_partition_by? order_by_options? afun_windowing? ')'
| invocation_expression from_first_last_option '(' afun_partition_by? order_by_options? afun_windowing? ')'
| pexp_pfx '(' afun_arg_lst ')' OVER '(' afun_partition_by? order_by_options? afun_windowing? ')'
| pexp time_zone_exp_new
| CURSOR FAST? select_with_paran
| exp MULTISET (UNION | INTERSECT | EXCEPT) all_distinct_option? exp
| SET '(' exp ')'
| contains_exp
;
from_first_last_option :
FROM FIRST OVER
| FROM LAST OVER
| FROM FIRST IGNORE NULLS OVER
| FROM LAST IGNORE NULLS OVER
| FROM FIRST RESPECT NULLS OVER
| FROM LAST RESPECT NULLS OVER
;
afun_arg_lst :
afun_arg_lst_low
;
afun_arg_lst_low :
exp ignore_nulls_clause (COMMA exp)*
;
in_value_exp :
op=('~'| '+'| '-') in_value_exp
| PRIOR in_value_exp
| in_value_exp op=('*'|'/'| '%'| MOD ) in_value_exp
| in_value_exp op=('+'|'-'| '|'| '^' ) in_value_exp
| in_value_exp op=(OP_CONSTR | OP_SHIFT_LEFT | OP_SHIFT_RIGHT) in_value_exp
| boolean_case
| if_exp
| null_value
| stm_param
| USER
| USER '(' ')'
| INTERVAL '+' LT_STRING interval_qualifier
| INTERVAL '-' LT_STRING interval_qualifier
| INTERVAL LT_STRING interval_qualifier
| DATEPART '(' datepart_op COMMA in_value_exp ')'
| datead_fun '(' datepart_op COMMA in_value_exp COMMA in_value_exp ')'
| REPEAT '(' in_value_exp COMMA in_value_exp ')'
| REPLICATE '(' in_value_exp COMMA in_value_exp ')'
| OVERLAY '(' in_value_exp PLACING in_value_exp FROM in_value_exp ')'
| OVERLAY '(' in_value_exp PLACING in_value_exp FROM in_value_exp FOR in_value_exp ')'
| decode_case
| pexp_pfx '%' ROWCOUNT
| pexp_pfx '%' ROWCOUNT2
| global_var
| NEXT VALUE FOR pexp_pfx
| ARRAYLEN '(' in_value_exp ')'
| CHAR '(' in_value_exp ')'
| REVERSE '(' in_value_exp ')'
| ROWNUM
| sizeof_expression
| pexp_a
| pexp_b
| pexp_c
| TRUE
| FALSE
| pexp_a time_zone_exp_new
;
afun_partition_by :
PARTITION BY exp_list
;
afun_windowing :
afun_windowing_type afun_range_clause
| afun_windowing_type BETWEEN afun_range_clause AND afun_range_clause
;
afun_windowing_type :
ROWS
| RANGE
;
afun_range_clause :
exp PRECEDING
| exp FOLLOWING
| CURRENT ROW
;
pexp :
pexp_a
| pexp_b
| pexp_c
| pexp_d
| pexp_e
;
pexp_pfx :
pexp_pfx DOT (id dblink_clause? | key | '*') (('[' exp_list ']')+)?
| pexp_pfx '(' opt_argument_list ')' ( keep_clause | within_clause )? (('[' exp_list ']')+)?
| pexp_pfx '.' ( EXECUTE | EXTRACT )'(' opt_argument_list ')' (('[' exp_list ']')+)?
| XMLPARSE '(' raw_id exp raw_id? ')' (('[' exp_list ']')+)?
| XMLELEMENT '(' xmlele_name xmlele_sub_lst? ')' (('[' exp_list ']')+)?
| XMLAGG '(' exp order_by_options? ')' (('[' exp_list ']')+)?
| pexp_c_insert (('[' exp_list ']')+)?
| new_arr_expression
| pexp_cast
| stm_param_normal
;
pexp_cast :
'(' exp AS datatype ')'
| CAST '(' exp AS datatype ')'
| CAST '(' COLLECT '(' all_distinct_option? exp order_by_options? ')' AS datatype ')'
;
pexp_b :
element_access
| new_arr_expression
;
pexp_a :
typeof_expression
| LT_INTEGER
| LT_BINTEGER
| LT_DECIMAL
| LT_REAL
| LT_STRING
| LT_BITSTRING
;
pexp_c :
member ('%' BULK (EXCEPTION | ROWCOUNT))?
| member_access
| new_obj_expression
| invocation_expression
| ':' trig_new_name '.' column_name
| NEW '.' column_name
;
pexp_c_insert :
member
| new_obj_expression
| ':' trig_new_name '.' column_name
| NEW '.' column_name
| member '%' BULK EXCEPTION
| member '%' BULK ROWCOUNT
;
pexp_d :
member LT_STRING
| CAST '(' exp AS datatype ')'
| CAST '(' COLLECT '(' all_distinct_option? exp order_by_options? ')' AS datatype ')'
| CONVERT '(' datatype COMMA exp ')'
| CONVERT '(' datatype COMMA exp COMMA exp ')'
| TRIM '(' exp ')'
| TRIM '(' orient_option FROM exp ')'
| TRIM '(' exp FROM exp ')'
| TRIM '(' orient_option exp FROM exp ')'
| TRUNCATE '(' value_list ')'
| INSERT '(' value_list ')'
| EXTRACT '(' datepart FROM exp ')'
| EXTRACT '(' exp COMMA exp ')'
| GROUPING '(' exp ')'
;
pexp_e :
'(' exp ')'
;
pexp_pfx2 :
pexp_pfx2 DOT (id dblink_clause? | key) (('[' exp_list ']')+)?
| pexp_pfx2 '(' opt_argument_list ')' ( keep_clause | within_clause )? (('[' exp_list ']')+)?
| pexp_pfx2 '.' ( EXECUTE | EXTRACT )'(' opt_argument_list ')' (('[' exp_list ']')+)?
| pexp_c2_insert (('[' exp_list ']')+)?
| XMLPARSE '(' raw_id exp raw_id? ')' (('[' exp_list ']')+)?
| XMLELEMENT '(' xmlele_name xmlele_sub_lst? ')' (('[' exp_list ']')+)?
| XMLAGG '(' exp order_by_options? ')' (('[' exp_list ']')+)?
| new_arr_expression
| pexp_cast
| stm_param_normal
;
member2 :
variable_name dblink_clause?
;
pexp_c2_insert :
member2
| new_obj_expression
| ':' trig_new_name '.' column_name
| NEW '.' column_name
| member2 '%' BULK EXCEPTION
| member2 '%' BULK ROWCOUNT
;
member_access2 :
pexp_pfx2 (DOT id dblink_clause?)+
| pexp_pfx2 (DOT key)+
;
invocation_expression2 :
pexp_pfx2 invocation_expression_low
;
member :
id dblink_clause?
;
key :
FIRST
| NEXT
| PRIOR
| DELETE
| GET
| SET
| EXISTS
| TRIM
| ROWNUM
| ROWS
;
member_access :
pexp_pfx ((DOT id dblink_clause?)+ | (DOT key)+ | (DOT '*')+)
;
invocation_expression :
pexp_pfx invocation_expression_low
| xmlfun_inv_expression
| xmlagg_inv_expression
;
invocation_expression_low :
('.' EXECUTE LR_BRACKET opt_argument_list? RR_BRACKET)+
| (LR_BRACKET opt_argument_list? RR_BRACKET (keep_clause | within_clause)? )+
;
xmlagg_inv_expression :
XMLAGG '(' exp order_by_options? ')'
;
xmlfun_inv_expression :
XMLPARSE '(' raw_id exp raw_id ')'
| XMLPARSE '(' raw_id exp ')'
| XMLELEMENT '(' xmlele_name xmlele_sub_lst? ')'
| pexp_pfx (DOT EXTRACT '(' opt_argument_list? ')')+
;
xmlele_name :
id
| EVALNAME exp
;
xmlele_sub_lst :
COMMA xmlval_lst
| COMMA XMLATTRIBUTES '(' xmlattr_lst ')'
| COMMA XMLATTRIBUTES '(' xmlattr_lst ')' COMMA xmlval_lst
;
xmlattr_lst :
xmlattr (COMMA xmlattr)*
;
xmlattr :
exp
| exp id
| exp AS id
| exp AS EVALNAME exp
;
xmlval_lst :
exp (COMMA exp)*
;
keep_clause :
KEEP '(' DENSE_RANK FIRST order_by_options? ')'
| KEEP '(' DENSE_RANK LAST order_by_options? ')'
;
within_clause :
WITHIN GROUP '(' order_by_options? ')'
;
typeof_expression :
TYPEOF '(' sizeof_type ')'
;
new_obj_expression :
NEW qualified_name '(' opt_argument_list? ')'
;
new_arr_expression :
array_creation_expression
;
array_creation_expression :
NEW new_array_type '[' exp_list ']' opt_rank_specifier? opt_array_initializer?
| NEW STRUCT new_array_type '[' exp_list ']' opt_rank_specifier? opt_array_initializer?
;
plsql_datatype_ex :
INTERVAL interval_qualifier
| qualified_name '%' TYPE
| qualified_name '%' ROWTYPE
| REF qualified_name
| CURSOR
;
new_array_type :
plsql_datatype_ex
| dtype
| REF CURSOR
;
opt_array_initializer :
array_initializer
;
array_initializer :
'{' '}'
| '{' variable_initializer_list opt_comma? '}'
;
variable_initializer_list :
variable_initializer (COMMA variable_initializer)*
;
variable_initializer :
exp
;
opt_comma :
COMMA
;
sizeof_expression :
SIZEOF '(' type_name ')'
;
element_access :
pexp_c ('[' exp_list ']')+
;
decode_case :
DECODE '(' exp_list ')'
;
else_exp :
ELSE exp
;
boolean_case :
CASE bool_exp? bool_when_list else_exp? END case_option?
;
if_exp :
IF '(' bool_exp COMMA bool_exp COMMA bool_exp ')'
;
bool_when_list :
(WHEN bool_exp THEN exp)+
;
ops :
'='
| '=='
| '>'
| '<'
| '<' '>'
| '>' '='
| '<' '='
| OPR_NE
| OPR_GE
| OPR_LE
| OP_MULT_ASSIGN
;
value_list :
exp_list
;
in_value_list :
in_value_exp
;
value_list_set :
'(' value_list ')' (COMMA '(' value_list ')')*
;
comma_list :
COMMA+
;
ins_value_list :
ins_exp_list
| comma_list ins_exp_list
;
null_value :
NULL
;
id_and_rsvd_word_others :
new_none_reserved_word
| alias_resvd_word
| variable_resvd_word
| schname_resvd_word
;
id_and_rsvd_word :
raw_id
| reserved_word
| id_and_rsvd_word_others
;
stm_param :
stm_param_normal
| stm_param_name
;
stm_param_normal :
'?'
| ':' LT_INTEGER
| ':' '<' LT_INTEGER param_name_options? '>'
| '^' '?' '^'
;
stm_param_name :
':' id_and_rsvd_word
;
param_name_options :
id
;
contains_query_exp :
exp
| contains_query_exp (AND | OR | AND NOT) contains_query_exp
;
contains_query_exp_lst :
contains_query_exp (COMMA contains_query_exp)*
;
contains_exp :
CONTAINS '(' exp COMMA contains_query_exp ')'
| CONTAINS '(' exp COMMA contains_query_exp COMMA contains_query_exp ')'
| CONTAINS '(' exp COMMA contains_query_exp COMMA SYSTEM LABEL COMMA LT_INTEGER COMMA LT_INTEGER ')'
| CONTAINS '(' exp COMMA contains_query_exp COMMA contains_query_exp COMMA contains_query_exp_lst ')'
;
strict_option :
'(' LAX ')'
| LAX
| '(' STRICT ')'
| STRICT
;
with_unique_option :
WITHOUT UNIQUE KEYS
| WITH UNIQUE KEYS
;
type_option :
TYPE
;
type_element :
qualified_name
;
type_element_list :
type_element (COMMA type_element)*
;
bool_exp :
exp
| bool_exp_element
;
bool_exp_element :
exp IS not_tag? JSON strict_option? with_unique_option?
| exp IS not_tag? OF type_option? '(' type_element_list ')'
| NOT (bool_exp_element | exp)
//| (bool_exp_element | exp) (AND | OR) (bool_exp_element | exp)
| bool_exp_element (AND | OR) (bool_exp_element | exp)
| exp (AND | OR) (bool_exp_element | exp)
| exp not_tag? IN (select_with_paran | in_value_list | ('(' value_list ')'))
| '(' exp_list_2 ')' not_tag? IN (select_with_paran | ('(' value_list_set ')'))
| '(' exp_list_2 ')' ops query_any_options? (select_with_paran | ('(' value_list_set ')'))
| exp ops query_any_options (select_with_paran | ('(' value_list_set ')'))
| EXISTS select_with_paran
| exp ops exp
| exp IS not_tag? NULL
| exp NOT? BETWEEN exp AND exp
| exp NOT? LIKE exp (ESCAPE exp)?
| pexp_pfx '.' ROW NOT? LIKE exp (ESCAPE exp)?
| BINARY_KEYWORD pexp_pfx '.' ROW NOT? LIKE exp (ESCAPE exp)?
| '(' exp_list_2 ')' OVERLAPS '(' exp_list_2 ')'
| LNNVL '(' (bool_exp_element | exp) ')'
| exp not_tag? MEMBER OF exp
| '(' bool_exp_element ')'
;
query_any_options :
ALL
| SOME
| ANY
| EVERY
;
global_var :
LT_GLOBAL_VAR
;
reserved_word :
IFNULL
| ABSOLUTE
| ADD
| ALL
| ALTER
| AND
| ANY
| ARRAYLEN
| AS
| ASC
| ASSIGN
| AUDIT
| BEGIN
| BETWEEN
| BIGDATEDIFF
| BOOL
| BOTH
| BSTRING
| BY
| BYTE
| CALL
| CASE
| CAST
| CHAR
| CHECK
| CLUSTER
| COLUMN
| COMMIT
| COMMITWORK
| COMMENT
| CONNECT
| CONNECT_BY_ROOT
| CONSTRAINT
| CONTAINS
| CONTEXT
| CONVERT
| CORRESPONDING
| CREATE
| CRYPTO
| CURRENT
| CURSOR
| DATEADD
| DATEDIFF
| DATEPART
| DECIMAL
| DECLARE
| DECODE
| DEFAULT
| DELETE
| DESC
| DISTINCT
| DISTRIBUTED
| DOUBLE
| DROP
| ELSE
| ELSEIF
| END
| EXECUTE
| EXISTS
| EXIT
| EXPLAIN
| EXTRACT
| FETCH
| FINAL
| FIRST
| FLOAT
| FOR
| FOREIGN
| FROM
| FULLY
| FUNCTION
| GOTO
| GRANT
| GROUP
| HAVING
| IDENTITY
| IF
| IMMEDIATE
| IN
| INDEX
| INSERT
| INT
| INTERVAL
| INTO
| IS
| LEAD
| LIKE
| LOGIN
| LOOP
| MEMBER
| NEW
| NEXT
| NOT
| NULL
| OBJECT
| OF
| ON
| OR
| ORDER
| OUT
| PARTITION
| PENDANT
| PERCENT
| PRIMARY
| PRINT
| PRIOR
| PRIVILEGES
| PROCEDURE
| PUBLIC
| RAISE
| RECORD
| REF
| REFERENCES
| REFERENCE
| REFERENCING
| RELATIVE
| REPEAT
| RETURN
| REVERSE
| REVOKE
| ROLLBACK
| ROW
| ROWNUM
| ROWS
| SAVEPOINT
| SCHEMA
| SELECT
| SET
| SOME
| SUBPARTITION
| SWITCH
| SYNONYM
| TABLE
| TIMESTAMPADD
| TIMESTAMPDIFF
| TO
| TOP
| TRAIL
| TRIGGER
| TRIM
| TRUNCATE
| UNION
| UNIQUE
| UNTIL
| UPDATE
| USER
| USING
| VALUES
| VARRAY
| VIEW
| WHEN
| WHENEVER
| WHILE
| WITH
| DISKSPACE
| RETURNING
| SBYTE
| SHORT
| USHORT
| UINT
| ULONG
| VOID
| CONST
| DO
| BREAK
| CONTINUE
| THROW
| FINALLY
| TRY
| CATCH
| PROTECTED
| PRIVATE
| ABSTRACT
| SEALED
| STATIC
| VIRTUAL
| OVERRIDE
| EXTERN
| CLASS
| STRUCT
| GET
| SIZEOF
| TYPEOF
| ADMIN
| REPLICATE
| VERIFY
| EQU
| EXCHANGE
| CLUSTERBTR
| LIST
| ARRAY
| ROLLUP
| CUBE
| GROUPING
| OVER
| SECTION
| SETS
| DOMAIN
| COLLATION
| OVERLAY
| EVERY
| KEEP
| WITHIN
| LNNVL
| NOCOPY
| INLINE
| TYPEDEF
| XMLTABLE
| XMLPARSE
| XMLAGG
| AUTO_INCREMENT
| BINARY_KEYWORD
| XMLELEMENT
| XMLATTRIBUTES
| EVALNAME
| LEXER
| FLASHBACK
| NOCYCLE
| NOSORT
| OPTIMIZE
| VERSIONS
| LARGE
| WITHOUT
| PIPE
| XML
| JSON_TABLE
| SUBSCRIBE
| LESS
| THAN
;
new_none_reserved_word :
ACROSS
| ABORT
| ROWID
| ACTION
| AFTER
| ALLOW_DATETIME
| ALLOW_IP
| ANALYZE
| ARCHIVEDIR
| ARCHIVELOG
| ARCHIVESTYLE
| AT_KEYWORD
| ATTACH
| AUTO
| AVG
| BACKUP
| BACKUPDIR
| BACKUPINFO
| BAKFILE
| BEFORE
| BIGINT
| DEVICE
| PARMS
| TRACE
| FILE
| BIT
| BITMAP
| BLOB
| BLOCK
| BOOLEAN
| CACHE
| CASCADE
| CASCADED
| CATALOG
| CHAIN
| CALCULATE
| CHARACTER
| CIPHER
| CLOB
| COMMITTED
| COMPILE
| DUMP
| JOB
| COMPRESS
| COMPRESSED
| CONNECT_BY_IS_CYCLE
| CONNECT_BY_IS_LEAF
| CONNECT_IDLE_TIME
| COUNT
| COUNTER
| CTLFILE
| CYCLE
| SEARCH
| DEPTH
| BREADTH
| DANGLING
| DATAFILE
| DATE
| DATETIME
| DBFILE
| DEBUG
| DEC
| DEFERRABLE
| DEFERRED
| DELETING
| DELTA
| DEREF
| DETACH
| DISCONNECT
| DOWN
| EACH
| ENCRYPT
| ENCRYPTION
| ESCAPE
| EVENTINFO
| EXCLUSIVE
| EXTERNAL
| EXTERNALLY
| FAILED_LOGIN_ATTEMPS
| FAILED_LOGIN_ATTEMPTS
| FILEGROUP
| FILLFACTOR
| FORCE
| FREQUENCE
| GLOBAL
| GLOBALLY
| HASH
| HEXTORAW
| IDENTIFIED
| IDENTITY_INSERT
| IMAGE
| INCREASE
| INCREMENT
| INITIAL
| INITIALLY
| INNERID
| INSERTING
| INSTEAD
| INTEGER
| INTENT
| ISOLATION
| KEY
| LABEL
| LOCAL
| LOCALLY
| LOGFILE
| LOGOUT
| LONG
| LONGVARBINARY
| LONGVARCHAR
| MANUAL
| MATCH
| MATCHED
| MAX
| MAXSIZE
| MAXVALUE
| MERGE
| MIN
| MINEXTENTS
| MINVALUE
| MODE
| MODIFY
| MONEY
| MOUNT
| NO
| NOARCHIVELOG
| NOAUDIT
| NOCACHE
| NOMAXVALUE
| NOMINVALUE
| NOORDER
| NOT_ALLOW_DATETIME
| NOT_ALLOW_IP
| NOWAIT
| NUMBER
| NUMERIC
| OFF
| OFFLINE
| CORRUPT
| ONLY
| OPTION
| OUTER
| OVERLAPS
| CONSTANT
| PAGE
| PARTIAL
| PARTITIONS
| PASSWORD_GRACE_TIME
| PASSWORD_LIFE_TIME
| PARALLEL
| CPU_PER_CALL
| CPU_PER_SESSION
| MEM_SPACE
| READ_PER_CALL
| READ_PER_SESSION
| PASSWORD_LOCK_TIME
| PASSWORD_POLICY
| PASSWORD_REUSE_MAX
| PASSWORD_REUSE_TIME
| PRECISION
| PRESERVE
| RAWTOHEX
| READ
| REAL
| REBUILD
| RELATED
| RENAME
| REPEATABLE
| REPLACE
| RESTORE
| RESTRICT
| PLACING
| ROLE
| ROLLFILE
| ROOT
| ROWCOUNT
| RULE
| SALT
| SCOPE
| SERERR
| SERIALIZABLE
| SESSION_PER_USER
| SHARE
| SHUTDOWN
| SIBLINGS
| SMALLINT
| SNAPSHOT
| SOUND
| SPATIAL
| SPLIT
| SQL
| STARTUP
| STATEMENT
| STORAGE
| STRING
| STYLE
| SUBSTRING
| SUCCESSFUL
| SUM
| SUSPEND
| SYNC
| SYS_CONNECT_BY_PATH
| TEMPORARY
| TEXT
| THEN
| TIES
| TIME
| TIMES
| TIMESTAMP
| TINYINT
| TRANSACTION
| TRIGGERS
| TRUNCSIZE
| UNCOMMITTED
| UNDER
| UNLIMITED
| UP
| UPDATING
| VALUE
| VARBINARY_KEYWORD
| VARCHAR
| VARCHAR2
| STDDEV
| VARIANCE
| VARYING
| VSIZE
| WORK
| WRITE
| SEQUENCE
| SERVER
| TIMER
| WEEK
| ONCE
| ZONE
| VERTICAL
| QUOTA
| LOG
| NONE
| LOB
| ERROR
| PASSWORD
| EXPIRE
| BACKUPSET
| MAXPIECESIZE
| BACKED
| SINCE
| DDL_CLONE
| CUMULATIVE
| NORMAL
| STANDBY
| TRANSACTIONAL
| STORE
| BRANCH
| NOBRANCH
| READONLY
| UNBOUNDED
| PRECEDING
| FOLLOWING
| AUTOEXTEND
| WRAPPED
| BTREE
| CONNECT_TIME
| TRXID
| THROUGH
| SCN
| VERSIONS_STARTTIME
| VERSIONS_ENDTIME
| VERSIONS_STARTTRXID
| VERSIONS_ENDTRXID
| VERSIONS_OPERATION
| RANDOMLY
| COPY
| PATH
| HUGE
| FILESIZE
| SESSION
| QUERY_REWRITE_INTEGRITY
| REFRESH
| MATERIALIZED
| FAST
| COMPLETE
| DEMAND
| MIRROR
| NEVER
| BUILD
| PURGE
| SYNCHRONOUS
| ASYNCHRONOUS
| PREBUILT
| REDUCED
| BASE
| SELF
| INDEXES
| EXCEPTION_INIT
| AUTONOMOUS_TRANSACTION
| INDICES
| EXCEPTIONS
| SAVE
| RESULT
| COLLATE
| PAD
| SPACE_KEYWORD
| EVENTS
| NCHAR
| NCHARACTER
| NATIONAL
| USE_HASH
| USE_MERGE
| USE_NL
| USE_NL_WITH_INDEX
| TIME_ZONE
| DIAGNOSTICS
| SIMPLE
| CHARACTERISTICS
| INSENSITIVE
| ASENSITIVE
| SENSITIVE
| SCROLL
| HOLD
| SUBPARTITIONS
| TEMPLATE
| NULLS
| DENSE_RANK
| SYSTEM
| MEMORY
| SPFILE
| AUTHID
| CURRENT_USER
| CURRENT_SCHEMA
| DEFINER
| ACCESSED
| INITIALIZED
| LOGGING
| NOLOGGING
| DETERMINISTIC
| TABLESPACE
| COLUMNS
| WAIT
| SKIP_KEYWORD
| LOCKED
| PARALLEL_ENABLE
| AGGREGATE
| SIZE
| LEVEL
| REPLAY
| DICTIONARY
| PRIVILEGE
| BUFFER
| MOVE
| MOVEMENT
| ACCOUNT
| UNLOCK
| INCLUDING
| EXCLUDING
| JAVA
| INVISIBLE
| VISIBLE
| UNUSABLE
| DATA
| CONSTRAINTS
| OLD
| MAPPED
| LOGON
| LOGOFF
| RANGE
| ARCHIVE
| FIELDS
| DELIMITED
| RECORDS
| ERRORS
| LSN
| INPUT
| INCLUDE
| EXCLUDE
| DDL
| DIRECTORY
| LOCATION
| RESULT_CACHE
| PIPELINED
| MONITORING
| NOMONITORING
| EXTENDS
| NODE
| STRICT
| LAX
| FORMAT
| JSON
| KEYS
| ASCII
| PRETTY
| WRAPPER
| EMPTY
| CONDITIONAL
| UNCONDITIONAL
| TASK
| THREAD
| BADFILE
| ADVANCED
| ROWDEPENDENCIES
| NOROWDEPENDENCIES
| SPAN
| MON
| TUE
| WED
| THU
| FRI
| SAT
| SUN
| JAN
| FEB
| MAR
| APR
| MAY
| JUN
| JUL
| AUG
| SEP
| OCT
| NOV
| YEARLY
| MONTHLY
| WEEKLY
| DAILY
| HOURLY
| MINUTELY
| SECONDLY
| BYMONTH
| BYWEEKNO
| BYYEARDAY
| BYMONTHDAY
| BYDAY
| BYHOUR
| BYMINUTE
| BYSECOND
| USAGE
| EXCEPTION
| DATABASE
| LAST
| PACKAGE
| PASSING
| GREAT
| MICRO
| LOCAL_OBJECT
| LINK
| RESTRICT_REFERENCES
| REJECT
| PROFILE
| HASHPARTMAP
| SPEED
| STOP
| INSTANCE
| IGNORE_ROW_ON_DUPKEY_INDEX
| EDITIONABLE
| NONEDITIONABLE
| BATCH
| ORDINALITY
| STRIPING
| HIGH
| DISKGROUP
| SHADOW
| CASE_SENSITIVE
| LEFTARG
| RIGHTARG
| OPERATOR
| RESIZE
| SCHEMABINDING
| CHANGE
| TRACKING
| SUBSTITUTABLE
| LEVELS
| IDENTIFIER_KEYWORD
| GENERATED
| OIDINDEX
| NOPARALLEL
| COLLECT
| DML
| APPLY
| CHECKPOINT
| NOVALIDATE
| QUERY
;
interval_nresvd_word :
YEAR
| MONTH
| DAY
| HOUR
| MINUTE
| SECOND
;
variable_resvd_word :
TYPE
| SUBTYPE
| MAP
| INSTANTIABLE
| CONSTRUCTOR
| OVERRIDING
| PRAGMA
| CLOSE
| OPEN
| LOCK
| STAT
| FORALL
| DISABLE
| ENABLE
;
alias_resvd_word :
interval_nresvd_word
| LEFT
| RIGHT
| EXCEPT
| MINUS
| INTERSECT
| CROSS
| FULL
| INNER
| JOIN
| NATURAL
| WHERE
| BULK
| OFFSET
| MOD
| SEED
| SAMPLE
| PIVOT
| ONLINE
| UNPIVOT
| LIMIT
| MULTISET
;
schname_resvd_word :
AUTHORIZATION
;
raw_id :
LT_IDENTIFIER
;
id :
raw_id
| new_none_reserved_word
| schname_resvd_word
| alias_resvd_word
| variable_resvd_word
;
qualified_name :
id ('.' id)*
;
qualified_name2 :
id ('.' id)*
;
variable_name :
raw_id
| new_none_reserved_word
| schname_resvd_word
| alias_resvd_word
;
end_loop_label_null :
END LOOP label_name_options?
;
label_name_options :
label_name
;
label_name :
id
;
database_name :
id
;
backup_name :
id
;
full_proc_name :
qualified_name
;
full_proc_name2 :
qualified_name2
;
full_fun_name :
qualified_name
;
full_table_name :
qualified_name
;
full_grp_name :
qualified_name
;
full_table_name2 :
qualified_name2
;
full_partition_name :
raw_id
;
full_schema_name :
schema_name
| database_name '.' schema_name
;
table_name :
id
;
column_name :
id
;
constraint_name :
id
;
full_trigger_name :
qualified_name
;
full_trigger_name2 :
qualified_name2
;
full_view_name :
qualified_name
;
full_view_name2 :
qualified_name2
;
cursor_name :
raw_id
;
trigger_name :
id
;
login_name :
id
;
profile_name :
DEFAULT
| id
;
user_name :
id
;
role_name :
id
| PUBLIC
;
user_role_name :
role_name
;
role_name_list :
role_name
| role_name COMMA role_name_list
;
full_func_name :
qualified_name2
;
param_name :
id
;
index_name :
id
| id '.' id
;
index_name2 :
id
| id '.' id
| id '.' id '.' id
;
trig_old_name :
variable_name
| NEW
;
trig_new_name :
variable_name
| variable_resvd_word
| NEW
;
full_tv_name :
qualified_name dblink_clause2? ((PARTITION | SUBPARTITION) ('(' full_partition_name ')' | FOR '(' value_list ')'))?
| qualified_name INDEX (id | LT_INTEGER)
;
full_object_name :
qualified_name
;
orient_option :
LEAD
| TRAIL
| BOTH
;
datepart :
raw_id
| YEAR
| MONTH
| WEEK
| DAY
| HOUR
| MINUTE
| SECOND
;
datepart_op :
datepart
;
datead_fun :
DATEADD
| DATEDIFF
| BIGDATEDIFF
| TIMESTAMPADD
| TIMESTAMPDIFF
;
returning :
RETURNING dtype double_length_option?
;
pretty :
ASCII
| PRETTY
| PRETTY ASCII
;
wrapper_flag :
WRAPPER
| ARRAY WRAPPER
;
array_wrapper :
WITHOUT wrapper_flag
| WITH wrapper_flag
| WITH UNCONDITIONAL wrapper_flag
| WITH CONDITIONAL wrapper_flag
;
json_tail_on_empty :
empty_handle
| DEFAULT exp ON EMPTY
;
empty_handle :
NULL ON EMPTY
| ERROR ON EMPTY
;
json_tail_on_error_null :
error_handle?
| DEFAULT exp ON ERROR
;
error_handle :
NULL ON ERROR
| ERROR ON ERROR
| EMPTY ON ERROR
| TRUE ON ERROR
| FALSE ON ERROR
;
savepoint_name :
id
;
alias :
raw_id
| new_none_reserved_word
| schname_resvd_word
| '*'
| variable_resvd_word
| interval_nresvd_word
;
alias_2 :
id
;
full_column_name :
qualified_name
;
schema_name :
raw_id
| new_none_reserved_word
| variable_resvd_word
;
not_tag :
NOT
;
debug_tag :
DEBUG
;
column_tag :
COLUMN
;
pendant_tag :
PENDANT
;
unique_tag :
UNIQUE
| BITMAP
| SPATIAL
| ARRAY
;
partition_tag :
CLUSTER
| NOT PARTIAL
;
row_tag :
ROW
;
as_tag :
AS
;
from_tag :
FROM
;
into_tag :
INTO
;
work_tag :
WORK
;
with_grant_option :
WITH GRANT OPTION
;
with_admin_option :
WITH ADMIN OPTION
;
time_zone_or_local :
TIME ZONE
| LOCAL TIME ZONE
;
sub_plsql_datatype :
datatype
| qualified_name dblink_clause? '%' TYPE
| qualified_name dblink_clause? '%' ROWTYPE
;
datatype_list :
datatype (COMMA datatype)*
;
datatype :
dtype double_length_option? (WITH time_zone_or_local | WITHOUT TIME ZONE)?
| INTERVAL interval_qualifier
| dtype LARGE OBJECT double_length_option?
;
datatype2 :
dtype1 double_length_option?
| INTERVAL interval_qualifier
;
opr_dtype :
dtype
| NULL
;
opr_datatype_lst :
opr_dtype COMMA opr_dtype
;
interval_qualifier :
interval_nresvd_word double_length_option? (TO interval_nresvd_word double_length_option?)?
;
dtype :
dtype1
| dtype2
;
dtype1 :
qualified_name
| BINARY_KEYWORD
| sql_builtin_types
;
dtype2 :
CHAR VARYING
| CHARACTER VARYING
| NCHAR VARYING
| NATIONAL CHAR VARYING
| NATIONAL CHAR
| NCHARACTER VARYING
| NATIONAL CHARACTER VARYING
| NATIONAL CHARACTER
| DOUBLE PRECISION
| REF '(' qualified_name ')'
;
double_length_option :
'(' LT_INTEGER size_unit_caluse? ')'
| '(' LT_INTEGER COMMA LT_INTEGER ')'
| '(' '*' COMMA LT_INTEGER ')'
;
size_unit_caluse :
CHAR
| BYTE
;
lt_integer_negative :
LT_INTEGER
| '-' LT_INTEGER
;
create_contextindex_stmt :
CREATE replace_option? CONTEXT INDEX not_exist? index_name ON full_table_name '(' index_column_list ')' storage_tag? lexer_clause? sync?
;
lexer_name :
id
;
lexer_clause :
LEXER lexer_name
;
lexer_clause2 :
LEXER lexer_name
;
sync :
SYNC
| SYNC TRANSACTION
;
drop_contextindex_stmt :
DROP CONTEXT INDEX exist? index_name ON full_table_name
;
alter_contextindex_stmt :
alter_tag CONTEXT INDEX index_name ON full_table_name cti_sync_option online_options? lexer_clause2?
;
cti_sync_option :
REBUILD
| INCREMENT
| OPTIMIZE
;
type_name :
qualified_name
| BINARY_KEYWORD
;
sizeof_type :
type_name
| builtin_types
;
type :
sizeof_type
| array_type
;
array_type :
sizeof_type rank_specifiers
;
builtin_types :
OBJECT
| BSTRING
| BOOL
| DECIMAL
| FLOAT
| DOUBLE
| integral_type
;
integral_type :
SBYTE
| BYTE
| SHORT
| USHORT
| INT
| UINT
| ULONG
| CHAR
| VOID
;
sql_builtin_types :
BOOL
| DECIMAL
| FLOAT
| DOUBLE
| INT
| CHAR
| BYTE
;
cursor_declaration :
CURSOR cursor_name cursor_attrs_options? cursor_option?
;
cursor_declaration_2 :
cursor_declaration
| variable_name_list CURSOR cursor_attrs_options? cursor_option_2
;
cursor_attrs_options :
cursor_attrs
;
cursor_attrs :
cursor_attr
| cursor_attrs cursor_attr
;
cursor_attr :
INSENSITIVE
| SENSITIVE
| ASENSITIVE
| NO SCROLL
| SCROLL
| WITHOUT HOLD
| WITH HOLD
| WITHOUT RETURN
| WITH RETURN
| FAST
| NO FAST
;
opt_rank_specifier :
rank_specifiers
;
rank_specifiers :
rank_specifier
;
rank_specifier :
'[' opt_dim_separators? ']'
;
opt_dim_separators :
dim_separators
;
opt_rank_specifier2 :
opt_rank_specifier?
| '[' lt_int_lst ']'
;
dim_separators :
COMMA+
;
opt_argument_list :
mixed_param_list json_fun_tail
| bool_exp FROM exp (FOR exp)?
| all_distinct_option_2 exp
| all_distinct_option_2 exp_list_2
| '*'
| '+'
| without_into_select
;
json_fun_tail :
returning? pretty? array_wrapper? json_tail_on_error_null
| returning? pretty? array_wrapper? json_tail_on_empty json_tail_on_error_null
;
ignore_nulls_clause :
IGNORE NULLS
| RESPECT NULLS
;
mixed_param_list :
mixed_param (COMMA mixed_param)*
;
mixed_param :
argument as_alias?
| param
;
argument :
bool_exp (FORMAT JSON)?
;
cursor_option :
cursor_option_2
;
without_into_select2 :
without_into_select
| select_with_paran
;
cursor_option_2 :
IS without_into_select2
| IS joined_table
| IS TABLE full_tv_name
| FOR without_into_select2
| FOR joined_table
| FOR TABLE full_tv_name
| '(' param_def_list ')' IS without_into_select2
| '(' param_def_list ')' RETURN plsql_datatype IS without_into_select2
| RETURN plsql_datatype IS without_into_select2
;
region_size :
GREAT
| MICRO
;
copy_num :
COPY LT_INTEGER
;
redundancy_clause :
EXTERNAL
| NORMAL
| HIGH
;
striping_clause :
STRIPING LT_INTEGER
;
with_huge_clause :
WITH HUGE PATH pathname region_size?
;
================================================
FILE: superior-dameng-parser/src/main/kotlin/io/github/melin/superior/parser/dameng/AbstractSqlParser.kt
================================================
package io.github.melin.superior.parser.dameng
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.parser.dameng.antlr4.DmSqlParser
import java.util.concurrent.atomic.AtomicReference
object AbstractSqlParser {
private val parserCaches = AtomicReference(AntlrCaches(DmSqlParser._ATN))
/**
* Install the parser caches into the given parser.
*
* This method should be called before parsing any input.
*/
fun installCaches(parser: DmSqlParser): Unit = parserCaches.get().installCaches(parser)
/**
* Drop the existing parser caches and create a new one.
*
* ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can
* consume a lot of memory depending on the input seen so far.
*
* This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL
* inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.
*/
fun refreshParserCaches() {
parserCaches.set(AntlrCaches(DmSqlParser._ATN))
}
}
================================================
FILE: superior-dameng-parser/src/main/kotlin/io/github/melin/superior/parser/dameng/DmSqlAntlr4Visitor.kt
================================================
package io.github.melin.superior.parser.dameng
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.SQLParserException
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.TableType
import io.github.melin.superior.common.antlr4.ParserUtils.source
import io.github.melin.superior.common.relational.DefaultStatement
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.alter.AlterTable
import io.github.melin.superior.common.relational.common.CommentStatement
import io.github.melin.superior.common.relational.common.ShowStatement
import io.github.melin.superior.common.relational.create.CreateMaterializedView
import io.github.melin.superior.common.relational.create.CreateTable
import io.github.melin.superior.common.relational.create.CreateView
import io.github.melin.superior.common.relational.dml.*
import io.github.melin.superior.common.relational.drop.DropTable
import io.github.melin.superior.parser.dameng.antlr4.DmSqlParser
import io.github.melin.superior.parser.dameng.antlr4.DmSqlParserBaseVisitor
import org.antlr.v4.runtime.ParserRuleContext
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2018/2/8. */
class DmSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) : DmSqlParserBaseVisitor() {
private var rootTableId: TableId = TableId("")
private var currentOptType: StatementType = StatementType.UNKOWN
private var limit: Int? = null
private var offset: Int? = null
private val primaryKeys = ArrayList()
private var queryStmt: QueryStmt? = null
private var inputTables: ArrayList = arrayListOf()
private var outputTables: ArrayList = arrayListOf()
private var cteTempTables: ArrayList = arrayListOf()
// 多语句解析结果
private var statements: ArrayList = arrayListOf()
// 存储过程和函数中包含的子语句
private var childStatements: ArrayList = arrayListOf()
private val sqls: ArrayList = arrayListOf()
fun getSqlStatements(): List {
return statements
}
fun getSplitSqls(): List {
return sqls
}
override fun visitDmprogram(ctx: DmSqlParser.DmprogramContext): Statement? {
ctx.sql_clauses().forEach {
var sql = source(it)
if (splitSql) {
if (StringUtils.endsWith(sql, ";")) {
sql = StringUtils.substringBeforeLast(sql, ";")
}
sqls.add(sql)
} else {
val startNode = it.start.text
val statement =
if (StringUtils.equalsIgnoreCase("show", startNode)) {
val keyWords: ArrayList = arrayListOf()
CommonUtils.findShowStatementKeyWord(keyWords, it)
ShowStatement(*keyWords.toTypedArray())
} else {
var statement = this.visitSql_clauses(it)
if (statement == null) {
statement = DefaultStatement(StatementType.UNKOWN)
}
statement
}
statement.setSql(sql)
statements.add(statement)
currentOptType = StatementType.UNKOWN
}
}
return null
}
override fun visitSelect_stmt(ctx: DmSqlParser.Select_stmtContext?): Statement? {
currentOptType = StatementType.SELECT
super.visitSelect_stmt(ctx)
return queryStmt
}
override fun visitQuery_exp(ctx: DmSqlParser.Query_expContext?): Statement? {
super.visitQuery_exp(ctx)
queryStmt = QueryStmt(inputTables, limit, offset)
val sql = source(ctx)
queryStmt?.setSql(sql)
return queryStmt
}
override fun visitMerge_into_stmt(ctx: DmSqlParser.Merge_into_stmtContext?): Statement {
currentOptType = StatementType.MERGE
super.visitMerge_into_stmt(ctx)
return MergeTable(rootTableId, inputTables)
}
override fun visitInsert_stmt(ctx: DmSqlParser.Insert_stmtContext?): Statement {
currentOptType = StatementType.INSERT
super.visitInsert_stmt(ctx)
var curQueryStmt: QueryStmt = QueryStmt()
if (queryStmt != null) {
curQueryStmt = queryStmt as QueryStmt
}
val retObj = InsertTable(InsertMode.INTO, curQueryStmt, rootTableId)
retObj.outputTables.clear()
retObj.outputTables.addAll(outputTables)
return retObj
}
override fun visitUpdate_stmt(ctx: DmSqlParser.Update_stmtContext?): Statement {
currentOptType = StatementType.UPDATE
super.visitUpdate_stmt(ctx)
return UpdateTable(rootTableId, inputTables)
}
override fun visitDelete_stmt(ctx: DmSqlParser.Delete_stmtContext?): Statement {
currentOptType = StatementType.DELETE
super.visitDelete_stmt(ctx)
return DeleteTable(rootTableId, inputTables)
}
override fun visitCreate_table_stmt(ctx: DmSqlParser.Create_table_stmtContext?): Statement {
currentOptType = StatementType.CREATE_TABLE
super.visitCreate_table_stmt(ctx)
return CreateTable(rootTableId, TableType.DAMENG)
}
override fun visitCreate_view_stmt(ctx: DmSqlParser.Create_view_stmtContext?): Statement {
currentOptType = StatementType.CREATE_VIEW
super.visitCreate_view_stmt(ctx)
return CreateView(rootTableId, QueryStmt(inputTables, limit, offset))
}
override fun visitCreate_materialized_view_stmt(ctx: DmSqlParser.Create_materialized_view_stmtContext?): Statement {
currentOptType = StatementType.CREATE_MATERIALIZED_VIEW
super.visitCreate_materialized_view_stmt(ctx)
return CreateMaterializedView(rootTableId, QueryStmt(inputTables, limit, offset))
}
override fun visitFull_view_name2(ctx: DmSqlParser.Full_view_name2Context?): Statement? {
if (currentOptType == StatementType.CREATE_VIEW
|| currentOptType == StatementType.CREATE_MATERIALIZED_VIEW) {
if (ctx?.qualified_name2() != null) {
rootTableId = parseTableViewName(ctx.qualified_name2())
}
}
return super.visitFull_view_name2(ctx)
}
override fun visitComment_stmt(ctx: DmSqlParser.Comment_stmtContext): Statement {
super.visitComment_stmt(ctx)
var objValue: String? = null
val isNull = false
var objType: String = ""
val text: String = CommonUtils.cleanQuote(ctx.LT_STRING().text)
val fullTableName = ctx.full_table_name()
val fullColumnName = ctx.full_column_name()
val fullViewName = ctx.full_view_name()
if (fullTableName != null) {
objType = "TABLE"
objValue = fullTableName.qualified_name().text
} else if(fullColumnName != null) {
objType = "COLUMN"
objValue = fullColumnName.qualified_name().text
} else if(fullViewName != null) {
objType = "VIEW"
objValue = fullViewName.qualified_name().text
}
currentOptType = StatementType.COMMENT
return CommentStatement(text, isNull, objType, objValue)
}
override fun visitDrop_stmt(ctx: DmSqlParser.Drop_stmtContext?): Statement? {
super.visitDrop_stmt(ctx)
val dropDbObject = ctx?.drop_db_object()
if (dropDbObject?.db_object()?.text.equals("table")) {
currentOptType = StatementType.DROP_TABLE
val dropStmtBody = ctx?.drop_stmt_body_1()
if (dropStmtBody?.full_object_name() != null) {
rootTableId = parseTableViewName(dropStmtBody.full_object_name().qualified_name())
} else if(dropStmtBody?.full_table_name() != null) {
rootTableId = parseTableViewName(dropStmtBody.full_table_name().qualified_name())
}
val dropTable = DropTable(rootTableId, dropDbObject?.exist()?.text == "ifexists")
if (dropStmtBody?.purge_option() != null) {
dropTable.purge = true
}
return dropTable
}
return null
}
override fun visitAlter_table_stmt(ctx: DmSqlParser.Alter_table_stmtContext): Statement {
currentOptType = StatementType.ALTER_TABLE
super.visitAlter_table_stmt(ctx)
rootTableId = parseTableViewName(ctx.full_table_name().qualified_name())
return AlterTable(rootTableId)
}
override fun visitFull_tv_name(ctx: DmSqlParser.Full_tv_nameContext): Statement? {
super.visitFull_tv_name(ctx)
val tableId = parseTableViewName(ctx.qualified_name())
val parentLv2 = ctx.parent?.parent
val parentLv5 = parentLv2?.parent?.parent?.parent
val parentLv6 = parentLv5?.parent
if (parentLv6 is DmSqlParser.Update_stmt_bodyContext
|| parentLv5 is DmSqlParser.Delete_stmtContext
|| parentLv2 is DmSqlParser.Insert_stmtContext
|| parentLv5 is DmSqlParser.Insert_stmtContext
|| parentLv5 is DmSqlParser.Insert_stmt_bodyContext
|| parentLv5 is DmSqlParser.Multi_insert_stmt_bodyContext
|| parentLv2 is DmSqlParser.Merge_into_stmtContext) {
if (rootTableId.tableName == "") {
tableId.also { rootTableId = it }
}
addOutputTableId(tableId)
} else {
if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {
inputTables.add(tableId)
}
}
return null
}
override fun visitFull_table_name(ctx: DmSqlParser.Full_table_nameContext?): Statement? {
if (ctx?.qualified_name() != null) {
rootTableId = parseTableViewName(ctx.qualified_name())
}
return super.visitFull_table_name(ctx)
}
private fun parseTableViewName(ctx: ParserRuleContext): TableId {
if (ctx.childCount == 1) {
return TableId(null, null, CommonUtils.cleanQuote(ctx.getChild(0).text))
} else if (ctx.childCount == 3) {
return TableId(null, CommonUtils.cleanQuote(ctx.getChild(0).text), CommonUtils.cleanQuote(ctx.getChild(2).text))
} else {
throw SQLParserException("not suuport tablename")
}
}
private fun addOutputTableId(tableId: TableId) {
if (!outputTables.contains(tableId)) {
outputTables.add(tableId)
}
}
}
================================================
FILE: superior-dameng-parser/src/main/kotlin/io/github/melin/superior/parser/dameng/DmSqlHelper.kt
================================================
package com.github.melin.superior.sql.parser.mysql
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.common.antlr4.ParseErrorListener
import io.github.melin.superior.common.antlr4.ParseException
import io.github.melin.superior.common.antlr4.UpperCaseCharStream
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.parser.dameng.AbstractSqlParser
import io.github.melin.superior.parser.dameng.DmSqlAntlr4Visitor
import io.github.melin.superior.parser.dameng.antlr4.DmSqlLexer
import io.github.melin.superior.parser.dameng.antlr4.DmSqlParser
import io.github.melin.superior.parser.dameng.antlr4.DmSqlParserBaseVisitor
import org.antlr.v4.runtime.CharStreams
import org.antlr.v4.runtime.CommonTokenStream
import org.antlr.v4.runtime.atn.PredictionMode
import org.antlr.v4.runtime.misc.ParseCancellationException
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2018/1/10. */
object DmSqlHelper {
@JvmStatic
fun sqlKeywords(): List {
val keywords = hashSetOf()
(0 until DmSqlLexer.VOCABULARY.maxTokenType).forEach { idx ->
val name = DmSqlLexer.VOCABULARY.getLiteralName(idx)
if (name != null) {
val matchResult = CommonUtils.KEYWORD_REGEX.find(name)
if (matchResult != null) {
keywords.add(matchResult.groupValues.get(1))
}
}
}
return keywords.sorted()
}
@JvmStatic
fun parseStatement(command: String): Statement {
val statements = this.parseMultiStatement(command)
if (statements.size != 1) {
throw IllegalStateException("only parser one sql, sql count: " + statements.size)
} else {
return statements.get(0)
}
}
@JvmStatic
fun parseMultiStatement(command: String): List {
val trimCmd = StringUtils.trim(command)
val sqlVisitor = DmSqlAntlr4Visitor(false, trimCmd)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSqlStatements()
}
@JvmStatic
fun splitSql(command: String): List {
val trimCmd = StringUtils.trim(command)
val sqlVisitor = DmSqlAntlr4Visitor(true, trimCmd)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSplitSqls()
}
@JvmStatic
fun checkSqlSyntax(command: String) {
val sqlVisitor = DmSqlParserBaseVisitor()
innerParseStatement(command, sqlVisitor)
}
private fun innerParseStatement(command: String, sqlVisitor: DmSqlParserBaseVisitor) {
val charStream = UpperCaseCharStream(CharStreams.fromString(command))
val lexer = DmSqlLexer(charStream)
lexer.removeErrorListeners()
lexer.addErrorListener(ParseErrorListener())
val tokenStream = CommonTokenStream(lexer)
val parser = DmSqlParser(tokenStream)
AbstractSqlParser.installCaches(parser)
parser.removeErrorListeners()
parser.addErrorListener(ParseErrorListener())
try {
try {
// first, try parsing with potentially faster SLL mode
sqlVisitor.visitDmprogram(parser.dmprogram())
} catch (e: ParseCancellationException) {
tokenStream.seek(0) // rewind input stream
parser.reset()
// Try Again.
parser.interpreter.predictionMode = PredictionMode.LL
sqlVisitor.visitDmprogram(parser.dmprogram())
}
} catch (e: ParseException) {
if (StringUtils.isNotBlank(e.command)) {
throw e
} else {
throw e.withCommand(command)
}
} finally {
val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)
if (releaseAntlrCache == null || "true".equals(releaseAntlrCache)) {
AbstractSqlParser.refreshParserCaches()
}
}
}
}
================================================
FILE: superior-dameng-parser/src/test/kotlin/io/github/melin/superior/parser/dameng/DmSqlParserDdlTest.kt
================================================
package io.github.melin.superior.parser.dameng
import com.github.melin.superior.sql.parser.mysql.DmSqlHelper
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.alter.AlterTable
import io.github.melin.superior.common.relational.common.CommentStatement
import io.github.melin.superior.common.relational.create.CreateMaterializedView
import io.github.melin.superior.common.relational.create.CreateTable
import io.github.melin.superior.common.relational.create.CreateView
import io.github.melin.superior.common.relational.drop.DropTable
import org.junit.Assert
import org.junit.Test
class DmSqlParserDdlTest {
@Test
fun createTableTest0() {
val sql = """
CREATE TABLE employees(
employee_id number(10) NOT NULL,
employee_name varchar2(50) NOT NULL,
city varchar2(50),
CONSTRAINT employees_pk PRIMARY KEY (employee_id)
)
""".trimIndent()
DmSqlHelper.splitSql(sql)
val statement = DmSqlHelper.parseStatement(sql)
if (statement is CreateTable) {
Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)
Assert.assertEquals("employees", statement.tableId.tableName)
// Assert.assertEquals(3, statement.columnRels?.size)
// Assert.assertTrue(statement.columnRels?.get(0)?.primaryKey!!)
// Assert.assertFalse(statement.columnRels?.get(1)?.primaryKey!!)
} else {
Assert.fail()
}
}
@Test
fun createView0() {
val sql = """
CREATE OR REPLACE VIEW comedies AS
SELECT f.*,
country_code_to_name(f.country_code) AS country,
(SELECT avg(r.rating)
FROM user_ratings r
WHERE r.film_id = f.id) AS avg_rating
FROM films f
WHERE f.kind = 'Comedy'
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is CreateView) {
Assert.assertEquals(StatementType.CREATE_VIEW, statement.statementType)
Assert.assertEquals("comedies", statement.tableId.tableName)
Assert.assertEquals(2, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun createMatView0() {
val sql = """
CREATE MATERIALIZED VIEW sales_summary AS
SELECT
seller_no,
invoice_date,
sum(invoice_amt) as sales_amt
FROM invoice
WHERE invoice_date < CURRENT_DATE
GROUP BY
seller_no,
invoice_date;
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is CreateMaterializedView) {
Assert.assertEquals(StatementType.CREATE_MATERIALIZED_VIEW, statement.statementType)
Assert.assertEquals("sales_summary", statement.tableId.tableName)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun commentTest0() {
val sql = """
COMMENT ON COLUMN employees.job_id IS 'abbreviated job title';
COMMENT ON COLUMN employees1.job_id IS 'abbreviated1 job title'
""".trimIndent()
val statement = DmSqlHelper.parseMultiStatement(sql)
val st1 = statement[0]
val st2 = statement[1]
if (st1 is CommentStatement) {
Assert.assertEquals(StatementType.COMMENT, st1.statementType)
Assert.assertEquals("employees.job_id", st1.objValue)
Assert.assertEquals("abbreviated job title", st1.comment)
Assert.assertFalse(st1.isNull)
}
if (st2 is CommentStatement) {
Assert.assertEquals(StatementType.COMMENT, st2.statementType)
Assert.assertEquals("employees1.job_id", st2.objValue)
Assert.assertEquals("abbreviated1 job title", st2.comment)
Assert.assertFalse(st2.isNull)
}
}
@Test
fun dropTableTest() {
val sql = """
drop table employees purge;
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is DropTable) {
Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)
Assert.assertEquals("employees", statement.tableId.tableName)
Assert.assertTrue(statement.purge)
} else {
Assert.fail()
}
}
@Test
fun alterTableTest() {
val sql = """
ALTER TABLE "t1" RENAME COLUMN "old_column" TO "new_column_temp";
ALTER TABLE "t2" ADD "new_column" VARCHAR(8000);
ALTER TABLE "t3" DROP COLUMN "new_column_temp";
""".trimIndent()
val statement = DmSqlHelper.parseMultiStatement(sql)
val st1 = statement[0]
val st2 = statement[1]
val st3 = statement[2]
if (st1 is AlterTable) {
Assert.assertEquals(StatementType.ALTER_TABLE, st1.statementType)
Assert.assertEquals("t1", st1.tableId.tableName)
} else {
Assert.fail()
}
if (st2 is AlterTable) {
Assert.assertEquals(StatementType.ALTER_TABLE, st2.statementType)
Assert.assertEquals("t2", st2.tableId.tableName)
} else {
Assert.fail()
}
if (st3 is AlterTable) {
Assert.assertEquals(StatementType.ALTER_TABLE, st3.statementType)
Assert.assertEquals("t3", st3.tableId.tableName)
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-dameng-parser/src/test/kotlin/io/github/melin/superior/parser/dameng/DmSqlParserDmlTest.kt
================================================
package io.github.melin.superior.parser.dameng
import com.github.melin.superior.sql.parser.mysql.DmSqlHelper
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.dml.DeleteTable
import io.github.melin.superior.common.relational.dml.InsertTable
import io.github.melin.superior.common.relational.dml.MergeTable
import io.github.melin.superior.common.relational.dml.QueryStmt
import io.github.melin.superior.common.relational.dml.UpdateTable
import org.apache.commons.io.FileUtils
import org.junit.Assert
import org.junit.Test
import java.io.File
/** Created by libinsong on 2018/1/10. */
class DmSqlParserDmlTest {
@Test
fun querySqlTest0() {
val sql1 = FileUtils.readFileToString(File("./src/test/resources/insert.sql"), "UTF-8")
val statement = DmSqlHelper.parseStatement(sql1)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals(27, statement.queryStmt.inputTables.size)
Assert.assertEquals(TableId("dwd", "dwd_d03_contract_det_s"), statement.outputTables.get(0))
} else {
Assert.fail()
}
}
@Test
fun querySqlTest1() {
val sql = """
select 1 from db.t1;
""".trimIndent()
try {
val statement = DmSqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(1, statement.inputTables.size)
Assert.assertEquals(TableId(null, "db", "t1"), statement.inputTables[0])
} else {
Assert.fail()
}
} catch (e: Exception) {
Assert.fail()
}
}
@Test
fun cteSqlTest0() {
val sql = """
WITH
cte1 AS (SELECT 'a' AS a, 'b' AS b),
cte2 AS (SELECT 'c' AS c, 'd' AS d)
SELECT b, d FROM cte1 JOIN cte2 ON cte1.a = cte2.c;
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(2, statement.inputTables.size)
Assert.assertEquals(TableId("cte1"), statement.inputTables.get(0))
} else {
Assert.fail()
}
}
@Test
fun deleteTest() {
val sql = """
DELETE FROM films
WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is DeleteTable) {
Assert.assertEquals(StatementType.DELETE, statement.statementType)
Assert.assertEquals("films", statement.tableId.tableName)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun updateTest0() {
val sql = """
UPDATE employees SET sales_count = sales_count + 1 WHERE id =
(SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is UpdateTable) {
Assert.assertEquals(StatementType.UPDATE, statement.statementType)
Assert.assertEquals("employees", statement.tableId.tableName)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest0() {
val sql = """
INSERT ALL
INTO pivot_dest (id, day, val) VALUES (id, 'mon', mon_val)
INTO pivot_dest (id, day, val) VALUES (id, 'tue', tue_val)
INTO pivot_dest (id, day, val) VALUES (id, 'wed', wed_val)
INTO pivot_dest (id, day, val) VALUES (id, 'thu', thu_val)
INTO pivot_dest (id, day, val) VALUES (id, 'fri', fri_val)
SELECT *
FROM pivot_source;
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("pivot_dest", statement.outputTables.get(0).tableName)
Assert.assertEquals(1, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest1() {
val sql = """
INSERT ALL
INTO dest_tab1 (id, description) VALUES (id, description)
INTO dest_tab2 (id, description) VALUES (id, description)
INTO dest_tab3 (id, description) VALUES (id, description)
SELECT id, description
FROM source_tab;
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("dest_tab1", statement.outputTables.get(0).tableName)
Assert.assertEquals(3, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest2() {
val sql = """
INSERT ALL
WHEN id <= 3 THEN
INTO dest_tab1 (id, description) VALUES (id, description)
WHEN id BETWEEN 4 AND 7 THEN
INTO dest_tab2 (id, description) VALUES (id, description)
WHEN id >= 8 THEN
INTO dest_tab3 (id, description) VALUES (id, description)
SELECT id, description
FROM source_tab;
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("dest_tab1", statement.outputTables.get(0).tableName)
Assert.assertEquals(3, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest3() {
val sql = """
INSERT FIRST
WHEN id <= 3 THEN
INTO dest_tab1 (id, description) VALUES (id, description)
WHEN id <= 5 THEN
INTO dest_tab2 (id, description) VALUES (id, description)
ELSE
INTO dest_tab3 (id, description) VALUES (id, description)
SELECT id, description
FROM source_tab;
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("dest_tab1", statement.outputTables.get(0).tableName)
Assert.assertEquals(3, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest4() {
val sql = """
INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("films", statement.tableId?.tableName)
Assert.assertEquals(1, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun deltaMergeTest() {
val sql = """
MERGE INTO bonuses D
USING (SELECT employee_id, salary, department_id FROM hr.employees
WHERE department_id = 80) S
ON (D.employee_id = S.employee_id)
WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01
DELETE WHERE (S.salary > 8000)
WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus)
VALUES (S.employee_id, S.salary*.01)
WHERE (S.salary <= 8000);
""".trimIndent()
val statement = DmSqlHelper.parseStatement(sql)
if (statement is MergeTable) {
Assert.assertEquals(StatementType.MERGE, statement.statementType)
Assert.assertEquals("bonuses", statement.targetTable.tableName)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-dameng-parser/src/test/kotlin/io/github/melin/superior/parser/dameng/DmSqlProcedureParserTest.kt
================================================
package io.github.melin.superior.parser.dameng
class DmSqlProcedureParserTest {}
================================================
FILE: superior-dameng-parser/src/test/resources/insert.sql
================================================
insert into dwd.dwd_d03_contract_det_s
select to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') stt_date
,to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') end_date
,'01' cont_source_cd -- 合同来源编码: 01-通用核心; 02-商用车
,'通用核心' cont_source_nm -- 合同来源:通用核心/商用车
,cc.pk_contract -- 合同主键
,cc.cont_code -- 合同编码
,cc.cont_name -- 合同名称
,cc.cont_type cont_type_cd -- 合同类型编码
,pt2.param_name cont_type_nm -- 合同类型名称
,cc.cont_status cont_status_cd -- 合同状态编码
,pt1.param_name cont_status_nm -- 合同状态名称
,pt3.param_value economic_style_cd -- 控股类型编码
,replace(replace(pt3.param_name ,'绝对',''),'相对','') economic_style_nm -- 控股类型
,cc.cont_amount -- 合同金额
,cc.lease_date_fact -- 起租日
,cc.cont_end_date -- 到期日
,lc.lease_times lease_times -- 租赁期(月数)
,round(lc.lease_times/12,2) lease_year -- 租赁期(年数)
,case when cc.cont_amount >= 100000000 then '大型'
when cc.cont_amount >= 10000000 and cc.cont_amount < 100000000
then '中型'
else '小型'
end cont_scala -- 合同规模
,case when cc.if_adjust = 0 then '是'
when cc.if_adjust = 1 then '否'
else null
end if_adjust -- 是否调息
,sjtf.fact_cash_loan -- 已投放金额
,sjtf.pay_date -- 首次投放日期
,ba1.name pay_province -- 投放地区省
,ba2.name pay_city -- 投放地区市
,ba3.name pay_area -- 客户所属区
,coalesce(nn.assets_classify, cc.assets_classify, 0) assets_classify_cd -- 五级分类代码
,case coalesce(nn.assets_classify, cc.assets_classify, 0)
when 0 then '正常'
when 1 then '关注'
when 2 then '次级'
when 3 then '可疑'
when 4 then '损失'
else '正常'
end assets_classify_nm -- 五级分类名称
,pi.pk_project_info -- 项目编号
,pi.project_name -- 项目名称
,pi.lease_categry lease_categry_cd -- 租赁类型代码
,case when pi.lease_categry = 0 then '融资租赁'
when pi.lease_categry = 1 then '经营性租赁'
else null
end lease_categry_nm -- 租赁类型名称
,case when pbl.if_group_company = 0 then '是'
else '否'
end if_group_company -- 是否集团客户
,pbl.vesting_group -- 集团客户名称
,lc.lease_method lease_method_cd -- 业务类型代码
,case when lc.lease_method = 0 then '直租'
when lc.lease_method = 1 then '回租'
when lc.lease_method = 4 then '转租赁'
else null
end lease_method_nm -- 业务类型名称
,main_thing.fixed_assets -- 固定资产门类
,main_thing.fixed_assets_lag -- 固定资产门类-大类
,main_thing.fixed_assets_mid -- 固定资产门类--中类
,main_thing.fixed_assets_sml -- 固定资产门类--小类
,main_thing.thing_name -- 租赁物名称
-- 主办人相关信息
,su.user_code main_user_code -- 主办项目经理编号
,su.user_name main_user_name -- 主办项目经理
,su.dept_code main_dept_code -- 主办业务部门编号
,su.dept_name main_dept_name -- 主办业务部门名称
-- 协办人相关信息
,su2.user_code help_user_code -- 协办项目经理编号
,su2.user_name help_user_name -- 协办项目经理
,su2.dept_code help_dept_code -- 协办业务部门编号
,su2.dept_name help_dept_name -- 协办业务部门名称
,coalesce(pa.sponsor_performance, pa.sponsor_performance_sh * 100) sponsor_performance -- 主办分成比例(两位整数)
,coalesce(pa.help_performance, pa.help_performance_one * 100) help_performance -- 协办分成比例(两位整数)
,pn.investment investment_cd -- 城建类分类
,case when coalesce(pn.investment, cu.investment) = 0
then '是'
else '否'
end investment_nm -- 是否城建类
,vc.customer_name -- 承租人名称
,case when vc.identity_type = 4 then vc.identity_no
else null
end identity_no -- 统一社会信用代码
,vc.risk_level risk_level_cd -- 客户洗钱风险评级代码
,case when vc.risk_level = '1001' then '低风险'
when vc.risk_level = '1002' then '较低风险'
when vc.risk_level = '1003' then '中风险'
when vc.risk_level = '1004' then '较高风险'
when vc.risk_level = '1005' then '高风险'
when vc.risk_level = '1006' then '无结果'
when vc.risk_level = '1007' then '查询失败'
else null
end risk_level_nm -- 客户洗钱风险评级名称
,cu.organization_code organization_code -- 组织机构代码
,hy.param_name industry -- 国标行业门类
,hy1.param_name industry_lag -- 国标行业大类
,hy2.param_name industry_mid -- 国标行业中类
,hy3.param_name industry_sml -- 国标行业小类
,coalesce(cc.business_module, dm1.business_mode_nm, '其他') industry_mod -- 业务板块——9大分类
,case when cc.cont_status = 8 or
(cc.cont_status = 2 and '${yyyy-mm-dd}' <= cc.lease_date_fact) or
(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 )
then coalesce(sjtf.fact_cash_loan,0) - coalesce(gather.gather_corpus,0) - coalesce(sfk.inner_deduct_cash,0)
else coalesce(ipc.lease_corpus,0) - coalesce(gather.gather_corpus,0) - coalesce(sfk.inner_deduct_cash,0)
end corpus_balance -- 剩余本金
,coalesce(history.lease_interest,ipc.lease_interest) - coalesce(gather.gather_interest,0) interest_balance -- 剩余利息
,case when yoc.pk_contract is not null then coalesce(lpb.deposit_balance,0)
else 0
end deposit_balance -- 剩余保证金
-- 调整剩余保证金逻辑, 保持和源端取值一样 11.22(剩余风险抵押金 按照逻辑把字段衍生出来)
-- ,coalesce(lpb.deposit_balance,0) deposit_balance -- 剩余保证金
,case when yoc.pk_contract is null then coalesce(lpb.deposit_balance,0)
else 0
end mortgage_balance -- 剩余风险抵押金
,COALESCE(adj.INTERRATE_FACT_AFTER,lc.FINAL_RATE, 0) contract_rate -- 合同利率
,COALESCE(adj.PROJECT_IRR,lc.PROJECT_IRR, 0) * 100.0 PROJECT_IRR -- IRR(现行)
,COALESCE(adj.CONTRACT_XIRR,lc.CONTRACT_XIRR, 0) * 100.0 CONTRACT_XIRR -- XIRR(含税)
-- 增加字段
,case when yoc.pk_contract is null then '是'
else '否'
end is_mortgage -- 是否风险抵押金
,case when cc.cont_status = 8 and coalesce(ipo.overdue_days_zqx, 0) >= 1
then '是'
when cc.cont_status <> 8 and coalesce(ipo.overdue_days, 0) >= 1
then '是'
else '否'
end if_overdue -- 是否逾期
,yq.OVERDUE_DATE overdue_days -- 最大逾期天数(含历史)
,magum.param_name pledge_name -- 担保方式
,case when lc.interrate_type = 0
then '浮动利率' else '固定利率'
end interrate_type -- 利率类型
,ipc.lease_cash1 handling_fee -- 手续费/咨询费
,ipc.lease_cash11 fixed_rent -- 固定租金
,ipc.lease_cash2 deposit_amt -- 保证金金额
,ipc.lease_cash22 margin_bal -- 保证金余额
,ipc.lease_cash3 margin_off_amt -- 保证金冲抵金额
,ipc.lease_cash33 refund_deposit -- 退还保证金
,nn.accrue_cash -- 拨备余额
,vc.customer_code -- 承租人编号
from dwd.dg1_yls_contract_c_c cc -- 合同表
-- 补全9大分类
left join dim.dim_d99_business_mode_cd dm1
on cc.industry3 = dm1.pk_parameter
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between dm1.stt_date and dm1.end_date
-- 合同状态
left join dwd.dg1_yls_parameter_c pt1
on cc.cont_status = pt1.param_value
and pt1.pk_param_type = upper('0001AA1000000001RC3C')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt1.stt_date and pt1.end_date
-- 合同类型
left join dwd.dg1_yls_parameter_c pt2
on cc.cont_type = pt2.param_value
and pt2.pk_param_type = upper('0001AA1000000001VJBS')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt2.stt_date and pt2.end_date
-- 控股类型
left join dwd.dg1_yls_parameter_c pt3
on cc.economic_style1 = pt3.pk_parameter
and pt3.pk_param_type = upper('0001AA10000000041633')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt3.stt_date and pt3.end_date
-- 担保方式
left join dwd.dg1_yls_parameter_c magum
on cc.major_guarantee_method = magum.pk_parameter
and magum.pk_param_type = upper('0001AA1000000002K3MQ')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt3.stt_date and pt3.end_date
-- 逾期情况
left join (
select ipc.pk_contract
,coalesce(max(case
when ipc.trans_type = upper('0001AA100000000AUBPA') and
ipc.charge_off_status = 2 and
gab.check_date > '${yyyy-mm-dd}' then
to_date(gab.check_date, 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')
when ipc.trans_type = upper('0001AA100000000AUBPA') and
ipc.charge_off_status <> 2 and
ipc.plan_date <= '${yyyy-mm-dd}' then
to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')
end),
0) as overdue_days_zqx
,coalesce(max(case
when ipc.charge_off_status = 2 and
gab.check_date > '${yyyy-mm-dd}' then
to_date(gab.check_date, 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')
when ipc.charge_off_status <> 2 and
ipc.plan_date <= '${yyyy-mm-dd}' then
to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')
end),
0) as overdue_days /*租金逾期天数*/
from dwd.dg1_yls_inout_plan_c_c ipc
left join (select gab.pk_inout_plan
,coalesce(max(gap.trade_date), '${yyyy-mm-dd}') as check_date
from dwd.dg1_yls_gather_account_b_c gab
inner join dwd.dg1_yls_gather_account_c ga
on ga.pk_gather_account = gab.pk_gather_account
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date
inner join dwd.dg1_yls_gather_audit_plan_c gap
on gap.pk_gather_account_b = gab.pk_gather_account_b
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gap.stt_date and gap.end_date
where ga.billstatus = 9
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date
group by gab.pk_inout_plan) gab
on gab.pk_inout_plan = ipc.pk_inout_plan
where ipc.trans_type in (upper('0001AA10000000007NGV'),
upper('0001AA100000000AUBPA'),
upper('0001AA10000000007NH3')) /* 现金流类型 租金 收租(租前息) 首付款*/
and ipc.rent_type = 1 /* 租金表类型 会计表*/
and ipc.plan_date <= '${yyyy-mm-dd}'
and ipc.lease_cash >= 0.01
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
group by ipc.pk_contract
) ipo
on cc.pk_contract = ipo.pk_contract
left join (
select plan.PK_CONTRACT,max(rec.OVERDUE_DATE) OVERDUE_DATE
from dwd.dg1_yls_overdue_record_c rec
join dwd.dg1_yls_inout_plan_c_c plan on plan.PK_INOUT_PLAN = rec.PK_INOUT_PLAN
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between plan.stt_date and plan.end_date
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between rec.stt_date and rec.end_date
group by plan.PK_CONTRACT
) yq on yq.PK_CONTRACT = cc.PK_CONTRACT
-- 实际投放金额
left join (
select ipc.pk_contract -- 主键
,sum(coalesce(lp.real_pay_cash, 0.00)) fact_cash_loan -- 已投放金额
,min(coalesce(ld.real_pay_date, '${yyyy-mm-dd}')) pay_date -- 首次投放日
from dwd.dg1_yls_inout_plan_c_c ipc
left join dwd.dg1_yls_loan_plan_c lp
on ipc.pk_inout_plan = lp.pk_inout_plan
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date
left join dwd.dg1_yls_loan_deal_c ld
on lp.pk_loan_deal = ld.pk_loan_deal
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
and ipc.trans_type in (upper('0001AA10000000005GRC'), upper('0001AA10000000007NGO'), upper('0001AA1000000005AB31'), upper('0001AA1000000005AB32'))
and ipc.rent_type = 1 -- 租金表类型-会计表
and lp.if_account = 0 -- 是否核销为是
and lp.if_approve_cancel = 1 -- 是否审核撤销为否时
and lp.if_cancel = 1 -- 是否核销撤销为否时
and ld.billstatus = 9
and ld.real_pay_date <= '${yyyy-mm-dd}'
group by ipc.pk_contract
) sjtf
on cc.pk_contract = sjtf.pk_contract
-- 首付款
left join (
select ipc.pk_contract
,sum(coalesce(ipc.lease_cash, 0.00)) as inner_deduct_cash
,min(coalesce(ld.real_pay_date, '${yyyy-mm-dd}')) as pay_date
from dwd.dg1_yls_inout_plan_c_c ipc
left join dwd.dg1_yls_loan_plan_c lp
on lp.pk_inout_plan = ipc.pk_inout_plan
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date
left join dwd.dg1_yls_loan_deal_c ld
on ld.pk_loan_deal = lp.pk_loan_deal
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date
where ipc.trans_type = '0001AA10000000007NH3' /* 现金流类型 设备款*/
and ipc.rent_type = 1 /* 租金表类型 会计表*/
and lp.if_inner_deduct = 2 /* 是否内扣为是 */
and lp.if_cancel = 1 /* 是否核销撤销为否时 */
and ld.billstatus = 9
and ld.real_pay_date <= '${yyyy-mm-dd}'
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
group by ipc.pk_contract
) sfk
on cc.pk_contract = sfk.pk_contract
-- 五级分类
left join (
select i1.pk_contract -- 合同PK
,i1.assets_classify -- 五级分类
,i1.accrue_cash
from dwd.dg1_assets_classify_history_c i1 -- yls_assets_classify_history
join (
select ic.pk_contract
,max(ic.pk_assets_classify_history) pk_assets_classify_history
from dwd.dg1_assets_classify_history_c ic
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ic.stt_date and ic.end_date
and (
case when ic.if_new = 0 then ic.period
else coalesce(substr(replace(ic.change_date, '-', ''), 1, 6), ic.period)
end
) <= substr(replace('${yyyy-mm-dd}', '-', ''), 1, 6)
group by ic.pk_contract
) i2
on i1.pk_assets_classify_history = i2.pk_assets_classify_history
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between i1.stt_date and i1.end_date
) nn
on cc.pk_contract = nn.pk_contract
-- 项目信息
left join dwd.dg1_yls_project_info_c pi
on cc.pk_project = pi.pk_project_info
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pi.stt_date and pi.end_date
-- 集团客户
left join (
select distinct source_bill, if_group_company, vesting_group
from dwd.dg1_yls_project_both_lessee_c
where lessee_type = 0
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between stt_date and end_date
) pbl
on pi.pk_project_info = pbl.source_bill
-- 主办/协办信息
left join dwd.dg1_yls_project_approval_c pa
on pi.pk_project_approval = pa.pk_project_approval
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pa.stt_date and pa.end_date
-- 城建类
left join (
select row_number() over(partition by pk_project_info order by ts) rcnt
,i3.pk_project_info
,i3.investment -- 城建类判断
from dwd.dg1_yls_prj_nodecollect_c i3
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between i3.stt_date and i3.end_date
) pn
on pi.pk_project_info = pn.pk_project_info
and pn.rcnt = 1
-- 用户信息相关
left join dwd.dg1_yls_customer_c vc
on cc.pk_customer_lessee = vc.pk_customer
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between vc.stt_date and vc.end_date
-- 企业客户基本信息
left join dwd.dg1_yls_customer_corp_c cu
on vc.pk_customer = cu.pk_customer
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between cu.stt_date and cu.end_date
-- 投放地区
left join dwd.dg1_bd_areacl_c ba1 on ba1.pk_areacl = cu.PROVINCE
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba1.stt_date and ba1.end_date
left join dwd.dg1_bd_areacl_c ba2 on ba2.pk_areacl = cu.CITY
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba2.stt_date and ba2.end_date
left join dwd.dg1_bd_areacl_c ba3 on ba3.pk_areacl = cu.DISTRICT
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba3.stt_date and ba3.end_date
-- 行业分类
left join dwd.dg1_yls_parameter_c hy
on cc.industry = hy.pk_parameter
and hy.pk_param_type = upper('0001AA1000000000OY5C')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy.stt_date and hy.end_date
left join dwd.dg1_yls_parameter_c hy1
on cc.industry1 = hy1.pk_parameter
and hy1.pk_param_type = upper('0001AA1000000000OY5C')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy1.stt_date and hy1.end_date
left join dwd.dg1_yls_parameter_c hy2
on cc.industry2 = hy2.pk_parameter
and hy2.pk_param_type = upper('0001AA1000000000OY5C')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy2.stt_date and hy2.end_date
left join dwd.dg1_yls_parameter_c hy3
on cc.industry3 = hy3.pk_parameter
and hy3.pk_param_type = upper('0001AA1000000000OY5C')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy3.stt_date and hy3.end_date
-- 剩余保证金计算
left join (
select ipc.pk_contract
,sum(case
when ipc.trans_type = '0001AA10000000007NHR' then
(case when lp.pay_cash > ipc.lease_cash then coalesce(ipc.lease_cash, 0.00)
else coalesce(lp.pay_cash, 0.00)
end) + coalesce(gac.gather_cash, 0)
when ipc.trans_type = '0001AA10000000007NHT' then
-coalesce(gab.gather_cash, 0)
when ipc.trans_type = '0001AA10000000007NI5' then
coalesce(gac.gather_cash, 0)
when ipc.trans_type = '0001AA10000000007NHX' then
-coalesce(lp.pay_cash, 0)
else 0
end) as deposit_balance
from dwd.dg1_yls_inout_plan_c_c ipc
left join (select ipc.pk_inout_plan
,coalesce(ga.charge_off_cash, 0) as gather_cash
from dwd.dg1_yls_inout_plan_c_c ipc
inner join dwd.dg1_yls_gather_account_c ga
on ipc.pk_inout_plan = ga.pk_account_bill
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date
where ga.billstatus = 9 /*单据状态 审核通过*/
and ga.check_date <= '${yyyy-mm-dd}'
and ipc.trans_type = '0001AA10000000007NHT'
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
) gab
on gab.pk_inout_plan = ipc.pk_inout_plan
left join (select ipc.pk_inout_plan
,coalesce(gab.gather_cash, 0) as gather_cash
from dwd.dg1_yls_inout_plan_c_c ipc
inner join dwd.dg1_yls_gather_account_b_c gab
on ipc.pk_inout_plan = gab.pk_inout_plan
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date
inner join dwd.dg1_yls_gather_account_c ga
on ga.pk_gather_account = gab.pk_gather_account
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date
where ga.billstatus = 9 /*单据状态 审核通过*/
and ga.check_date <= '${yyyy-mm-dd}'
and ipc.trans_type in
('0001AA10000000007NHR', '0001AA10000000007NI5')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
) gac
on gac.pk_inout_plan = ipc.pk_inout_plan
left join (select lp.pk_inout_plan
,(case when coalesce(ld.real_pay_cash, 0.00) = 0
then coalesce(ld.inner_deduct_cash, 0.00)
else coalesce(ld.real_pay_cash, 0.00)
end) as pay_cash
from dwd.dg1_yls_loan_plan_c lp
inner join dwd.dg1_yls_loan_deal_c ld
on ld.pk_loan_deal = lp.pk_loan_deal
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date
where lp.if_approve_cancel = 1 /* 是否审核撤销为否时 */
and lp.if_cancel = 1 /* 是否核销撤销为否时 */
and ld.billstatus = 9
and ld.real_pay_date <= '${yyyy-mm-dd}'
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date
) lp
on lp.pk_inout_plan = ipc.pk_inout_plan
where ipc.trans_type in ('0001AA10000000007NHR',
'0001AA10000000007NHT',
'0001AA10000000007NI5',
'0001AA10000000007NHX') /* 现金流类型 收取保证金,保证金冲抵,补足保证金,退还保证金*/
and ipc.rent_type = 1 /* 租金表类型 会计表*/
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
group by ipc.pk_contract
) lpb
on cc.pk_contract = lpb.pk_contract
left join dwd.dg1_yls_old_contract_c yoc
on cc.pk_contract = yoc.pk_contract
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between yoc.stt_date and yoc.end_date
-- 实收数据
left join (
select sum(case when et.event_code in ('10201', '10203', '10216') and gab.trade_date <= '${yyyy-mm-dd}'
then coalesce(gab.gather_cash, 0)
else 0
end) gather_cash
,sum(case when et.event_code in ('10201', '10203') and gab.trade_date <= '${yyyy-mm-dd}'
then coalesce(gab.gather_corpus, 0)
else 0
end) gather_corpus
,sum(case when et.event_code in ('10201', '10216') and gab.trade_date <= '${yyyy-mm-dd}'
then coalesce(gab.gather_interest, 0)
else 0
end) gather_interest
,sum(case when et.event_code in ('10213') and gab.trade_date <= '${yyyy-mm-dd}'
then coalesce(gab.gather_cash, 0)
else 0
end) gather_penal_cash
,sum(case when et.event_code in ('10201', '10203') and gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and
gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')
then coalesce(gab.gather_cash, 0)
else 0
end) gather_cash1
,sum(case when et.event_code in ('10201', '10203') and
gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and
gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')
then coalesce(gab.gather_corpus, 0)
else 0
end) gather_corpus1
,sum(case when et.event_code in ('10201', '10203', '10216') and
gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and
gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')
then coalesce(gab.gather_interest, 0)
else 0
end) gather_interest1
,sum(case when et.event_code in ('10213') and
gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and
gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')
then coalesce(gab.gather_cash, 0)
else 0
end) gather_penal_cash1
,sum(case when gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and
gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')
then
1
else
0
end) cur_year_time
,sum(case when gab.trade_date >= '${yyyy-mm-dd}' and
gab.trade_date <= to_char(add_months(date'${yyyy-mm-dd}', 12), 'yyyy-mm-dd') then
1
else
0
end) future_time
,ipc.pk_contract
from dwd.dg1_yls_gather_account_b_c gab
join dwd.dg1_yls_gather_account_c ga
on ga.pk_gather_account = gab.pk_gather_account
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date
join dwd.dg1_yls_inout_plan_c_c ipc
on ipc.pk_inout_plan = gab.pk_inout_plan
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
join dwd.dg1_yls_event_type_c et
on et.pk_event_type = ipc.trans_type
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date
where ga.billstatus = 9
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date
group by ipc.pk_contract
) gather
on cc.pk_contract = gather.pk_contract
left join dwd.dg1_yls_lease_calculator_c_c lc
on cc.pk_lease_calculator = lc.pk_lease_calculator
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lc.stt_date and lc.end_date
-- 实时数据
left join (
select sum(case when et.event_code in ('10201','10202','10203','10216') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash, /* 总租金 */
sum(case when et.event_code in ('10401'/*,'10402','10403'*/,'10606') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash1,/* 手续费/咨询费 */
sum(case when et.event_code in ('10405') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash11,/* 固定租金 */
sum(case when et.event_code in ('10301') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash2, /* 保证金收取 */
sum(case when et.event_code in ('10308') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash22, /* 补住保证金 */
sum(case when et.event_code in ('10302') then coalesce(ipc.fact_cash,0) else 0 end) lease_cash3, /* 保证金冲抵 */
sum(case when et.event_code in ('10304') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash33, /* 退还保证金 */
sum(case when et.event_code in ('10201','10203') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash4, /* 收取总租金 */
sum(case when et.event_code in ('10201','10202','10216') then coalesce(ipc.lease_interest,0) else 0 end) lease_interest, /* 收取总利息 */
sum(case when et.event_code in ('10101','10102') and ycc.cont_status = 8 then coalesce(ipc.fact_cash,0)
when et.event_code in ('10201','10203') and ycc.cont_status != 8 then coalesce(ipc.lease_corpus,0) else 0 end) lease_corpus, /* 总本金 */
sum(case when et.event_code in ('10301','10308') then coalesce(ipc.fact_cash,0) else 0 end) fact_cash2, /* 实收:保证金收取、补足 */
sum(case when et.event_code in ('10302','10304') then coalesce(ipc.fact_cash,0) else 0 end) fact_cash3, /* 实际:保证金冲抵、退还保证金 */
ipc.source_bill
from dwd.dg1_yls_inout_plan_c_c ipc
join dwd.dg1_yls_event_type_c et on et.pk_event_type = ipc.trans_type
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date
join dwd.dg1_yls_contract_c_c ycc on ycc.pk_contract = ipc.pk_contract
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ycc.stt_date and ycc.end_date
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
group by ipc.source_bill
) ipc on lc.pk_lease_calculator = ipc.source_bill
-- 历史数据
left join (
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,
h.lease_cash3,lease_cash22,h.lease_cash33,h.LEASE_INTEREST,
h.fact_cash2,h.fact_cash3
from dwd.dg1_yls_contract_h_c ch
join dwd.dg1_yls_rent_calculator_c rc on rc.PK_CONTRACT = ch.PK_CONTRACT
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between rc.stt_date and rc.end_date
join (
select iph.SOURCE_BILL,
sum(case when et.EVENT_CODE in ('10201','10202','10203','10216') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash, /* 收租总租金 */
sum(case when et.EVENT_CODE in ('10401'/*,'10402','10403'*/,'10405','10606') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash1, /* 手续费/咨询费/固定租金 */
sum(case when et.EVENT_CODE in ('10201','10202','10216') then coalesce(iph.LEASE_INTEREST,0) else 0 end) LEASE_INTEREST, /* 收租总租息 */
sum(case when et.EVENT_CODE in ('10301') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash2, /* 保证金收取 */
sum(case when et.EVENT_CODE in ('10308') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash22, /* 保证金补住 */
sum(case when et.EVENT_CODE in ('10302') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash3, /* 保证金冲抵*/
sum(case when et.EVENT_CODE in ('10304') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash33, /* 保证金退还 */
sum(case when et.EVENT_CODE in ('10301','10308') then coalesce(iph.FACT_CASH,0) else 0 end) fact_cash2, /* 实收:保证金收取、补足 */
sum(case when et.EVENT_CODE in ('10302','10304') then coalesce(iph.FACT_CASH,0) else 0 end) fact_cash3 /* 实际:保证金冲抵、退还保证金 */
from dwd.dg1_yls_inout_plan_h_c iph
join dwd.dg1_yls_event_type_c et on et.PK_EVENT_TYPE = iph.TRANS_TYPE
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between iph.stt_date and iph.end_date
group by iph.SOURCE_BILL
) h on h.SOURCE_BILL = rc.PK_RENT_CALCULATOR
where ch.SOURCE_BILL_VERSIONPK in (
select chh.PK_CONTRACT
from dwd.dg1_yls_contract_h_c chh
join (
select max(CHECK_DATE)CHECK_DATE,ch.cont_code
from dwd.dg1_yls_contract_h_c ch
where upper(ch.SOURCE_BILLTYPE) = upper('lease/ContractChange')
and ch.SOURCE_BILL_VERSIONPK is null
and ch.CHECK_DATE > '${yyyy-mm-dd}'
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ch.stt_date and ch.end_date
group by ch.CONT_CODE
)zj_change on zj_change.CHECK_DATE = chh.check_date and zj_change.cont_code = chh.cont_code
and upper(chh.SOURCE_BILLTYPE) = upper('lease/ContractChange')
and chh.SOURCE_BILL_VERSIONPK is null
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between chh.stt_date and chh.end_date
)
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ch.stt_date and ch.end_date
) history
on history.cont_code = cc.cont_code
-- 计划投放数量
left join (
select i5.pk_contract
,count(*) plan_count
from dwd.dg1_yls_inout_plan_c_c i5
where i5.trans_type in ('0001AA10000000005GRC','0001AA10000000007NGO','0001AA1000000005AB31', '0001AA1000000005AB32')
and i5.rent_type = 1
group by i5.pk_contract
) planc
on cc.pk_contract = planc.pk_contract
-- 租赁物信息
left join (
select ypfa1.param_name fixed_assets
,ypfa2.param_name fixed_assets_lag
,ypfa3.param_name fixed_assets_mid
,ypfa4.param_name fixed_assets_sml
,prtc.thing_name
,prtc.source_bill
from dwd.dg1_yls_project_rent_thing_c_c prtc
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
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa1.stt_date and ypfa1.end_date
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
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa2.stt_date and ypfa2.end_date
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
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa3.stt_date and ypfa3.end_date
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
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa4.stt_date and ypfa4.end_date
where prtc.is_ref_main = 0
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between prtc.stt_date and prtc.end_date
) main_thing
on cc.pk_contract = main_thing.source_bill
-- 主办
left join dwd.dwd_d01_party_c su
on cc.pk_prj_manager = su.cuserid
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between su.stt_date and su.end_date
-- 协办
left join dwd.dwd_d01_party_c su2
on cc.pk_cust_help = su2.cuserid
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between su2.stt_date and su2.end_date
left join (
select adj3.cont_code,
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,
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,
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,
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
from(
select adj.cont_code,
adj.response_day,
coalesce(min(case when adj.response_day < adj2.response_day then adj2.response_day end),'${yyyy-mm-dd}') response_day_end,
min(adj.interrate_after) interrate_after, -- /*调息后基准利率*/
min(adj.interrate_fact_after) interrate_fact_after, -- /*调息后实际利率*/
min(adj.project_irr) project_irr, -- /*调息后合同irr*/
min(adj.contract_xirr) contract_xirr -- /*合同收益xirr*/
from (select ch.cont_code,
ch.check_date as response_day,
rc.interrate as interrate_after,
rc.new_final_rate as interrate_fact_after,
rc.new_project_irr as project_irr,
rc.new_contract_xirr as contract_xirr
from dwd.dg1_yls_contract_h_c ch
join dwd.dg1_yls_rent_calculator_c rc on rc.pk_contract = ch.pk_contract
where upper(ch.source_billtype) = upper('lease/contractchange')
and ch.source_bill_versionpk is null
and ch.billstatus = 9
and date'${yyyy-mm-dd}' between ch.stt_date and ch.end_date
and date'${yyyy-mm-dd}' between rc.stt_date and rc.end_date
union all -- /*实际调息*/
select distinct cc.cont_code,aa.response_day,
aa.interrate_after, -- /*调息后基准利率*/
aa.interrate_fact_after, -- /*调息后实际利率*/
aa.project_irr, -- /*调息后合同irr*/
aa.contract_xirr -- /*合同收益xirr*/
from dwd.dg1_yls_adjust_apply_c aa
left join dwd.dg1_yls_contract_c_c cc on cc.pk_contract = aa.pk_contract
and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date
where aa.billstatus = 9
and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date
union all -- /*首次调息时,调息前信息*/
select distinct cc.cont_code,to_char(to_date(aa.response_day, 'yyyy-mm-dd') - 1, 'yyyy-mm-dd') as response_day,
aa.interrate_before as interrate_after, -- /*调息前基准利率*/
aa.interrate_fact_before as interrate_fact_after, -- /*调息前实际利率*/
aa.cont_irr_befor as project_irr, -- /*调息前合同irr*/
aa.contract_xirr_before as contract_xirr -- /*调息前合同收益xirr*/
from dwd.dg1_yls_adjust_apply_c aa
join (select min(a.response_day) as response_day,a.pk_contract
from dwd.dg1_yls_adjust_apply_c a
where a.billstatus = 9
and date'${yyyy-mm-dd}' between a.stt_date and a.end_date
group by a.pk_contract) minday
on minday.pk_contract = aa.pk_contract and minday.response_day = aa.response_day
and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date
left join dwd.dg1_yls_contract_c_c cc
on cc.pk_contract = aa.pk_contract
and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date) adj
left join (
select ch.cont_code,
ch.check_date as response_day,
rc.interrate as interrate_after,
rc.new_final_rate as interrate_fact_after,
rc.new_project_irr as project_irr,
rc.new_contract_xirr as contract_xirr
from dwd.dg1_yls_contract_h_c ch
join dwd.dg1_yls_rent_calculator_c rc on rc.pk_contract = ch.pk_contract
where upper(ch.source_billtype) = upper('lease/contractchange')
and ch.source_bill_versionpk is null
and ch.billstatus = 9
and date'${yyyy-mm-dd}' between ch.stt_date and ch.end_date
and date'${yyyy-mm-dd}' between rc.stt_date and rc.end_date
union all
select distinct cc.cont_code,aa.response_day,
aa.interrate_after, -- /*调息后基准利率*/
aa.interrate_fact_after, -- /*调息后实际利率*/
aa.project_irr, -- /*调息后合同irr*/
aa.contract_xirr -- /*合同收益xirr*/
from dwd.dg1_yls_adjust_apply_c aa
left join dwd.dg1_yls_contract_c_c cc on cc.pk_contract = aa.pk_contract
where aa.billstatus = 9
and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date
and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date
union all
select distinct cc.cont_code,to_char(to_date(aa.response_day, 'yyyy-mm-dd') - 1, 'yyyy-mm-dd') as response_day,
aa.interrate_before as interrate_after, -- /*调息前基准利率*/
aa.interrate_fact_before as interrate_fact_after, -- /*调息前实际利率*/
aa.cont_irr_befor as project_irr, -- /*调息前合同irr*/
aa.contract_xirr_before as contract_xirr -- /*调息前合同收益xirr*/
from dwd.dg1_yls_adjust_apply_c aa
join (select min(a.response_day) as response_day,a.pk_contract
from dwd.dg1_yls_adjust_apply_c a
where a.billstatus = 9
and date'${yyyy-mm-dd}' between a.stt_date and a.end_date
group by a.pk_contract) minday
on minday.pk_contract = aa.pk_contract and minday.response_day = aa.response_day
left join dwd.dg1_yls_contract_c_c cc
on cc.pk_contract = aa.pk_contract
and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date
where date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date
) adj2 on adj2.cont_code = adj.cont_code
group by adj.cont_code,adj.response_day
) adj3
group by adj3.cont_code
) adj on adj.cont_code = cc.cont_code
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between cc.stt_date and cc.end_date
-- PK_PARAM_TYPE = '0001AA1000000001RC3C' 合同状态
and cc.cont_status > '1'
and cc.cont_status not in ('5' ,'7')
================================================
FILE: superior-dameng-parser/src/test/resources/log4j2.xml
================================================
================================================
FILE: superior-flink-parser/README.md
================================================
### 介绍
### 整库同步
```sql
-- 分布表,合并写入目标库中
CREATE DATABASE IF NOT EXISTS flink_cdc_demos
WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://172.18.1.55:3306/flink_cdc_demos?characterEncoding=utf-8&useSSL=false',
'username' = 'root',
'password' = 'Datac@123',
'table-name' = '${'$'}{tableName}',
'sink.buffer-flush.interval' = '2s',
'sink.buffer-flush.max-rows' = '100',
'sink.max-retries' = '5'
)
AS DATABASE `cdc_demos_[0-9]+` INCLUDING ALL TABLES
OPTIONS(
'connector' = 'mysql-cdc',
'hostname' = '172.18.5.44',
'port' = '3306',
'username' = 'root',
'password' = 'root2023',
'checkpoint' = '10000',
'scan.startup.mode' = 'initial',
'parallelism' = '1'
)
```
### 分库分表同步
```sql
CREATE TABLE IF NOT EXISTS flink_cdc_demos.account
WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://172.18.1.55:3306/flink_cdc_demos?characterEncoding=utf-8&useSSL=false',
'username' = 'root',
'password' = 'Datac@123',
'table-name' = 'account',
'sink.buffer-flush.interval' = '2s',
'sink.buffer-flush.max-rows' = '100',
'sink.max-retries' = '5'
)
AS TABLE `cdc_demos_[0-9]*`.`account_[0-9]*`
OPTIONS(
'connector' = 'mysql-cdc',
'hostname' = '172.18.5.44',
'port' = '3306',
'username' = 'root',
'password' = 'root2023',
'checkpoint' = '10000',
'scan.startup.mode' = 'initial',
'parallelism' = '2'
)
```
### 参考
1. [Dinky在Doris实时整库同步和模式演变的探索实践](https://mp.weixin.qq.com/s/OVsbRbfLEIgSNurlP6woAg)
2. [Dinky 数据集成](http://www.dlink.top/docs/next/data_integration_guide/cdcsource_statements)
3. [CREATE DATABASE AS(CDAS)语句](https://help.aliyun.com/document_detail/374304.html)
4. [数据库类型转换](https://www.sqlines.com/oracle-to-mysql)
================================================
FILE: superior-flink-parser/pom.xml
================================================
4.0.0
io.github.melin.superior
superior-sql-parser
4.0.23
superior-flink-parser
superior-flink-parser
io.github.melin.superior
superior-common-parser
${project.version}
================================================
FILE: superior-flink-parser/src/main/antlr4/io/github/melin/superior/parser/flink/antlr4/FlinkSqlLexer.g4
================================================
lexer grammar FlinkSqlLexer;
// SKIP
WHITE_SPACE : (' ' | '\t' | '\r' | '\n') -> channel(HIDDEN);
BRACKETED_COMMENT : '/*' .*? '*/' -> channel(HIDDEN);
LINE_COMMENT: (('--' | '#') ~[\r\n]* ('\r'? '\n' | EOF) | '--' ('\r'? '\n' | EOF)) -> channel(HIDDEN);
/**
* Keywords and Reserved Keywords
* Flink uses Calcite as its SQL parser,
* The following keywords are derived from the Calcite documentation and Flink's own source code.
* First, perform a union between the keyword sets declared in the Flink source code and those in the Calcite documentation,
* then calculate the difference between the resulting set and the non-keyword set declared in the Flink source code.
*
* Calcite Documentation: https://calcite.apache.org/docs/reference.html#keywords
* Flink Parser.tdd file: https://github.com/apache/flink/blob/release-1.16/flink-table/flink-sql-parser/src/main/codegen/data/Parser.tdd
*
* Please keep the keyword in alphabetical order if new keyword is added.
* When adding new keywords, please consider whether they should be added to the NonReserved Keywords section below.
*/
KW_ABS : 'ABS';
KW_ALL : 'ALL';
KW_ALLOCATE : 'ALLOCATE';
KW_ALLOW : 'ALLOW';
KW_ALTER : 'ALTER';
KW_ANALYZE : 'ANALYZE';
KW_AND : 'AND';
KW_ANY : 'ANY';
KW_ARE : 'ARE';
KW_ARRAY : 'ARRAY';
KW_ARRAY_AGG : 'ARRAY_AGG';
KW_ARRAY_CONCAT_AGG : 'ARRAY_CONCAT_AGG';
KW_ARRAY_MAX_CARDINALITY : 'ARRAY_MAX_CARDINALITY';
KW_AS : 'AS';
KW_ASENSITIVE : 'ASENSITIVE';
KW_ASYMMETRIC : 'ASYMMETRIC';
KW_AT : 'AT';
KW_ATOMIC : 'ATOMIC';
KW_AUTHORIZATION : 'AUTHORIZATION';
KW_AVG : 'AVG';
KW_BEGIN : 'BEGIN';
KW_BEGIN_FRAME : 'BEGIN_FRAME';
KW_BEGIN_PARTITION : 'BEGIN_PARTITION';
KW_BETWEEN : 'BETWEEN';
KW_BIGINT : 'BIGINT';
KW_BINARY : 'BINARY';
KW_BIT : 'BIT';
KW_BLOB : 'BLOB';
KW_BOOLEAN : 'BOOLEAN';
KW_BOTH : 'BOTH';
KW_BY : 'BY';
KW_BYTES : 'BYTES';
KW_CALL : 'CALL';
KW_CALLED : 'CALLED';
KW_CARDINALITY : 'CARDINALITY';
KW_CASCADED : 'CASCADED';
KW_CASE : 'CASE';
KW_CAST : 'CAST';
KW_CATALOGS : 'CATALOGS';
KW_CEIL : 'CEIL';
KW_CEILING : 'CEILING';
KW_CHANGELOG_MODE : 'CHANGELOG_MODE';
KW_CHAR : 'CHAR';
KW_CHARACTER : 'CHARACTER';
KW_CHARACTER_LENGTH : 'CHARACTER_LENGTH';
KW_CHAR_LENGTH : 'CHAR_LENGTH';
KW_CHECK : 'CHECK';
KW_CLASSIFIER : 'CLASSIFIER';
KW_CLOB : 'CLOB';
KW_CLOSE : 'CLOSE';
KW_COALESCE : 'COALESCE';
KW_COLLATE : 'COLLATE';
KW_COLLECT : 'COLLECT';
KW_COLUMN : 'COLUMN';
KW_COLUMNS : 'COLUMNS';
KW_COMMENT : 'COMMENT';
KW_COMMIT : 'COMMIT';
KW_COMPUTE : 'COMPUTE';
KW_CONDITION : 'CONDITION';
KW_CONNECT : 'CONNECT';
KW_CONSTRAINT : 'CONSTRAINT';
KW_CONTAINS : 'CONTAINS';
KW_CONVERT : 'CONVERT';
KW_CORR : 'CORR';
KW_CORRESPONDING : 'CORRESPONDING';
KW_COUNT : 'COUNT';
KW_COVAR_POP : 'COVAR_POP';
KW_COVAR_SAMP : 'COVAR_SAMP';
KW_CREATE : 'CREATE';
KW_CROSS : 'CROSS';
KW_CUBE : 'CUBE';
KW_CUME_DIST : 'CUME_DIST';
KW_CURRENT : 'CURRENT';
KW_CURRENT_CATALOG : 'CURRENT_CATALOG';
KW_CURRENT_DATE : 'CURRENT_DATE';
KW_CURRENT_DEFAULT_TRANSFORM_GROUP : 'CURRENT_DEFAULT_TRANSFORM_GROUP';
KW_CURRENT_PATH : 'CURRENT_PATH';
KW_CURRENT_ROLE : 'CURRENT_ROLE';
KW_CURRENT_ROW : 'CURRENT_ROW';
KW_CURRENT_SCHEMA : 'CURRENT_SCHEMA';
KW_CURRENT_TIME : 'CURRENT_TIME';
KW_CURRENT_TIMESTAMP : 'CURRENT_TIMESTAMP';
KW_CURRENT_TRANSFORM_GROUP_FOR_TYPE : 'CURRENT_TRANSFORM_GROUP_FOR_TYPE';
KW_CURRENT_USER : 'CURRENT_USER';
KW_CURSOR : 'CURSOR';
KW_CYCLE : 'CYCLE';
KW_DATABASES : 'DATABASES';
KW_DATE : 'DATE';
KW_DATETIME : 'DATETIME';
KW_DATETIME_DIFF : 'DATETIME_DIFF';
KW_DATETIME_TRUNC : 'DATETIME_TRUNC';
KW_DATE_DIFF : 'DATE_DIFF';
KW_DATE_TRUNC : 'DATE_TRUNC';
KW_DAY : 'DAY';
KW_DAYOFWEEK : 'DAYOFWEEK';
KW_DAYOFYEAR : 'DAYOFYEAR';
KW_DEALLOCATE : 'DEALLOCATE';
KW_DEC : 'DEC';
KW_DECIMAL : 'DECIMAL';
KW_DECLARE : 'DECLARE';
KW_DEFAULT : 'DEFAULT';
KW_DEFINE : 'DEFINE';
KW_DELETE : 'DELETE';
KW_DENSE_RANK : 'DENSE_RANK';
KW_DEREF : 'DEREF';
KW_DESCRIBE : 'DESCRIBE';
KW_DETERMINISTIC : 'DETERMINISTIC';
KW_DISALLOW : 'DISALLOW';
KW_DISCONNECT : 'DISCONNECT';
KW_DISTINCT : 'DISTINCT';
KW_DOT : 'DOT';
KW_DOUBLE : 'DOUBLE';
KW_DROP : 'DROP';
KW_DYNAMIC : 'DYNAMIC';
KW_EACH : 'EACH';
KW_ELEMENT : 'ELEMENT';
KW_ELSE : 'ELSE';
KW_EMPTY : 'EMPTY';
KW_END : 'END';
// KW_END_EXEC: 'END-EXEC';
KW_END_FRAME : 'END_FRAME';
KW_END_PARTITION : 'END_PARTITION';
KW_ENFORCED : 'ENFORCED';
KW_EQUALS : 'EQUALS';
KW_ESCAPE : 'ESCAPE';
KW_ESTIMATED_COST : 'ESTIMATED_COST';
KW_EVERY : 'EVERY';
KW_EXCEPT : 'EXCEPT';
KW_EXEC : 'EXEC';
KW_EXECUTE : 'EXECUTE';
KW_EXISTS : 'EXISTS';
KW_EXP : 'EXP';
KW_EXPLAIN : 'EXPLAIN';
KW_EXTEND : 'EXTEND';
KW_EXTENDED : 'EXTENDED';
KW_EXTERNAL : 'EXTERNAL';
KW_EXTRACT : 'EXTRACT';
KW_FALSE : 'FALSE';
KW_FETCH : 'FETCH';
KW_FILTER : 'FILTER';
KW_FIRST_VALUE : 'FIRST_VALUE';
KW_FLOAT : 'FLOAT';
KW_FLOOR : 'FLOOR';
KW_FOR : 'FOR';
KW_FOREIGN : 'FOREIGN';
KW_FRAME_ROW : 'FRAME_ROW';
KW_FREE : 'FREE';
KW_FRIDAY : 'FRIDAY';
KW_FROM : 'FROM';
KW_FULL : 'FULL';
KW_FUNCTION : 'FUNCTION';
KW_FUNCTIONS : 'FUNCTIONS';
KW_FUSION : 'FUSION';
KW_GET : 'GET';
KW_GLOBAL : 'GLOBAL';
KW_GRANT : 'GRANT';
KW_GROUP : 'GROUP';
KW_GROUPING : 'GROUPING';
KW_GROUPS : 'GROUPS';
KW_GROUP_CONCAT : 'GROUP_CONCAT';
KW_HAVING : 'HAVING';
KW_HOLD : 'HOLD';
KW_HOUR : 'HOUR';
KW_IDENTITY : 'IDENTITY';
KW_IF : 'IF';
KW_ILIKE : 'ILIKE';
KW_IMPORT : 'IMPORT';
KW_IN : 'IN';
KW_INCLUDE : 'INCLUDE';
KW_INDICATOR : 'INDICATOR';
KW_INITIAL : 'INITIAL';
KW_INNER : 'INNER';
KW_INOUT : 'INOUT';
KW_INSENSITIVE : 'INSENSITIVE';
KW_INSERT : 'INSERT';
KW_INT : 'INT';
KW_INTEGER : 'INTEGER';
KW_INTERSECT : 'INTERSECT';
KW_INTERSECTION : 'INTERSECTION';
KW_INTERVAL : 'INTERVAL';
KW_INTO : 'INTO';
KW_IS : 'IS';
KW_JOIN : 'JOIN';
KW_JSON : 'JSON';
KW_JSON_ARRAY : 'JSON_ARRAY';
KW_JSON_ARRAYAGG : 'JSON_ARRAYAGG';
KW_JSON_EXECUTION_PLAN : 'JSON_EXECUTION_PLAN';
KW_JSON_EXISTS : 'JSON_EXISTS';
KW_JSON_OBJECT : 'JSON_OBJECT';
KW_JSON_OBJECTAGG : 'JSON_OBJECTAGG';
KW_JSON_QUERY : 'JSON_QUERY';
KW_JSON_VALUE : 'JSON_VALUE';
KW_LAG : 'LAG';
KW_LANGUAGE : 'LANGUAGE';
KW_LARGE : 'LARGE';
KW_LAST_VALUE : 'LAST_VALUE';
KW_LATERAL : 'LATERAL';
KW_LEAD : 'LEAD';
KW_LEADING : 'LEADING';
KW_LEFT : 'LEFT';
KW_LIKE : 'LIKE';
KW_LIKE_REGEX : 'LIKE_REGEX';
KW_LIMIT : 'LIMIT';
KW_LN : 'LN';
KW_LOCAL : 'LOCAL';
KW_LOCALTIME : 'LOCALTIME';
KW_LOCALTIMESTAMP : 'LOCALTIMESTAMP';
KW_LOWER : 'LOWER';
KW_MATCH : 'MATCH';
KW_MATCHES : 'MATCHES';
KW_MATCH_NUMBER : 'MATCH_NUMBER';
KW_MATCH_RECOGNIZE : 'MATCH_RECOGNIZE';
KW_MAX : 'MAX';
KW_MEASURES : 'MEASURES';
KW_MEMBER : 'MEMBER';
KW_MERGE : 'MERGE';
KW_METADATA : 'METADATA';
KW_METHOD : 'METHOD';
KW_MIN : 'MIN';
KW_MINUS : 'MINUS';
KW_MINUTE : 'MINUTE';
KW_MOD : 'MOD';
KW_MODIFIES : 'MODIFIES';
KW_MODIFY : 'MODIFY';
KW_MODULE : 'MODULE';
KW_MODULES : 'MODULES';
KW_MONDAY : 'MONDAY';
KW_MONTH : 'MONTH';
KW_MORE : 'MORE';
KW_MULTISET : 'MULTISET';
KW_NATIONAL : 'NATIONAL';
KW_NATURAL : 'NATURAL';
KW_NCHAR : 'NCHAR';
KW_NCLOB : 'NCLOB';
KW_NEW : 'NEW';
KW_NEXT : 'NEXT';
KW_NO : 'NO';
KW_NONE : 'NONE';
KW_NORMALIZE : 'NORMALIZE';
KW_NOT : 'NOT';
KW_NTH_VALUE : 'NTH_VALUE';
KW_NTILE : 'NTILE';
KW_NULL : 'NULL';
KW_NULLIF : 'NULLIF';
KW_NUMERIC : 'NUMERIC';
KW_OCCURRENCES_REGEX : 'OCCURRENCES_REGEX';
KW_OCTET_LENGTH : 'OCTET_LENGTH';
KW_OF : 'OF';
KW_OFFSET : 'OFFSET';
KW_OLD : 'OLD';
KW_OMIT : 'OMIT';
KW_ON : 'ON';
KW_ONE : 'ONE';
KW_ONLY : 'ONLY';
KW_OPEN : 'OPEN';
KW_OR : 'OR';
KW_ORDER : 'ORDER';
KW_ORDINAL : 'ORDINAL';
KW_OUT : 'OUT';
KW_OUTER : 'OUTER';
KW_OVER : 'OVER';
KW_OVERLAPS : 'OVERLAPS';
KW_OVERLAY : 'OVERLAY';
KW_OVERWRITE : 'OVERWRITE';
KW_OVERWRITING : 'OVERWRITING';
KW_PARAMETER : 'PARAMETER';
KW_PARTITION : 'PARTITION';
KW_PARTITIONED : 'PARTITIONED';
KW_PARTITIONS : 'PARTITIONS';
KW_PATTERN : 'PATTERN';
KW_PER : 'PER';
KW_PERCENT : 'PERCENT';
KW_PERCENTILE_CONT : 'PERCENTILE_CONT';
KW_PERCENTILE_DISC : 'PERCENTILE_DISC';
KW_PERCENT_RANK : 'PERCENT_RANK';
KW_PERIOD : 'PERIOD';
KW_PERMUTE : 'PERMUTE';
KW_PLAN_ADVICE : 'PLAN_ADVICE';
KW_PIVOT : 'PIVOT';
KW_PORTION : 'PORTION';
KW_POSITION : 'POSITION';
KW_POSITION_REGEX : 'POSITION_REGEX';
KW_POWER : 'POWER';
KW_PRECEDES : 'PRECEDES';
KW_PRECISION : 'PRECISION';
KW_PREPARE : 'PREPARE';
KW_PREV : 'PREV';
KW_PRIMARY : 'PRIMARY';
KW_PROCEDURE : 'PROCEDURE';
KW_QUALIFY : 'QUALIFY';
KW_QUARTERS : 'QUARTERS';
KW_RANGE : 'RANGE';
KW_RANK : 'RANK';
KW_RAW : 'RAW';
KW_READS : 'READS';
KW_REAL : 'REAL';
KW_RECURSIVE : 'RECURSIVE';
KW_REF : 'REF';
KW_REFERENCES : 'REFERENCES';
KW_REFERENCING : 'REFERENCING';
KW_REGR_AVGX : 'REGR_AVGX';
KW_REGR_AVGY : 'REGR_AVGY';
KW_REGR_COUNT : 'REGR_COUNT';
KW_REGR_INTERCEPT : 'REGR_INTERCEPT';
KW_REGR_R2 : 'REGR_R2';
KW_REGR_SLOPE : 'REGR_SLOPE';
KW_REGR_SXX : 'REGR_SXX';
KW_REGR_SXY : 'REGR_SXY';
KW_REGR_SYY : 'REGR_SYY';
KW_RELEASE : 'RELEASE';
KW_RENAME : 'RENAME';
KW_RESET : 'RESET';
KW_RESULT : 'RESULT';
KW_RETURN : 'RETURN';
KW_RETURNS : 'RETURNS';
KW_REVOKE : 'REVOKE';
KW_RIGHT : 'RIGHT';
KW_RLIKE : 'RLIKE';
KW_ROLLBACK : 'ROLLBACK';
KW_ROLLUP : 'ROLLUP';
KW_ROW : 'ROW';
KW_ROWS : 'ROWS';
KW_ROW_NUMBER : 'ROW_NUMBER';
KW_RUNNING : 'RUNNING';
KW_SAFE_CAST : 'SAFE_CAST';
KW_SAFE_OFFSET : 'SAFE_OFFSET';
KW_SAFE_ORDINAL : 'SAFE_ORDINAL';
KW_SATURDAY : 'SATURDAY';
KW_SAVEPOINT : 'SAVEPOINT';
KW_SCALA : 'SCALA';
KW_SCOPE : 'SCOPE';
KW_SCROLL : 'SCROLL';
KW_SEARCH : 'SEARCH';
KW_SECOND : 'SECOND';
KW_SEEK : 'SEEK';
KW_SELECT : 'SELECT';
KW_SENSITIVE : 'SENSITIVE';
KW_SEPARATOR : 'SEPARATOR';
KW_SESSION_USER : 'SESSION_USER';
KW_SET : 'SET';
KW_SHOW : 'SHOW';
KW_SIMILAR : 'SIMILAR';
KW_SKIP : 'SKIP';
KW_SMALLINT : 'SMALLINT';
KW_SOME : 'SOME';
KW_SPECIFIC : 'SPECIFIC';
KW_SPECIFICTYPE : 'SPECIFICTYPE';
KW_SQL : 'SQL';
KW_SQLEXCEPTION : 'SQLEXCEPTION';
KW_SQLSTATE : 'SQLSTATE';
KW_SQLWARNING : 'SQLWARNING';
KW_SQRT : 'SQRT';
KW_START : 'START';
KW_STATEMENT : 'STATEMENT';
KW_STATIC : 'STATIC';
KW_STATISTICS : 'STATISTICS';
KW_STDDEV_POP : 'STDDEV_POP';
KW_STDDEV_SAMP : 'STDDEV_SAMP';
KW_STREAM : 'STREAM';
KW_STRING : 'STRING';
KW_STRING_AGG : 'STRING_AGG';
KW_SUBMULTISET : 'SUBMULTISET';
KW_SUBSET : 'SUBSET';
KW_SUBSTRING : 'SUBSTRING';
KW_SUBSTRING_REGEX : 'SUBSTRING_REGEX';
KW_SUCCEEDS : 'SUCCEEDS';
KW_SUM : 'SUM';
KW_SUNDAY : 'SUNDAY';
KW_SYMMETRIC : 'SYMMETRIC';
KW_SYSTEM : 'SYSTEM';
KW_SYSTEM_TIME : 'SYSTEM_TIME';
KW_SYSTEM_USER : 'SYSTEM_USER';
KW_TABLE : 'TABLE';
KW_TABLES : 'TABLES';
KW_TABLESAMPLE : 'TABLESAMPLE';
KW_THEN : 'THEN';
KW_THURSDAY : 'THURSDAY';
KW_TIME : 'TIME';
KW_TIMESTAMP : 'TIMESTAMP';
KW_TIMESTAMP_DIFF : 'TIMESTAMP_DIFF';
KW_TIMESTAMP_LTZ : 'TIMESTAMP_LTZ';
KW_TIMESTAMP_TRUNC : 'TIMESTAMP_TRUNC';
KW_TIMEZONE_HOUR : 'TIMEZONE_HOUR';
KW_TIMEZONE_MINUTE : 'TIMEZONE_MINUTE';
KW_TIME_DIFF : 'TIME_DIFF';
KW_TIME_TRUNC : 'TIME_TRUNC';
KW_TINYINT : 'TINYINT';
KW_TO : 'TO';
KW_TRAILING : 'TRAILING';
KW_TRANSLATE : 'TRANSLATE';
KW_TRANSLATE_REGEX : 'TRANSLATE_REGEX';
KW_TRANSLATION : 'TRANSLATION';
KW_TREAT : 'TREAT';
KW_TRIGGER : 'TRIGGER';
KW_TRIM : 'TRIM';
KW_TRIM_ARRAY : 'TRIM_ARRAY';
KW_TRUE : 'TRUE';
KW_TRUNCATE : 'TRUNCATE';
KW_TRY_CAST : 'TRY_CAST';
KW_TUESDAY : 'TUESDAY';
KW_UESCAPE : 'UESCAPE';
KW_UNION : 'UNION';
KW_UNIQUE : 'UNIQUE';
KW_UNKNOWN : 'UNKNOWN';
KW_UNNEST : 'UNNEST';
KW_UNPIVOT : 'UNPIVOT';
KW_UPDATE : 'UPDATE';
KW_UPPER : 'UPPER';
KW_UPSERT : 'UPSERT';
KW_USE : 'USE';
KW_USER : 'USER';
KW_USING : 'USING';
KW_VALUE : 'VALUE';
KW_VALUES : 'VALUES';
KW_VALUE_OF : 'VALUE_OF';
KW_VARBINARY : 'VARBINARY';
KW_VARCHAR : 'VARCHAR';
KW_VARYING : 'VARYING';
KW_VAR_POP : 'VAR_POP';
KW_VAR_SAMP : 'VAR_SAMP';
KW_VERSIONING : 'VERSIONING';
KW_VIEWS : 'VIEWS';
KW_VIRTUAL : 'VIRTUAL';
KW_WATERMARK : 'WATERMARK';
KW_WATERMARKS : 'WATERMARKS';
KW_WEDNESDAY : 'WEDNESDAY';
KW_WEEKS : 'WEEKS';
KW_WHEN : 'WHEN';
KW_WHENEVER : 'WHENEVER';
KW_WHERE : 'WHERE';
KW_WIDTH_BUCKET : 'WIDTH_BUCKET';
KW_WINDOW : 'WINDOW';
KW_WITH : 'WITH';
KW_WITHIN : 'WITHIN';
KW_WITHOUT : 'WITHOUT';
KW_YEAR : 'YEAR';
/**
* Non-Reserved Keywords
* Keywords that are used in the syntax rules but do not exist in the above keyword list section.
* Please keep the keyword in alphabetical order if new keyword is added.
* New non-reserved keywords should also be added to the nonReservedKeywords rule in FlinkSqlParser.g4 file.
*/
KW_ADD : 'ADD';
KW_AFTER : 'AFTER';
KW_ASC : 'ASC';
KW_CASCADE : 'CASCADE';
KW_CATALOG : 'CATALOG';
KW_CENTURY : 'CENTURY';
KW_CONFIG : 'CONFIG';
KW_CONSTRAINTS : 'CONSTRAINTS';
KW_CUMULATE : 'CUMULATE';
KW_DATA : 'DATA';
KW_DATABASE : 'DATABASE';
KW_DAYS : 'DAYS';
KW_DECADE : 'DECADE';
KW_DESC : 'DESC';
KW_DESCRIPTOR : 'DESCRIPTOR';
KW_DIV : 'DIV';
KW_ENGINE : 'ENGINE';
KW_EPOCH : 'EPOCH';
KW_EXCLUDING : 'EXCLUDING';
KW_FILE : 'FILE';
KW_FIRST : 'FIRST';
KW_GENERATED : 'GENERATED';
KW_HOP : 'HOP';
KW_HOURS : 'HOURS';
KW_IGNORE : 'IGNORE';
KW_INCLUDING : 'INCLUDING';
KW_JAR : 'JAR';
KW_JARS : 'JARS';
KW_JAVA : 'JAVA';
KW_KEY : 'KEY';
KW_LAST : 'LAST';
KW_LOAD : 'LOAD';
KW_MAP : 'MAP';
KW_MICROSECOND : 'MICROSECOND';
KW_MILLENNIUM : 'MILLENNIUM';
KW_MILLISECOND : 'MILLISECOND';
KW_MINUTES : 'MINUTES';
KW_MONTHS : 'MONTHS';
KW_NANOSECOND : 'NANOSECOND';
KW_NULLS : 'NULLS';
KW_OPTIONS : 'OPTIONS';
KW_PAST : 'PAST';
KW_PLAN : 'PLAN';
KW_PRECEDING : 'PRECEDING';
KW_PYTHON : 'PYTHON';
KW_PYTHON_ARCHIVES : 'PYTHON_ARCHIVES';
KW_PYTHON_DEPENDENCIES : 'PYTHON_DEPENDENCIES';
KW_PYTHON_FILES : 'PYTHON_FILES';
KW_PYTHON_JAR : 'PYTHON_JAR';
KW_PYTHON_PARAMETER : 'PYTHON_PARAMETER';
KW_PYTHON_REQUIREMENTS : 'PYTHON_REQUIREMENTS';
KW_QUARTER : 'QUARTER';
KW_REMOVE : 'REMOVE';
KW_RESTRICT : 'RESTRICT';
KW_SECONDS : 'SECONDS';
KW_SESSION : 'SESSION';
KW_SETS : 'SETS';
KW_SIZE : 'SIZE';
KW_SLIDE : 'SLIDE';
KW_STEP : 'STEP';
KW_TEMPORARY : 'TEMPORARY';
KW_TIMECOL : 'TIMECOL';
KW_TUMBLE : 'TUMBLE';
KW_UNLOAD : 'UNLOAD';
KW_VIEW : 'VIEW';
KW_WEEK : 'WEEK';
KW_YEARS : 'YEARS';
KW_ZONE : 'ZONE';
// Operators. Comparation
EQUAL_SYMBOL : '=';
GREATER_SYMBOL : '>';
LESS_SYMBOL : '<';
EXCLAMATION_SYMBOL : '!';
// Operators. Bit
BIT_NOT_OP : '~';
BIT_OR_OP : '|';
BIT_AND_OP : '&';
BIT_XOR_OP : '^';
// Constructors symbols
DOT : '.';
LS_BRACKET : '[';
RS_BRACKET : ']';
LR_BRACKET : '(';
RR_BRACKET : ')';
LB_BRACKET : '{';
RB_BRACKET : '}';
COMMA : ',';
SEMICOLON : ';';
AT_SIGN : '@';
SINGLE_QUOTE_SYMB : '\'';
DOUBLE_QUOTE_SYMB : '"';
REVERSE_QUOTE_SYMB : '`';
COLON_SYMB : ':';
ASTERISK_SIGN : '*';
UNDERLINE_SIGN : '_';
HYPHEN_SIGN : '-';
ADD_SIGN : '+';
PERCENT_SIGN : '%';
DOUBLE_VERTICAL_SIGN : '||';
DOUBLE_HYPHEN_SIGN : '--';
SLASH_SIGN : '/';
QUESTION_MARK_SIGN : '?';
DOUBLE_RIGHT_ARROW : '=>';
STRING_LITERAL : DQUOTA_STRING | SQUOTA_STRING | BQUOTA_STRING;
DIG_LITERAL : DEC_DIGIT+;
REAL_LITERAL: (DEC_DIGIT+)? '.' DEC_DIGIT+
| DEC_DIGIT+ '.' EXPONENT_NUM_PART
| (DEC_DIGIT+)? '.' (DEC_DIGIT+ EXPONENT_NUM_PART)
| DEC_DIGIT+ EXPONENT_NUM_PART;
BIT_STRING : BIT_STRING_L;
ID_LITERAL : ID_LITERAL_FRAG;
fragment JAR_FILE_PARTTARN : '`' ( '\\' . | '``' | ~('`' | '\\'))* '`';
fragment EXPONENT_NUM_PART : 'E' [-+]? DEC_DIGIT+;
fragment ID_LITERAL_FRAG : [A-Z_0-9]*? [A-Z_]+? [A-Z_0-9]*;
fragment DEC_DIGIT : [0-9];
fragment DEC_LETTER : [A-Z];
fragment DQUOTA_STRING : '"' ( '\\' . | '""' | ~('"' | '\\'))* '"';
fragment SQUOTA_STRING : '\'' ('\\' . | '\'\'' | ~('\'' | '\\'))* '\'';
fragment BIT_STRING_L : 'B' '\'' [01]+ '\'';
fragment BQUOTA_STRING : '`' ( '\\' . | '``' | ~('`' | '\\'))* '`';
================================================
FILE: superior-flink-parser/src/main/antlr4/io/github/melin/superior/parser/flink/antlr4/FlinkSqlParser.g4
================================================
parser grammar FlinkSqlParser;
options { tokenVocab=FlinkSqlLexer; }
sqlStatements
: singleStatement* EOF
;
singleStatement
: sqlStatement SEMICOLON?
| emptyStatement
;
sqlStatement
: ddlStatement
| dmlStatement
| describeStatement
| explainStatement
| useStatement
| showStatement
| loadStatement
| unloadStatement
| setStatement
| resetStatement
| jarStatement
| dtAddStatement
;
emptyStatement
: SEMICOLON
;
ddlStatement
: createTable
| createDatabase
| createView
| createFunction
| createCatalog
| alterTable
| alterView
| alterDatabase
| alterFunction
| dropCatalog
| dropTable
| dropDatabase
| dropView
| dropFunction
;
dmlStatement
: queryStatement
| insertStatement
;
// some statement
describeStatement
: (KW_DESCRIBE | KW_DESC) tablePath
;
explainStatement
: KW_EXPLAIN (explainDetails | KW_PLAN KW_FOR)? (
dmlStatement
| insertSimpleStatement
| insertMulStatement
)
;
explainDetails
: explainDetail (COMMA explainDetail)*
;
explainDetail
: KW_CHANGELOG_MODE
| KW_PLAN_ADVICE
| KW_JSON_EXECUTION_PLAN
| KW_ESTIMATED_COST
;
useStatement
: KW_USE KW_CATALOG catalogPath
| KW_USE databasePath
| useModuleStatement
;
useModuleStatement
: KW_USE KW_MODULES uid (COMMA uid)*
;
showStatement
: KW_SHOW (KW_CATALOGS | KW_DATABASES | KW_VIEWS | KW_JARS)
| KW_SHOW KW_CURRENT (KW_CATALOG | KW_DATABASE)
| KW_SHOW KW_TABLES (( KW_FROM | KW_IN) databasePath)? likePredicate?
| KW_SHOW KW_COLUMNS ( KW_FROM | KW_IN) (viewPath | tablePath) likePredicate?
| KW_SHOW KW_CREATE (KW_TABLE tablePath | KW_VIEW viewPath)
| KW_SHOW KW_USER? KW_FUNCTIONS
| KW_SHOW KW_FULL? KW_MODULES
;
loadStatement
: KW_LOAD KW_MODULE uid (KW_WITH tablePropertyList)?
;
unloadStatement
: KW_UNLOAD KW_MODULE uid
;
setStatement
: KW_SET (tableProperty)?
;
resetStatement
: KW_RESET tablePropertyKey?
;
jarStatement
: (KW_ADD | KW_REMOVE) KW_JAR jarFileName
;
// 数栈平台自研的添加文件语法
dtAddStatement
: KW_ADD KW_JAR KW_WITH dtFilePath (KW_AS uid)?
| KW_ADD KW_FILE KW_WITH dtFilePath (KW_AS uid)? (KW_RENAME uid)?
| KW_ADD (
KW_PYTHON_FILES
| KW_PYTHON_REQUIREMENTS
| KW_PYTHON_DEPENDENCIES
| KW_PYTHON_JAR
| KW_PYTHON_ARCHIVES
) KW_WITH dtFilePath KW_RENAME uid
| KW_ADD KW_PYTHON_PARAMETER dtFilePath
| KW_ADD KW_ENGINE KW_FILE KW_WITH dtFilePath KW_RENAME uid KW_KEY uid
| KW_ADD KW_CONFIG KW_FILE KW_WITH dtFilePath KW_FOR uid KW_AS uid
;
dtFilePath
: (SLASH_SIGN? uid)+
;
// Create statements
createTable
: (simpleCreateTable | createTableAsSelect)
;
simpleCreateTable
: KW_CREATE KW_TEMPORARY? KW_TABLE ifNotExists? tablePathCreate LR_BRACKET columnOptionDefinition (
COMMA columnOptionDefinition
)* (COMMA watermarkDefinition)? (COMMA tableConstraint)? (COMMA selfDefinitionClause)? RR_BRACKET (
KW_COMMENT comment=STRING_LITERAL
)? partitionDefinition? withOption likeDefinition?
;
/*
* 详见 https://nightlies.apache.org/flink/flink-docs-release-1.16/docs/dev/table/sql/create/#as-select_statement
* CTAS 不支持指定显示指定列,不支持创建分区表,临时表
*/
createTableAsSelect
: KW_CREATE KW_TABLE ifNotExists? tablePathCreate withOption (KW_AS queryStatement)?
;
columnOptionDefinition
: physicalColumnDefinition
| metadataColumnDefinition
| computedColumnDefinition
;
physicalColumnDefinition
: columnNameCreate columnType columnConstraint? (KW_COMMENT comment=STRING_LITERAL)?
;
columnNameCreate
: uid
| expression
;
columnName
: uid
;
columnNamePath
: uid
;
columnNameList
: LR_BRACKET columnName (COMMA columnName)* RR_BRACKET
;
columnType
: colType=(KW_DATE | KW_BOOLEAN | KW_NULL)
| colType=(
KW_CHAR
| KW_VARCHAR
| KW_STRING
| KW_BINARY
| KW_VARBINARY
| KW_BYTES
| KW_TINYINT
| KW_SMALLINT
| KW_INT
| KW_INTEGER
| KW_BIGINT
| KW_TIME
| KW_TIMESTAMP_LTZ
| KW_DATETIME
) lengthOneDimension?
| colType=KW_TIMESTAMP lengthOneDimension? ((KW_WITHOUT | KW_WITH) KW_LOCAL? KW_TIME KW_ZONE)?
| colType=(KW_DECIMAL | KW_DEC | KW_NUMERIC | KW_FLOAT | KW_DOUBLE) lengthTwoOptionalDimension?
| colType=(KW_ARRAY | KW_MULTISET) lengthOneTypeDimension?
| colType=KW_MAP mapTypeDimension?
| colType=KW_ROW rowTypeDimension?
| colType=KW_RAW lengthTwoStringDimension?
;
lengthOneDimension
: LR_BRACKET decimalLiteral RR_BRACKET
;
lengthTwoOptionalDimension
: LR_BRACKET decimalLiteral (COMMA decimalLiteral)? RR_BRACKET
;
lengthTwoStringDimension
: LR_BRACKET stringLiteral (COMMA stringLiteral)? RR_BRACKET
;
lengthOneTypeDimension
: LESS_SYMBOL columnType GREATER_SYMBOL
;
mapTypeDimension
: LESS_SYMBOL columnType (COMMA columnType) GREATER_SYMBOL
;
rowTypeDimension
: LESS_SYMBOL columnName columnType (COMMA columnName columnType)* GREATER_SYMBOL
| LR_BRACKET columnName columnType (COMMA columnName columnType)* RR_BRACKET
;
columnConstraint
: (KW_CONSTRAINT constraintName)? KW_PRIMARY KW_KEY (KW_NOT KW_ENFORCED)?
| KW_NOT? KW_NULL
;
metadataColumnDefinition
: columnNameCreate columnType KW_METADATA (KW_FROM metadataKey)? KW_VIRTUAL?
;
metadataKey
: STRING_LITERAL
;
computedColumnDefinition
: columnNameCreate KW_AS computedColumnExpression (KW_COMMENT comment=STRING_LITERAL)?
;
// 计算表达式
computedColumnExpression
: expression
;
watermarkDefinition
: KW_WATERMARK KW_FOR columnName KW_AS expression
;
tableConstraint
: (KW_CONSTRAINT constraintName)? KW_PRIMARY KW_KEY columnNameList KW_NOT KW_ENFORCED
;
constraintName
: identifier
;
selfDefinitionClause // 数栈自定义语句 ‘PERIOD KW_FOR SYSTEM_TIME’
: KW_PERIOD KW_FOR KW_SYSTEM_TIME
;
partitionDefinition
: KW_PARTITIONED KW_BY transformList
;
transformList
: LR_BRACKET transform (COMMA transform)* RR_BRACKET
;
transform
: columnName # identityTransform
| LR_BRACKET transformArgument (COMMA transformArgument)* RR_BRACKET # applyTransform
;
transformArgument
: qualifiedName
| constant
;
likeDefinition
: KW_LIKE tablePath (LR_BRACKET likeOption* RR_BRACKET)?
;
likeOption
: ((KW_INCLUDING | KW_EXCLUDING) (KW_ALL | KW_CONSTRAINTS | KW_PARTITIONS))
| ((KW_INCLUDING | KW_EXCLUDING | KW_OVERWRITING) (KW_GENERATED | KW_OPTIONS | KW_WATERMARKS))
;
createCatalog
: KW_CREATE KW_CATALOG catalogPathCreate withOption
;
createDatabase
: KW_CREATE KW_DATABASE ifNotExists? databasePathCreate (KW_COMMENT comment=STRING_LITERAL)? withOption
;
createView
: KW_CREATE KW_TEMPORARY? KW_VIEW ifNotExists? viewPathCreate columnNameList? (
KW_COMMENT comment=STRING_LITERAL
)? KW_AS queryStatement
;
createFunction
: KW_CREATE (KW_TEMPORARY | KW_TEMPORARY KW_SYSTEM)? KW_FUNCTION ifNotExists? functionNameCreate KW_AS identifier (
KW_LANGUAGE (KW_JAVA | KW_SCALA | KW_PYTHON)
)? usingClause?
;
usingClause
: KW_USING KW_JAR jarFileName (COMMA KW_JAR jarFileName)*
;
jarFileName
: STRING_LITERAL
;
// Alter statements
// Just for simple alter table statements,
// it only includes rename, set key, add constraint, drop constraint, add unique
alterTable
: KW_ALTER KW_TABLE ifExists? tablePath (
renameDefinition
| setKeyValueDefinition
| addConstraint
| dropConstraint
| addUnique
)
;
renameDefinition
: KW_RENAME uid? KW_TO uid
;
setKeyValueDefinition
: KW_SET tablePropertyList
;
addConstraint
: KW_ADD KW_CONSTRAINT constraintName KW_PRIMARY KW_KEY columnNameList notForced?
;
dropConstraint
: KW_DROP KW_CONSTRAINT constraintName
;
addUnique
: KW_ADD KW_UNIQUE columnNameList
;
notForced
: KW_NOT KW_ENFORCED
;
alterView
: KW_ALTER KW_VIEW viewPath (renameDefinition | KW_AS queryStatement)
;
alterDatabase
: KW_ALTER KW_DATABASE databasePath setKeyValueDefinition
;
alterFunction
: KW_ALTER (KW_TEMPORARY | KW_TEMPORARY KW_SYSTEM)? KW_FUNCTION ifExists? functionName KW_AS identifier (
KW_LANGUAGE (KW_JAVA | KW_SCALA | KW_PYTHON)
)? // TODO
;
// Drop statements
dropCatalog
: KW_DROP KW_CATALOG ifExists? catalogPath
;
dropTable
: KW_DROP KW_TEMPORARY? KW_TABLE ifExists? tablePath
;
dropDatabase
: KW_DROP KW_DATABASE ifExists? databasePath dropType=(KW_RESTRICT | KW_CASCADE)?
;
dropView
: KW_DROP KW_TEMPORARY? KW_VIEW ifExists? viewPath
;
dropFunction
: KW_DROP (KW_TEMPORARY | KW_TEMPORARY KW_SYSTEM)? KW_FUNCTION ifExists? functionName
;
// Insert statements
insertStatement
: (KW_EXECUTE? insertSimpleStatement)
| insertMulStatementCompatibility
| (KW_EXECUTE insertMulStatement)
;
insertSimpleStatement
: KW_INSERT (KW_INTO | KW_OVERWRITE) tablePath (
insertPartitionDefinition? columnNameList? queryStatement
| valuesDefinition
)
;
insertPartitionDefinition
: KW_PARTITION tablePropertyList
;
valuesDefinition
: KW_VALUES valuesRowDefinition (COMMA valuesRowDefinition)*
;
valuesRowDefinition
: LR_BRACKET valueDefinition (COMMA valueDefinition)* RR_BRACKET
;
valueDefinition
: constant
| functionCallExpression
;
insertMulStatementCompatibility
: KW_BEGIN KW_STATEMENT KW_SET SEMICOLON (insertSimpleStatement SEMICOLON)+ KW_END
;
insertMulStatement
: KW_STATEMENT KW_SET KW_BEGIN (insertSimpleStatement SEMICOLON)+ KW_END
;
// Select statements
queryStatement
: valuesClause
| withClause queryStatement
| LR_BRACKET queryStatement RR_BRACKET
| left=queryStatement operator=(KW_INTERSECT | KW_UNION | KW_EXCEPT) KW_ALL? right=queryStatement orderByClause? limitClause?
| selectClause orderByClause? limitClause?
| selectStatement orderByClause? limitClause?
;
valuesClause
: KW_VALUES expression (COMMA expression)*
;
withClause
: KW_WITH withItem (COMMA withItem)*
;
withItem
: withItemName (LR_BRACKET columnName (COMMA columnName)* RR_BRACKET)? KW_AS LR_BRACKET queryStatement RR_BRACKET
;
withItemName
: identifier
;
selectStatement
: selectClause fromClause? whereClause? groupByClause? havingClause? windowClause?
| selectClause fromClause matchRecognizeClause
;
selectClause
: KW_SELECT setQuantifier? (
ASTERISK_SIGN
| projectItemDefinition (COMMA projectItemDefinition)*
)
;
projectItemDefinition
: overWindowItem
| expression (KW_AS? columnName)?
| columnName (KW_AS? expression)?
;
overWindowItem
: primaryExpression KW_OVER windowSpec KW_AS identifier
| primaryExpression KW_OVER errorCapturingIdentifier KW_AS identifier
;
fromClause
: KW_FROM tableExpression
;
tableExpression
: tableReference (COMMA tableReference)*
| tableExpression KW_NATURAL? (KW_LEFT | KW_RIGHT | KW_FULL | KW_INNER)? KW_OUTER? KW_JOIN tableExpression joinCondition?
| tableExpression KW_CROSS KW_JOIN tableExpression
| inlineDataValueClause
| windowTVFClause
;
tableReference
: tablePrimary tableAlias?
;
tablePrimary
: KW_TABLE? tablePath systemTimePeriod?
| viewPath systemTimePeriod?
| KW_LATERAL KW_TABLE LR_BRACKET functionCallExpression RR_BRACKET
| KW_LATERAL? LR_BRACKET queryStatement RR_BRACKET
| KW_UNNEST LR_BRACKET expression RR_BRACKET
;
systemTimePeriod
: KW_FOR KW_SYSTEM_TIME KW_AS KW_OF dateTimeExpression
;
dateTimeExpression
: expression
;
inlineDataValueClause
: LR_BRACKET valuesDefinition RR_BRACKET tableAlias
;
windowTVFClause
: KW_TABLE LR_BRACKET windowTVFExpression RR_BRACKET
;
windowTVFExpression
: windowTVFName LR_BRACKET windowTVFParam (COMMA windowTVFParam)* RR_BRACKET
;
windowTVFName
: KW_TUMBLE
| KW_HOP
| KW_CUMULATE
;
windowTVFParam
: KW_TABLE timeAttrColumn
| columnDescriptor
| timeIntervalExpression
| KW_DATA DOUBLE_RIGHT_ARROW KW_TABLE timeAttrColumn
| KW_TIMECOL DOUBLE_RIGHT_ARROW columnDescriptor
| timeIntervalParamName DOUBLE_RIGHT_ARROW timeIntervalExpression
;
timeIntervalParamName
: KW_DATA
| KW_TIMECOL
| KW_SIZE
| KW_OFFSET
| KW_STEP
| KW_SLIDE
;
columnDescriptor
: KW_DESCRIPTOR LR_BRACKET columnName RR_BRACKET
;
joinCondition
: KW_ON booleanExpression
| KW_USING columnNameList
;
whereClause
: KW_WHERE booleanExpression
;
groupByClause
: KW_GROUP KW_BY groupItemDefinition (COMMA groupItemDefinition)*
;
groupItemDefinition
: columnName
| groupWindowFunction
| LR_BRACKET RR_BRACKET
| LR_BRACKET expression (COMMA expression)* RR_BRACKET
| groupingSetsNotationName LR_BRACKET expression (COMMA expression)* RR_BRACKET
| groupingSets LR_BRACKET groupItemDefinition (COMMA groupItemDefinition)* RR_BRACKET
| expression
;
groupingSets
: KW_GROUPING KW_SETS
;
groupingSetsNotationName
: KW_CUBE
| KW_ROLLUP
;
groupWindowFunction
: groupWindowFunctionName LR_BRACKET timeAttrColumn COMMA timeIntervalExpression RR_BRACKET
;
groupWindowFunctionName
: KW_TUMBLE
| KW_HOP
| KW_SESSION
;
timeAttrColumn
: uid
;
havingClause
: KW_HAVING booleanExpression
;
windowClause
: KW_WINDOW namedWindow (COMMA namedWindow)*
;
namedWindow
: name=errorCapturingIdentifier KW_AS windowSpec
;
windowSpec
: name=errorCapturingIdentifier? LR_BRACKET partitionByClause? orderByClause? windowFrame? RR_BRACKET
;
matchRecognizeClause
: KW_MATCH_RECOGNIZE LR_BRACKET partitionByClause? orderByClause? measuresClause? outputMode? afterMatchStrategy? patternDefinition?
patternVariablesDefinition RR_BRACKET (KW_AS? identifier)?
;
orderByClause
: KW_ORDER KW_BY orderItemDefinition (COMMA orderItemDefinition)*
;
orderItemDefinition
: columnName ordering=(KW_ASC | KW_DESC)? (KW_NULLS nullOrder=(KW_LAST | KW_FIRST))?
;
limitClause
: KW_LIMIT (KW_ALL | limit=expression)
;
partitionByClause
: KW_PARTITION KW_BY (columnName | primaryExpression) (COMMA (columnName | primaryExpression))*
;
quantifiers
: (ASTERISK_SIGN)
| (ADD_SIGN)
| (QUESTION_MARK_SIGN)
| (LB_BRACKET DIG_LITERAL COMMA DIG_LITERAL RB_BRACKET)
| (LB_BRACKET DIG_LITERAL COMMA RB_BRACKET)
| (LB_BRACKET COMMA DIG_LITERAL RB_BRACKET)
;
measuresClause
: KW_MEASURES projectItemDefinition (COMMA projectItemDefinition)*
;
patternDefinition
: KW_PATTERN LR_BRACKET patternVariable+ RR_BRACKET withinClause?
;
patternVariable
: unquotedIdentifier quantifiers?
;
outputMode
: KW_ALL KW_ROWS KW_PER KW_MATCH
| KW_ONE KW_ROW KW_PER KW_MATCH
;
afterMatchStrategy
: KW_AFTER KW_MATCH KW_SKIP KW_PAST KW_LAST KW_ROW
| KW_AFTER KW_MATCH KW_SKIP KW_TO KW_NEXT KW_ROW
| KW_AFTER KW_MATCH KW_SKIP KW_TO KW_LAST unquotedIdentifier
| KW_AFTER KW_MATCH KW_SKIP KW_TO KW_FIRST unquotedIdentifier
;
patternVariablesDefinition
: KW_DEFINE projectItemDefinition (COMMA projectItemDefinition)*
;
windowFrame
: KW_RANGE KW_BETWEEN timeIntervalExpression frameBound
| KW_ROWS KW_BETWEEN DIG_LITERAL frameBound
;
frameBound
: KW_PRECEDING KW_AND KW_CURRENT KW_ROW
;
withinClause
: KW_WITHIN timeIntervalExpression
;
// expression
expression
: booleanExpression
;
booleanExpression
: KW_NOT booleanExpression # logicalNot
| KW_EXISTS LR_BRACKET queryStatement RR_BRACKET # exists
| valueExpression predicate? # predicated
| left=booleanExpression operator=KW_AND right=booleanExpression # logicalBinary
| left=booleanExpression operator=KW_OR right=booleanExpression # logicalBinary
| booleanExpression KW_IS KW_NOT? kind=(KW_TRUE | KW_FALSE | KW_UNKNOWN | KW_NULL) # logicalNested
;
predicate
: KW_NOT? kind=KW_BETWEEN (KW_ASYMMETRIC | KW_SYMMETRIC)? lower=valueExpression KW_AND upper=valueExpression
| KW_NOT? kind=KW_IN LR_BRACKET expression (COMMA expression)* RR_BRACKET
| KW_NOT? kind=KW_IN LR_BRACKET queryStatement RR_BRACKET
| kind=KW_EXISTS LR_BRACKET queryStatement RR_BRACKET
| KW_NOT? kind=KW_RLIKE pattern=valueExpression
| likePredicate
| KW_IS KW_NOT? kind=(KW_TRUE | KW_FALSE | KW_UNKNOWN | KW_NULL)
| KW_IS KW_NOT? kind=KW_DISTINCT KW_FROM right=valueExpression
| KW_NOT? kind=KW_SIMILAR KW_TO right=valueExpression (KW_ESCAPE stringLiteral)?
| KW_IS KW_JSON (KW_VALUE | KW_ARRAY | identifier)?
;
jsonFunctionBranch
: KW_NULL
| KW_EMPTY KW_ARRAY
| KW_EMPTY uid
| KW_TRUE
| KW_FALSE
| KW_UNKNOWN
;
likePredicate
: KW_NOT? kind=KW_LIKE quantifier=(KW_ANY | KW_ALL) (
LR_BRACKET RR_BRACKET
| LR_BRACKET expression (COMMA expression)* RR_BRACKET
)
| KW_NOT? kind=KW_LIKE pattern=valueExpression (KW_ESCAPE stringLiteral)?
;
valueExpression
: primaryExpression # valueExpressionDefault
| operator=(HYPHEN_SIGN | ADD_SIGN | BIT_NOT_OP) valueExpression # arithmeticUnary
| left=valueExpression operator=(ASTERISK_SIGN | SLASH_SIGN | PERCENT_SIGN | KW_DIV) right=valueExpression # arithmeticBinary
| left=valueExpression operator=(ADD_SIGN | HYPHEN_SIGN | DOUBLE_VERTICAL_SIGN) right=valueExpression # arithmeticBinary
| left=valueExpression operator=BIT_AND_OP right=valueExpression # arithmeticBinary
| left=valueExpression operator=BIT_XOR_OP right=valueExpression # arithmeticBinary
| left=valueExpression operator=BIT_OR_OP right=valueExpression # arithmeticBinary
| left=valueExpression comparisonOperator right=valueExpression # comparison
;
functionCallExpression
: reservedKeywordsNoParamsUsedAsFuncName
| functionNameAndParams
| functionNameWithParams LR_BRACKET (setQuantifier? functionParam (COMMA functionParam)*)? RR_BRACKET
;
primaryExpression
: KW_CASE whenClause+ (KW_ELSE elseExpression=expression)? KW_END # searchedCase
| KW_CASE value=expression whenClause+ (KW_ELSE elseExpression=expression)? KW_END # simpleCase
| KW_CAST LR_BRACKET expression KW_AS columnType RR_BRACKET # cast
// | STRUCT LR_BRACKET (argument+=namedExpression (COMMA argument+=namedExpression)*)? RR_BRACKET #struct
| KW_FIRST LR_BRACKET expression (KW_IGNORE KW_NULLS)? RR_BRACKET # first
| KW_LAST LR_BRACKET expression (KW_IGNORE KW_NULLS)? RR_BRACKET # last
| KW_POSITION LR_BRACKET substr=valueExpression KW_IN str=valueExpression RR_BRACKET # position
| constant # constantDefault
| ASTERISK_SIGN # star
| uid DOT ASTERISK_SIGN # star
// | LR_BRACKET namedExpression (COMMA namedExpression)+ RR_BRACKET #rowConstructor
| LR_BRACKET queryStatement RR_BRACKET # subqueryExpression
| functionCallExpression # functionCall
// | identifier '->' expression #lambda
// | '(' identifier (',' identifier)+ ')' '->' expression #lambda
| value=primaryExpression LS_BRACKET index=valueExpression RS_BRACKET # subscript
| columnNamePath # columnReference
| dereferenceDefinition # dereference
| LR_BRACKET expression RR_BRACKET # parenthesizedExpression
// | EXTRACT LR_BRACKET field=identifier KW_FROM source=valueExpression RR_BRACKET #extract
// | (SUBSTR | SUBSTRING) LR_BRACKET str=valueExpression (KW_FROM | COMMA) pos=valueExpression
// ((KW_FOR | COMMA) len=valueExpression)? RR_BRACKET #substring
// | TRIM LR_BRACKET trimOption=(BOTH | LEADING | TRAILING)? (trimStr=valueExpression)?
// KW_FROM srcStr=valueExpression RR_BRACKET #trim
// | OVERLAY LR_BRACKET input=valueExpression PLACING replace=valueExpression
// KW_FROM position=valueExpression (KW_FOR length=valueExpression)? RR_BRACKET #overlay
;
functionNameCreate
: uid
;
functionName
: reservedKeywordsUsedAsFuncName
| reservedKeywordsNoParamsUsedAsFuncName
| reservedKeywordsFollowParamsUsedAsFuncName
| uid
;
/**
* Built-in function name that is following with params directly without parentheses
* 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
*/
functionNameAndParams
: reservedKeywordsFollowParamsUsedAsFuncName STRING_LITERAL
| timeIntervalExpression
;
/**
* Function name that is need to follow with parentheses and params
*/
functionNameWithParams
: reservedKeywordsUsedAsFuncName
| uid
;
functionParam
: reservedKeywordsUsedAsFuncParam
| timeIntervalUnit
| timePointUnit
| expression
| jsonValueParams
| jsonQueryParams
| jsonObjectParams
| jsonArrayParams
;
jsonValueParams
: columnNamePath (uid columnType)? (
(uid | KW_NULL | KW_DEFAULT valueExpression) KW_ON KW_EMPTY
)? ((uid | KW_NULL | KW_DEFAULT valueExpression) KW_ON uid)?
;
jsonQueryParams
: columnNamePath ((KW_WITHOUT | KW_WITH uid?) KW_ARRAY? uid)? (
jsonFunctionBranch KW_ON KW_EMPTY
)? (jsonFunctionBranch KW_ON uid)?
;
// JSON 函数只能在 JSON_OBJECT 函数中使用
jsonObjectParams
: (
KW_KEY? columnNamePath KW_VALUE? (
valueExpression
| KW_JSON LR_BRACKET (valueExpression)* RR_BRACKET
)
)* ((KW_NULL | uid) KW_ON KW_NULL)?
;
jsonArrayParams
: valueExpression* ((KW_NULL | uid) KW_ON KW_NULL)?
;
dereferenceDefinition
: uid
;
// base common
correlationName
: identifier
;
qualifiedName
: identifier
| dereferenceDefinition
;
timeIntervalExpression
: KW_INTERVAL (errorCapturingMultiUnitsInterval | errorCapturingUnitToUnitInterval)?
;
errorCapturingMultiUnitsInterval
: multiUnitsInterval unitToUnitInterval?
;
multiUnitsInterval
: (intervalValue timeIntervalUnit)+
;
errorCapturingUnitToUnitInterval
: body=unitToUnitInterval (error1=multiUnitsInterval | error2=unitToUnitInterval)?
;
unitToUnitInterval
: value=intervalValue from=timeIntervalUnit KW_TO to=timeIntervalUnit
;
intervalValue
: (ADD_SIGN | HYPHEN_SIGN)? (DIG_LITERAL | REAL_LITERAL)
| STRING_LITERAL
;
tableAlias
: KW_AS? alias=identifier identifierList?
;
errorCapturingIdentifier
: identifier errorCapturingIdentifierExtra
;
errorCapturingIdentifierExtra
: (KW_MINUS identifier)+ # errorIdent
| # realIdent
;
identifierList
: LR_BRACKET identifierSeq RR_BRACKET
;
identifierSeq
: identifier (COMMA identifier)*
;
identifier
: unquotedIdentifier # unquotedIdentifierAlternative
| quotedIdentifier # quotedIdentifierAlternative
| nonReservedKeywords # nonReservedKeywordsAlternative
;
unquotedIdentifier
: DIG_LITERAL
| ID_LITERAL
;
quotedIdentifier
: STRING_LITERAL
;
whenClause
: KW_WHEN condition=expression KW_THEN result=expression
;
catalogPath
: identifier
;
catalogPathCreate
: identifier
;
databasePath
: identifier (DOT identifier)?
;
databasePathCreate
: identifier (DOT identifier)?
;
tablePathCreate
: identifier (DOT identifier)?
| identifier DOT identifier (DOT identifier)?
;
tablePath
: identifier (DOT identifier)?
| identifier DOT identifier (DOT identifier)?
;
viewPath
: identifier (DOT identifier)?
| identifier DOT identifier (DOT identifier)?
;
viewPathCreate
: identifier (DOT identifier)?
| identifier DOT identifier (DOT identifier)?
;
uid
: identifier (DOT identifier)*?
;
withOption
: KW_WITH tablePropertyList
;
ifNotExists
: KW_IF KW_NOT KW_EXISTS
;
ifExists
: KW_IF KW_EXISTS
;
tablePropertyList
: LR_BRACKET tableProperty (COMMA tableProperty)* RR_BRACKET
;
tableProperty
: key=tablePropertyKey (EQUAL_SYMBOL? value=tablePropertyValue)?
;
tablePropertyKey
: identifier
| dereferenceDefinition
| STRING_LITERAL
;
tablePropertyValue
: DIG_LITERAL
| REAL_LITERAL
| booleanLiteral
| STRING_LITERAL
;
logicalOperator
: KW_AND
| BIT_AND_OP BIT_AND_OP
| KW_OR
| BIT_OR_OP BIT_OR_OP
;
comparisonOperator
: EQUAL_SYMBOL
| GREATER_SYMBOL
| LESS_SYMBOL
| LESS_SYMBOL EQUAL_SYMBOL
| GREATER_SYMBOL EQUAL_SYMBOL
| LESS_SYMBOL GREATER_SYMBOL
| EXCLAMATION_SYMBOL EQUAL_SYMBOL
| LESS_SYMBOL EQUAL_SYMBOL GREATER_SYMBOL
;
bitOperator
: LESS_SYMBOL LESS_SYMBOL
| GREATER_SYMBOL GREATER_SYMBOL
| BIT_AND_OP
| BIT_XOR_OP
| BIT_OR_OP
;
mathOperator
: ASTERISK_SIGN
| SLASH_SIGN
| PERCENT_SIGN
| KW_DIV
| ADD_SIGN
| HYPHEN_SIGN
| DOUBLE_HYPHEN_SIGN
;
unaryOperator
: EXCLAMATION_SYMBOL
| BIT_NOT_OP
| ADD_SIGN
| HYPHEN_SIGN
| KW_NOT
;
constant
: timeIntervalExpression
| timePointLiteral
| stringLiteral // 引号包含的字符串
| HYPHEN_SIGN? decimalLiteral // 正/负整数
| booleanLiteral // 布尔值
| REAL_LITERAL // 小数
| BIT_STRING
| KW_NOT? KW_NULL // 空 | 非空
;
timePointLiteral
: timePointUnit stringLiteral
;
stringLiteral
: STRING_LITERAL
;
decimalLiteral
: DIG_LITERAL
;
booleanLiteral
: KW_TRUE
| KW_FALSE
;
setQuantifier
: KW_DISTINCT
| KW_ALL
;
timePointUnit
: KW_YEAR
| KW_QUARTER
| KW_MONTH
| KW_WEEK
| KW_DAY
| KW_HOUR
| KW_MINUTE
| KW_SECOND
| KW_MILLISECOND
| KW_MICROSECOND
;
timeIntervalUnit
: KW_MILLENNIUM
| KW_CENTURY
| KW_DECADE
| KW_YEAR
| KW_YEARS
| KW_QUARTER
| KW_MONTH
| KW_MONTHS
| KW_WEEK
| KW_WEEKS
| KW_DAY
| KW_DAYS
| KW_HOUR
| KW_HOURS
| KW_MINUTE
| KW_MINUTES
| KW_SECOND
| KW_SECONDS
| KW_MILLISECOND
| KW_MICROSECOND
| KW_NANOSECOND
| KW_EPOCH
;
reservedKeywordsUsedAsFuncParam
: KW_ARRAY
| KW_ALL
| KW_BOTH
| KW_CURRENT_TIMESTAMP
| KW_CURRENT_DATE
| KW_CURRENT_TIME
| KW_LOCALTIME
| KW_LOCALTIMESTAMP
| KW_DISTINCT
| KW_LEADING
| KW_TRAILING
| KW_VALUE
| ASTERISK_SIGN
;
/**
* Built-in function name without parentheses and params
*/
reservedKeywordsNoParamsUsedAsFuncName
: KW_LOCALTIME
| KW_LOCALTIMESTAMP
| KW_CURRENT_TIME
| KW_CURRENT_DATE
| KW_CURRENT_TIMESTAMP
;
reservedKeywordsFollowParamsUsedAsFuncName
: KW_DATE
| KW_TIME
| KW_TIMESTAMP
;
reservedKeywordsUsedAsFuncName
: KW_ABS
| KW_ARRAY
| KW_AVG
| KW_CARDINALITY
| KW_CAST
| KW_CEIL
| KW_CEILING
| KW_COALESCE
| KW_COLLECT
| KW_COUNT
| KW_CUME_DIST
| KW_DAYOFWEEK
| KW_DAYOFYEAR
| KW_DENSE_RANK
| KW_ELEMENT
| KW_EXP
| KW_EXTRACT
| KW_FIRST_VALUE
| KW_FLOOR
| KW_GROUPING
| KW_HOUR
| KW_IF
| KW_LAG
| KW_LAST_VALUE
| KW_LEAD
| KW_LEFT
| KW_LN
| KW_LOWER
| KW_MAP
| KW_MAX
| KW_MIN
| KW_MINUTE
| KW_MOD
| KW_MONTH
| KW_NULLIF
| KW_NTILE
| KW_OVERLAY
| KW_PERCENT_RANK
| KW_POSITION
| KW_POWER
| KW_QUARTER
| KW_ROW
| KW_ROWS
| KW_ROW_NUMBER
| KW_RANK
| KW_RIGHT
| KW_SECOND
| KW_STDDEV_POP
| KW_STDDEV_SAMP
| KW_SUBSTRING
| KW_SUM
| KW_TIMESTAMP_DIFF
| KW_TRIM
| KW_TRUNCATE
| KW_TRY_CAST
| KW_UPPER
| KW_VAR_POP
| KW_VAR_SAMP
| KW_WEEK
| KW_YEAR
| KW_JSON_VALUE
| KW_JSON_EXISTS
| KW_JSON_QUERY
| KW_JSON_OBJECT
| KW_JSON_OBJECTAGG
| KW_JSON_ARRAY
| KW_JSON_ARRAYAGG
;
nonReservedKeywords
: KW_ADD
| KW_AFTER
| KW_ASC
| KW_CASCADE
| KW_CATALOG
| KW_CENTURY
| KW_CONFIG
| KW_CONSTRAINTS
| KW_CUMULATE
| KW_DATA
| KW_DATABASE
| KW_DAYS
| KW_DECADE
| KW_DESC
| KW_DESCRIPTOR
| KW_DIV
| KW_ENGINE
| KW_EPOCH
| KW_EXCLUDING
| KW_FILE
| KW_FIRST
| KW_GENERATED
| KW_HOP
| KW_HOURS
| KW_IGNORE
| KW_INCLUDING
| KW_JAR
| KW_JARS
| KW_JAVA
| KW_KEY
| KW_LAST
| KW_LOAD
| KW_MAP
| KW_MICROSECOND
| KW_MILLENNIUM
| KW_MILLISECOND
| KW_MINUTES
| KW_MONTHS
| KW_NANOSECOND
| KW_NULLS
| KW_OPTIONS
| KW_PAST
| KW_PLAN
| KW_PRECEDING
| KW_PYTHON
| KW_PYTHON_ARCHIVES
| KW_PYTHON_DEPENDENCIES
| KW_PYTHON_FILES
| KW_PYTHON_JAR
| KW_PYTHON_PARAMETER
| KW_PYTHON_REQUIREMENTS
| KW_QUARTER
| KW_REMOVE
| KW_RESTRICT
| KW_SECONDS
| KW_SESSION
| KW_SETS
| KW_SIZE
| KW_SLIDE
| KW_STEP
| KW_TEMPORARY
| KW_TIMECOL
| KW_TUMBLE
| KW_UNLOAD
| KW_VIEW
| KW_WEEK
| KW_YEARS
| KW_ZONE
;
================================================
FILE: superior-flink-parser/src/main/kotlin/io/github/melin/superior/parser/flink/AbstractSqlParser.kt
================================================
package io.github.melin.superior.parser.flink
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser
import java.util.concurrent.atomic.AtomicReference
object AbstractSqlParser {
private val parserCaches = AtomicReference(AntlrCaches(FlinkSqlParser._ATN))
/**
* Install the parser caches into the given parser.
*
* This method should be called before parsing any input.
*/
fun installCaches(parser: FlinkSqlParser): Unit = parserCaches.get().installCaches(parser)
/**
* Drop the existing parser caches and create a new one.
*
* ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can
* consume a lot of memory depending on the input seen so far.
*
* This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL
* inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.
*/
fun refreshParserCaches() {
parserCaches.set(AntlrCaches(FlinkSqlParser._ATN))
}
}
================================================
FILE: superior-flink-parser/src/main/kotlin/io/github/melin/superior/parser/flink/FlinkSqlAntlr4Visitor.kt
================================================
package io.github.melin.superior.parser.flink
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.*
import io.github.melin.superior.common.antlr4.ParserUtils.source
import io.github.melin.superior.common.relational.DefaultStatement
import io.github.melin.superior.common.relational.FunctionId
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.common.*
import io.github.melin.superior.common.relational.create.CreateCatalog
import io.github.melin.superior.common.relational.create.CreateTable
import io.github.melin.superior.common.relational.create.CreateTableAsSelect
import io.github.melin.superior.common.relational.create.CreateView
import io.github.melin.superior.common.relational.dml.InsertMode
import io.github.melin.superior.common.relational.dml.InsertMultiTable
import io.github.melin.superior.common.relational.dml.InsertTable
import io.github.melin.superior.common.relational.dml.QueryStmt
import io.github.melin.superior.common.relational.drop.DropCatalog
import io.github.melin.superior.common.relational.table.ColumnDefType
import io.github.melin.superior.common.relational.table.ColumnRel
import io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser
import io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.ComputedColumnDefinitionContext
import io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.MetadataColumnDefinitionContext
import io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.PhysicalColumnDefinitionContext
import io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.TablePropertyContext
import io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.TablePropertyListContext
import io.github.melin.superior.parser.flink.antlr4.FlinkSqlParser.UidContext
import io.github.melin.superior.parser.flink.antlr4.FlinkSqlParserBaseVisitor
import org.antlr.v4.runtime.tree.RuleNode
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2018/1/10. */
class FlinkSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) :
FlinkSqlParserBaseVisitor() {
private var currentOptType: StatementType = StatementType.UNKOWN
private var currentAlterActionType: AlterActionType = AlterActionType.UNKOWN
private var multiInsertToken: String? = null
private var limit: Int? = null
private var offset: Int? = null
private var inputTables: ArrayList = arrayListOf()
private var outputTables: ArrayList = arrayListOf()
private var cteTempTables: ArrayList = arrayListOf()
private var functionNames: HashSet = hashSetOf()
private var statements: ArrayList = arrayListOf()
private val sqls: ArrayList = arrayListOf()
fun getSqlStatements(): List {
return statements
}
fun getSplitSqls(): List {
return sqls
}
override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {
return if (currentResult == null) true else false
}
override fun visitSqlStatements(ctx: FlinkSqlParser.SqlStatementsContext): Statement? {
ctx.singleStatement().forEach {
var sql = source(it)
if (splitSql) {
if (StringUtils.endsWith(sql, ";")) {
sql = StringUtils.substringBeforeLast(sql, ";")
}
sqls.add(sql)
} else {
val startNode = it.start.text
val statement =
if (StringUtils.equalsIgnoreCase("show", startNode)) {
val keyWords: ArrayList = arrayListOf()
CommonUtils.findShowStatementKeyWord(keyWords, it)
ShowStatement(*keyWords.toTypedArray())
} else {
var statement = this.visitSingleStatement(it)
if (statement == null) {
statement = DefaultStatement(StatementType.UNKOWN)
}
statement
}
statement.setSql(sql)
statements.add(statement)
clean()
}
}
return null
}
private fun clean() {
currentOptType = StatementType.UNKOWN
limit = null
offset = null
inputTables = arrayListOf()
outputTables = arrayListOf()
cteTempTables = arrayListOf()
functionNames = hashSetOf()
}
override fun visitSqlStatement(ctx: FlinkSqlParser.SqlStatementContext): Statement? {
val statement = super.visitSqlStatement(ctx)
if (statement == null) {
val startToken = StringUtils.lowerCase(ctx.getStart().text)
if ("desc".equals(startToken) || "describe".equals(startToken)) {
return DefaultStatement(StatementType.DESC)
} else {
val sql = source(ctx)
throw SQLParserException("不支持的SQL: " + sql)
}
}
return statement
}
override fun visitSimpleCreateTable(ctx: FlinkSqlParser.SimpleCreateTableContext): Statement {
val tableId = parseTable(ctx.tablePathCreate().text)
val comment: String? = if (ctx.comment != null) ctx.comment.text else null
val properties = parseTableOptions(ctx.withOption().tablePropertyList())
val ifNotExists: Boolean = if (ctx.ifNotExists() != null) true else false
val primayKeys =
if (ctx.tableConstraint() != null) {
ctx.tableConstraint().columnNameList().columnName().map { col -> col.uid().text }
} else {
listOf()
}
val columnRels =
ctx.columnOptionDefinition().map {
val column = it.getChild(0)
if (column is PhysicalColumnDefinitionContext) {
val colName = column.columnNameCreate().text
val dataType = column.columnType().text
val primaryKey = if (column.columnConstraint() != null) true else primayKeys.contains(colName)
val colComment: String? =
if (column.comment != null) column.comment.text else null
ColumnRel(colName, dataType, colComment, primaryKey, ColumnDefType.PHYSICAL)
} else if (column is MetadataColumnDefinitionContext) {
val colName = column.columnNameCreate().text
val dataType = column.columnType().text
var metadataKey: String? = null
if (column.metadataKey() != null) {
metadataKey = CommonUtils.cleanQuote(column.metadataKey().text)
}
val columnRel = ColumnRel(colName, dataType, null, ColumnDefType.METADATA)
columnRel.metadataKey = metadataKey
columnRel
} else {
val computedColumn = column as ComputedColumnDefinitionContext
val colName = computedColumn.computedColumnExpression().text
val colComment: String? =
if (computedColumn.comment != null) computedColumn.comment.text
else null
val computedExpr = source(computedColumn.computedColumnExpression().expression())
val columnRel = ColumnRel(colName, null, colComment, ColumnDefType.COMPUTED)
columnRel.computedExpr = computedExpr
columnRel
}
}
return CreateTable(tableId, TableType.FLINK, comment, columnRels, ifNotExists, properties)
}
override fun visitCreateTableAsSelect(ctx: FlinkSqlParser.CreateTableAsSelectContext): Statement {
currentOptType = StatementType.CREATE_TABLE_AS_SELECT
val tableId = parseTable(ctx.tablePathCreate().text)
val properties = parseTableOptions(ctx.withOption().tablePropertyList())
val ifNotExists: Boolean = if (ctx.ifNotExists() != null) true else false
val queryStmt = this.visitQueryStatement(ctx.queryStatement()) as QueryStmt
return CreateTableAsSelect(tableId, queryStmt, null, ifNotExists, properties)
}
override fun visitCreateView(ctx: FlinkSqlParser.CreateViewContext): Statement {
currentOptType = StatementType.CREATE_VIEW
val tableId = parseTable(ctx.viewPathCreate().text)
val comment: String? = if (ctx.comment != null) ctx.comment.text else null
val queryStmt = this.visitQueryStatement(ctx.queryStatement()) as QueryStmt
val ifNotExists: Boolean = if (ctx.ifNotExists() != null) true else false
var columnNameList: List? = null
if (ctx.columnNameList() != null) {
columnNameList = ctx.columnNameList().columnName().map { ColumnRel(CommonUtils.cleanQuote(it.uid().text)) }
}
return CreateView(tableId, queryStmt, comment, ifNotExists, columnNameList)
}
override fun visitInsertStatement(ctx: FlinkSqlParser.InsertStatementContext): Statement {
if (ctx.insertSimpleStatement() != null) {
return this.insertSimpleStatement(ctx.insertSimpleStatement())
} else if (ctx.insertMulStatementCompatibility() != null) {
val insertTables =
ctx.insertMulStatementCompatibility().insertSimpleStatement().map { insertStmt ->
this.insertSimpleStatement(insertStmt)
}
return InsertMultiTable(insertTables)
} else if (ctx.insertMulStatement() != null) {
val insertTables =
ctx.insertMulStatement().insertSimpleStatement().map { insertStmt ->
this.insertSimpleStatement(insertStmt)
}
return InsertMultiTable(insertTables)
}
return super.visitInsertStatement(ctx)
}
private fun insertSimpleStatement(ctx: FlinkSqlParser.InsertSimpleStatementContext): InsertTable {
currentOptType = StatementType.INSERT
val tableId = parseTable(ctx.tablePath().text)
val insertMode = if (ctx.KW_INTO() != null) InsertMode.INTO else InsertMode.OVERWRITE
var columnNameList: List? = null
if (ctx.columnNameList() != null) {
columnNameList = ctx.columnNameList().columnName().map { ColumnRel(CommonUtils.cleanQuote(it.uid().text)) }
}
var queryStmt = QueryStmt()
if (ctx.queryStatement() != null) {
queryStmt = this.visitQueryStatement(ctx.queryStatement()) as QueryStmt
}
val insertTable = InsertTable(insertMode, queryStmt, tableId, columnNameList)
insertTable.outputTables.add(tableId)
var sql = source(ctx)
insertTable.setSql(sql)
return insertTable
}
override fun visitQueryStatement(ctx: FlinkSqlParser.QueryStatementContext): Statement {
if (currentOptType == StatementType.UNKOWN) {
currentOptType = StatementType.SELECT
}
super.visitQueryStatement(ctx)
return QueryStmt(inputTables, limit, offset)
}
override fun visitJarStatement(ctx: FlinkSqlParser.JarStatementContext): Statement {
val jarFileName = CommonUtils.cleanQuote(ctx.jarFileName().text)
if (ctx.KW_ADD() != null) {
return AddResourceStatement(jarFileName, "jar")
} else {
return RemoveResourceStatement(jarFileName, "jar")
}
}
override fun visitCreateCatalog(ctx: FlinkSqlParser.CreateCatalogContext): Statement {
val catalogName: String = CommonUtils.cleanQuote(ctx.catalogPathCreate().text)
val properties = parseTableOptions(ctx.withOption().tablePropertyList())
return CreateCatalog(catalogName, properties)
}
override fun visitDropCatalog(ctx: FlinkSqlParser.DropCatalogContext): Statement {
val catalogName: String = CommonUtils.cleanQuote(ctx.catalogPath().text)
return DropCatalog(catalogName)
}
override fun visitExplainStatement(ctx: FlinkSqlParser.ExplainStatementContext?): Statement {
return DefaultStatement(StatementType.EXPLAIN)
}
override fun visitUseStatement(ctx: FlinkSqlParser.UseStatementContext): Statement {
val catalogName: String = CommonUtils.cleanQuote(ctx.catalogPath().text)
return UseCatalog(catalogName)
}
override fun visitWindowTVFParam(ctx: FlinkSqlParser.WindowTVFParamContext): Statement? {
if (ctx.timeAttrColumn() != null) {
val tableId = parseTable(ctx.timeAttrColumn().uid().text)
inputTables.add(tableId)
}
return null
}
override fun visitTablePath(ctx: FlinkSqlParser.TablePathContext): Statement? {
if (
StatementType.SELECT == currentOptType ||
StatementType.INSERT == currentOptType ||
StatementType.UPDATE == currentOptType ||
StatementType.DELETE == currentOptType ||
StatementType.CREATE_VIEW == currentOptType ||
StatementType.CREATE_TABLE_AS_SELECT == currentOptType
) {
val tableId = parseTable(ctx.text)
if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {
inputTables.add(tableId)
}
}
return null
}
override fun visitWithItem(ctx: FlinkSqlParser.WithItemContext): Statement? {
val tableId = TableId(ctx.withItemName().text)
cteTempTables.add(tableId)
super.visitWithItem(ctx)
return null
}
override fun visitSetStatement(ctx: FlinkSqlParser.SetStatementContext): Statement {
val tableProperty = ctx.tableProperty()
var key = tableProperty.tablePropertyKey().text
var value = tableProperty.tablePropertyValue().text
key = CommonUtils.cleanQuote(key)
value = CommonUtils.cleanQuote(value)
return SetStatement(key, value)
}
override fun visitLimitClause(ctx: FlinkSqlParser.LimitClauseContext): Statement? {
if (ctx.limit != null) {
limit = ctx.limit.text.toInt()
}
return super.visitLimitClause(ctx)
}
private fun parseTable(path: String): TableId {
val path = CommonUtils.cleanQuote(path)
val items = StringUtils.split(path, ".")
if (items.size == 3) {
val catalog = CommonUtils.cleanQuote(items.get(0))
val schema = CommonUtils.cleanQuote(items.get(1))
val tableName = CommonUtils.cleanQuote(items.get(2))
return TableId(catalog, schema, tableName)
} else if (items.size == 2) {
val schema = CommonUtils.cleanQuote(items.get(0))
val tableName = CommonUtils.cleanQuote(items.get(1))
return TableId(schema, tableName)
} else if (items.size == 1) {
val tableName = CommonUtils.cleanQuote(items.get(0))
return TableId(tableName)
} else {
throw SQLParserException("parse multipart error: " + path)
}
}
fun parseDatabase(uid: UidContext): Pair {
val nodes = uid.identifier()
if (nodes.size == 2) {
val database = CommonUtils.cleanQuote(nodes.get(0).text)
val schema = CommonUtils.cleanQuote(nodes.get(1).text)
return Pair(database, schema)
} else if (nodes.size == 1) {
val schema = CommonUtils.cleanQuote(nodes.get(0).text)
return Pair(null, schema)
} else {
throw SQLParserException("parse multipart error: " + nodes.size)
}
}
private fun parseTableOptions(ctx: TablePropertyListContext): Map {
val properties = HashMap()
ctx.tableProperty().forEach { item ->
val property = item as TablePropertyContext
val key = CommonUtils.cleanQuote(property.key.text)
val value = CommonUtils.cleanQuote(property.value.text)
properties.put(key, value)
}
return properties
}
}
================================================
FILE: superior-flink-parser/src/main/kotlin/io/github/melin/superior/parser/flink/FlinkSqlHelper.kt
================================================
package io.github.melin.superior.parser.flink
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.common.antlr4.ParseErrorListener
import io.github.melin.superior.common.antlr4.ParseException
import io.github.melin.superior.common.antlr4.UpperCaseCharStream
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.parser.flink.antlr4.*
import org.antlr.v4.runtime.CharStreams
import org.antlr.v4.runtime.CommonTokenStream
import org.antlr.v4.runtime.atn.PredictionMode
import org.antlr.v4.runtime.misc.ParseCancellationException
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2018/1/10. */
object FlinkSqlHelper {
@JvmStatic
fun sqlKeywords(): List {
val keywords = hashSetOf()
(0 until FlinkSqlLexer.VOCABULARY.maxTokenType).forEach { idx ->
val name = FlinkSqlLexer.VOCABULARY.getLiteralName(idx)
if (name != null) {
val matchResult = CommonUtils.KEYWORD_REGEX.find(name)
if (matchResult != null) {
keywords.add(matchResult.groupValues.get(1))
}
}
}
return keywords.sorted()
}
@JvmStatic
fun parseStatement(command: String): Statement {
val statements = this.parseMultiStatement(command)
if (statements.size != 1) {
throw IllegalStateException("only parser one sql, sql count: " + statements.size)
} else {
return statements.get(0)
}
}
@JvmStatic
fun parseMultiStatement(command: String): List {
val trimCmd = StringUtils.trim(command)
val sqlVisitor = FlinkSqlAntlr4Visitor(false, trimCmd)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSqlStatements()
}
@JvmStatic
fun splitSql(command: String): List {
val trimCmd = StringUtils.trim(command)
val sqlVisitor = FlinkSqlAntlr4Visitor(true, trimCmd)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSplitSqls()
}
@JvmStatic
fun checkSqlSyntax(command: String) {
val sqlVisitor = FlinkSqlParserBaseVisitor()
innerParseStatement(command, sqlVisitor)
}
private fun innerParseStatement(command: String, sqlVisitor: FlinkSqlParserBaseVisitor) {
val charStream = UpperCaseCharStream(CharStreams.fromString(command))
val lexer = FlinkSqlLexer(charStream)
lexer.removeErrorListeners()
lexer.addErrorListener(ParseErrorListener())
val tokenStream = CommonTokenStream(lexer)
val parser = FlinkSqlParser(tokenStream)
AbstractSqlParser.installCaches(parser)
parser.addParseListener(FlinkSqlParserBaseListener())
parser.removeErrorListeners()
parser.addErrorListener(ParseErrorListener())
// parser.interpreter.predictionMode = PredictionMode.SLL
try {
try {
// first, try parsing with potentially faster SLL mode
sqlVisitor.visit(parser.sqlStatements())
} catch (e: ParseCancellationException) {
tokenStream.seek(0) // rewind input stream
parser.reset()
// Try Again.
parser.interpreter.predictionMode = PredictionMode.LL
sqlVisitor.visit(parser.sqlStatements())
}
} catch (e: ParseException) {
if (StringUtils.isNotBlank(e.command)) {
throw e
} else {
throw e.withCommand(command)
}
} finally {
val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)
if (releaseAntlrCache == null || "true".equals(releaseAntlrCache)) {
AbstractSqlParser.refreshParserCaches()
}
}
}
}
================================================
FILE: superior-flink-parser/src/test/kotlin/io/github/melin/superior/parser/flink/FlinkCheckSql.kt
================================================
package io.github.melin.superior.parser.flink
import org.junit.Test
class FlinkCheckSql {
@Test
fun selectSqlTest() {
val sql =
"""
CREATE TABLE test (
name VARCHAR(12)
) with(key = 'name')
"""
.trimIndent()
FlinkSqlHelper.checkSqlSyntax(sql)
}
}
================================================
FILE: superior-flink-parser/src/test/kotlin/io/github/melin/superior/parser/flink/FlinkSqlParserDdlTest.kt
================================================
package io.github.melin.superior.parser.flink
import io.github.melin.superior.common.relational.create.CreateTable
import io.github.melin.superior.common.relational.create.CreateView
import io.github.melin.superior.common.relational.dml.InsertTable
import org.junit.Assert
import org.junit.Test
/** Created by libinsong on 2018/1/10. */
class FlinkSqlParserDdlTest {
@Test
fun parseMultiSqlTest() {
val sql =
"""
CREATE TABLE IF NOT EXISTS `RETEK_XX_ITEM_ATTR_TRANSLATE_PRODUCT_ENRICHMENT`(
`ITEM` STRING,
`UDA_ID` DECIMAL(5,0),
`UDA_VALUE_ID` DECIMAL(3,0),
`LANG` DECIMAL(6,0),
`TRANSLATED_VALUE` STRING,
`LAST_UPDATE_ID` STRING,
`CREATE_DATETIME` TIMESTAMP(3),
`LAST_UPDATE_DATETIME` TIMESTAMP(3),
`KAFKA_PROCESS_TIME` AS PROCTIME(),
`record_time` TIMESTAMP_LTZ(3) METADATA FROM 'timestamp',
`cost` AS price * quantity
) WITH (
'connector' = 'kafka',
'properties.acks' = '-1',
'properties.allow.auto.create.topics' = 'true',
'topic' = 'test',
'properties.bootstrap.servers' = 'localhost:9082',
'value.format' = 'changelog-json',
'properties.group.id' = 'test',
'key.fields' = 'ITEM;UDA_ID;LANG',
'key.format'='json',
'scan.startup.mode' = 'earliest-offset',
'value.changelog-json.timestamp-format.standard'='ISO-8601',
'value.changelog-json.ignore-parse-errors' = 'true'
);
CREATE VIEW IF NOT EXISTS `MDM_VIEW_PRODUCT_ENRICHMENT` AS
(SELECT 'WTCTH' BU_CODE, 'WTCTH' FORMULA_COUNTRY_ID,
uif.ITEM PRODUCT_ID,
CAST(CAST(uif.UDA_ID AS DECIMAL(5, 0)) AS STRING) ENRICHMENT_ID,
uif.UDA_TEXT ENRICHMENT_VALUE,
u.UDA_DESC ENRICHMENT_DESC,
u.SINGLE_VALUE_IND SINGLE_VALUE_IND,
u.DISPLAY_TYPE CONTROL_TYPE,
'EN' LANG,
'FLINKJDBC' CREATE_BY,
uif.LAST_UPDATE_ID LAST_UPDATE_BY,
uif.CREATE_DATETIME CREATED,
uif.LAST_UPDATE_DATETIME LAST_UPDATED
FROM RETEK_UDA_ITEM_FF_PRODUCT_ENRICHMENT uif
JOIN MDM_DIM_UDA_LOOKUPMAP_ORACLE FOR SYSTEM_TIME AS OF uif.KAFKA_PROCESS_TIME AS u
ON CAST(uif.UDA_ID AS DECIMAL(5, 0)) = u.UDA_ID
JOIN MDM_DIM_PRODUCT_ATTRIB_TYPE_LOOKUPMAP_MYSQL FOR SYSTEM_TIME AS OF uif.KAFKA_PROCESS_TIME AS pat
ON CAST(CAST(uif.UDA_ID AS DECIMAL(5, 0)) AS STRING) = pat.ATTRIB_ID
AND pat.ATTRIB_TYPE = 'PRODUCT_ENRICHMENT'
);
INSERT INTO PROCESSED_MDM_PRODUCT_ENRICHMENT(PRODUCT_ID, ENRICHMENT_ID, LANG, ENRICHMENT_VALUE,LAST_UPDATED)
select PRODUCT_ID, ENRICHMENT_ID, LANG, ENRICHMENT_VALUE,LAST_UPDATED from MDM_VIEW_PRODUCT_ENRICHMENT_TRANSLATE;
"""
.trimIndent()
val statements = FlinkSqlHelper.parseMultiStatement(sql)
val createTable = statements.get(0)
if (createTable is CreateTable) {
Assert.assertEquals("RETEK_XX_ITEM_ATTR_TRANSLATE_PRODUCT_ENRICHMENT", createTable.tableId.tableName)
Assert.assertEquals(11, createTable.columnRels?.size)
Assert.assertEquals("PROCTIME()", createTable.columnRels?.get(8)?.computedExpr)
Assert.assertEquals("timestamp", createTable.columnRels?.get(9)?.metadataKey)
Assert.assertEquals("price * quantity", createTable.columnRels?.get(10)?.computedExpr)
Assert.assertEquals(12, createTable.properties?.size)
} else {
Assert.fail()
}
val createView = statements.get(1)
if (createView is CreateView) {
Assert.assertEquals("MDM_VIEW_PRODUCT_ENRICHMENT", createView.tableId.tableName)
Assert.assertEquals(3, createView.queryStmt.inputTables.size)
} else {
Assert.fail()
}
val insertTable = statements.get(2)
if (insertTable is InsertTable) {
Assert.assertEquals("PROCESSED_MDM_PRODUCT_ENRICHMENT", insertTable.outputTables.get(0).tableName)
Assert.assertEquals(1, insertTable.queryStmt.inputTables.size)
Assert.assertEquals(5, insertTable.columnRels?.size)
} else {
Assert.fail()
}
}
@Test
fun createTableTest0() {
val sql =
"""
CREATE TABLE Orders (
`user` BIGINT,
product STRING,
order_time TIMESTAMP(3),
WATERMARK FOR order_time AS order_time - INTERVAL '5' SECOND
) WITH (
'connector' = 'kafka'
)
"""
.trimIndent()
val statements = FlinkSqlHelper.parseMultiStatement(sql)
val createTable = statements.get(0)
if (createTable is CreateTable) {
Assert.assertEquals("Orders", createTable.tableId.tableName)
Assert.assertEquals(3, createTable.columnRels?.size)
Assert.assertEquals(1, createTable.properties?.size)
} else {
Assert.fail()
}
}
@Test
fun createTableTest1() {
val sql =
"""
CREATE TABLE `Orders` (product STRING PRIMARY KEY NOT ENFORCED, `a.b.c` INT)
WITH ('type'='source', 'foo'='bar')
"""
.trimIndent()
val createTable = FlinkSqlHelper.parseStatement(sql)
if (createTable is CreateTable) {
Assert.assertEquals("Orders", createTable.tableId.tableName)
Assert.assertEquals(2, createTable.columnRels?.size)
createTable.columnRels?.get(0)?.primaryKey?.let { Assert.assertTrue(it) }
Assert.assertEquals(2, createTable.properties?.size)
} else {
Assert.fail()
}
}
@Test
fun createTableTest2() {
val sql =
"""
CREATE TABLE flink_meta_role (
id INT,
name STRING,
code STRING,
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://172.18.5.44:3306/superior',
'table-name' = 'meta_role',
'username' = 'root',
'password' = 'root2023'
);
"""
.trimIndent()
val createTable = FlinkSqlHelper.parseStatement(sql)
if (createTable is CreateTable) {
Assert.assertEquals("flink_meta_role", createTable.tableId.tableName)
Assert.assertEquals(3, createTable.columnRels?.size)
createTable.columnRels?.get(0)?.primaryKey?.let { Assert.assertTrue(it) }
Assert.assertEquals(5, createTable.properties?.size)
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-flink-parser/src/test/kotlin/io/github/melin/superior/parser/flink/FlinkSqlParserDmlTest.kt
================================================
package io.github.melin.superior.parser.flink
import io.github.melin.superior.common.relational.common.AddResourceStatement
import io.github.melin.superior.common.relational.common.SetStatement
import io.github.melin.superior.common.relational.create.CreateCatalog
import io.github.melin.superior.common.relational.dml.InsertMultiTable
import io.github.melin.superior.common.relational.dml.QueryStmt
import org.junit.Assert
import org.junit.Test
/** Created by libinsong on 2018/1/10. */
class FlinkSqlParserDmlTest {
@Test
fun selectSqlTest() {
val sql =
"""
WITH orders_with_total AS (
SELECT order_id, price + tax AS total
FROM Orders
)
SELECT order_id, SUM(total)
FROM orders_with_total
GROUP BY order_id
limit 10;
SELECT order_id, price FROM (VALUES (1, 2.0), (2, 3.1)) AS t (order_id, price);
SELECT * FROM TABLE(TUMBLE(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '10' MINUTES));
SELECT * FROM TABLE(
TUMBLE(
DATA => TABLE Bid,
TIMECOL => DESCRIPTOR(bidtime),
SIZE => INTERVAL '10' MINUTES));
SELECT * FROM TABLE(
HOP(
DATA => TABLE Bid,
TIMECOL => DESCRIPTOR(bidtime),
SLIDE => INTERVAL '5' MINUTES,
SIZE => INTERVAL '10' MINUTES));
SELECT * FROM TABLE(
CUMULATE(
DATA => TABLE Bid,
TIMECOL => DESCRIPTOR(bidtime),
STEP => INTERVAL '2' MINUTES,
SIZE => INTERVAL '10' MINUTES));
SELECT window_start, window_end, SUM(price)
FROM TABLE(
TUMBLE(TABLE Bid, DESCRIPTOR(bidtime), INTERVAL '10' MINUTES, INTERVAL '1' MINUTES))
GROUP BY window_start, window_end;
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY category ORDER BY sales DESC) AS row_num
FROM ShopSales)
WHERE row_num <= 5;
SELECT *
FROM Ticker
MATCH_RECOGNIZE (
PARTITION BY symbol
ORDER BY rowtime
MEASURES
START_ROW.rowtime AS start_tstamp,
LAST(PRICE_DOWN.rowtime) AS bottom_tstamp,
LAST(PRICE_UP.rowtime) AS end_tstamp
ONE ROW PER MATCH
AFTER MATCH SKIP TO LAST PRICE_UP
PATTERN (START_ROW PRICE_DOWN+ PRICE_UP)
DEFINE
PRICE_DOWN AS
(LAST(PRICE_DOWN.price, 1) IS NULL AND PRICE_DOWN.price < START_ROW.price) OR
PRICE_DOWN.price < LAST(PRICE_DOWN.price, 1),
PRICE_UP AS
PRICE_UP.price > LAST(PRICE_DOWN.price, 1)
) MR;
set sfdf_1 = 'adf';
set sfdf_2 = true;
"""
.trimIndent()
val statements = FlinkSqlHelper.parseMultiStatement(sql)
var queryStmt = statements.get(0)
if (queryStmt is QueryStmt) {
Assert.assertEquals("Orders", queryStmt.inputTables.get(0).tableName)
Assert.assertEquals(10, queryStmt.limit)
} else {
Assert.fail()
}
queryStmt = statements.get(1)
if (queryStmt is QueryStmt) {
Assert.assertEquals(0, queryStmt.inputTables.size)
} else {
Assert.fail()
}
queryStmt = statements.get(2)
if (queryStmt is QueryStmt) {
Assert.assertEquals(1, queryStmt.inputTables.size)
Assert.assertEquals("Bid", queryStmt.inputTables.get(0).tableName)
} else {
Assert.fail()
}
queryStmt = statements.get(3)
if (queryStmt is QueryStmt) {
Assert.assertEquals(1, queryStmt.inputTables.size)
Assert.assertEquals("Bid", queryStmt.inputTables.get(0).tableName)
} else {
Assert.fail()
}
queryStmt = statements.get(4)
if (queryStmt is QueryStmt) {
Assert.assertEquals(1, queryStmt.inputTables.size)
Assert.assertEquals("Bid", queryStmt.inputTables.get(0).tableName)
} else {
Assert.fail()
}
queryStmt = statements.get(5)
if (queryStmt is QueryStmt) {
Assert.assertEquals(1, queryStmt.inputTables.size)
Assert.assertEquals("Bid", queryStmt.inputTables.get(0).tableName)
} else {
Assert.fail()
}
queryStmt = statements.get(6)
if (queryStmt is QueryStmt) {
Assert.assertEquals(1, queryStmt.inputTables.size)
Assert.assertEquals("Bid", queryStmt.inputTables.get(0).tableName)
} else {
Assert.fail()
}
queryStmt = statements.get(7)
if (queryStmt is QueryStmt) {
Assert.assertEquals(1, queryStmt.inputTables.size)
Assert.assertEquals("ShopSales", queryStmt.inputTables.get(0).tableName)
} else {
Assert.fail()
}
queryStmt = statements.get(8)
if (queryStmt is QueryStmt) {
Assert.assertEquals(1, queryStmt.inputTables.size)
Assert.assertEquals("Ticker", queryStmt.inputTables.get(0).tableName)
} else {
Assert.fail()
}
}
@Test
fun selectSqlTest1() {
val sql =
"""
add jar "flink-connector-jdbc-3.1.1-1.17.jar";
CREATE TABLE flink_meta_role (
id INT,
name STRING,
code STRING,
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://172.18.5.44:3306/superior',
'table-name' = 'meta_role',
'username' = 'root',
'password' = 'root2023'
);
set 'execution.checkpointing.checkpoints-after-tasks-finish.enabled' = false;
SELECT * FROM flink_meta_role;
"""
.trimIndent()
val statements = FlinkSqlHelper.parseMultiStatement(sql)
Assert.assertEquals(4, statements.size)
val addStmt = statements.get(0)
if (addStmt is AddResourceStatement) {
Assert.assertEquals("flink-connector-jdbc-3.1.1-1.17.jar", addStmt.first())
} else {
Assert.fail()
}
val setStmt = statements.get(2)
if (setStmt is SetStatement) {
Assert.assertEquals("execution.checkpointing.checkpoints-after-tasks-finish.enabled", setStmt.key)
} else {
Assert.fail()
}
}
@Test
fun selectSqlTest2() {
val sql =
"""
CREATE CATALOG my_catalog WITH (
'type' = 'jdbc',
'default-database' = 'demos',
'username' = 'root',
'password' = 'root2023',
'base-url' = 'jdbc:mysql://172.18.5.44:3306'
);
USE CATALOG my_catalog;
DROP CATALOG IF EXISTS my_catalog
EXPLAIN PLAN FOR select * from my_catalog.demos.orders;
EXPLAIN ESTIMATED_COST, CHANGELOG_MODE, PLAN_ADVICE, JSON_EXECUTION_PLAN
select * from my_catalog.demos.orders;
"""
.trimIndent()
val statements = FlinkSqlHelper.parseMultiStatement(sql)
Assert.assertEquals(5, statements.size)
val createCatalog = statements.get(0)
if (createCatalog is CreateCatalog) {
Assert.assertEquals("my_catalog", createCatalog.catalogName)
} else {
Assert.fail()
}
}
@Test
fun multiInsertTest() {
val sql =
"""
CREATE TABLE pageviews (
user_id BIGINT,
page_id BIGINT,
viewtime TIMESTAMP,
proctime AS PROCTIME()
) WITH (
'connector' = 'kafka',
'topic' = 'pageviews',
'properties.bootstrap.servers' = '...',
'format' = 'avro'
);
CREATE TABLE pageview (
page_id BIGINT,
cnt BIGINT
) WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://localhost:3306/mydatabase',
'table-name' = 'pageview'
);
CREATE TABLE uniqueview (
page_id BIGINT,
cnt BIGINT
) WITH (
'connector' = 'jdbc',
'url' = 'jdbc:mysql://localhost:3306/mydatabase',
'table-name' = 'uniqueview'
);
EXECUTE STATEMENT SET
BEGIN
INSERT INTO pageview
SELECT page_id, count(1)
FROM pageviews
GROUP BY page_id;
INSERT INTO uniqueview
SELECT page_id, count(distinct user_id)
FROM pageviews
GROUP BY page_id;
END;
"""
.trimIndent()
val statements = FlinkSqlHelper.parseMultiStatement(sql)
Assert.assertEquals(4, statements.size)
val statement = statements.get(3)
if (statement is InsertMultiTable) {
Assert.assertEquals(2, statement.insertTables.size)
val insertTable = statement.insertTables.get(0)
Assert.assertEquals(
"INSERT INTO pageview\n" + " SELECT page_id, count(1)\n" + " FROM pageviews\n" + " GROUP BY page_id",
insertTable.getSql()
)
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-flink-parser/src/test/resources/log4j2.xml
================================================
================================================
FILE: superior-mysql-parser/pom.xml
================================================
4.0.0
io.github.melin.superior
superior-sql-parser
4.0.23
superior-mysql-parser
superior-mysql-parser
io.github.melin.superior
superior-common-parser
${project.version}
================================================
FILE: superior-mysql-parser/src/main/antlr4/io/github/melin/superior/parser/mysql/antlr4/MySqlLexer.g4
================================================
lexer grammar MySqlLexer;
channels {
MYSQLCOMMENT,
ERRORCHANNEL
}
// SKIP
SPACE : [ \t\r\n]+ -> channel(HIDDEN);
SPEC_MYSQL_COMMENT : '/*!' .+? '*/' -> channel(MYSQLCOMMENT);
COMMENT_INPUT : '/*' .*? '*/' -> channel(HIDDEN);
LINE_COMMENT:
(('--' [ \t]* | '#') ~[\r\n]* ('\r'? '\n' | EOF) | '--' ('\r'? '\n' | EOF)) -> channel(HIDDEN)
;
// Keywords
// Common Keywords
ADD : 'ADD';
ALL : 'ALL';
ALTER : 'ALTER';
ALWAYS : 'ALWAYS';
ANALYZE : 'ANALYZE';
AND : 'AND';
ARRAY : 'ARRAY';
AS : 'AS';
ASC : 'ASC';
ATTRIBUTE : 'ATTRIBUTE';
BEFORE : 'BEFORE';
BETWEEN : 'BETWEEN';
BOTH : 'BOTH';
BUCKETS : 'BUCKETS';
BY : 'BY';
CALL : 'CALL';
CASCADE : 'CASCADE';
CASE : 'CASE';
CAST : 'CAST';
CHANGE : 'CHANGE';
CHARACTER : 'CHARACTER';
CHECK : 'CHECK';
COLLATE : 'COLLATE';
COLUMN : 'COLUMN';
CONDITION : 'CONDITION';
CONSTRAINT : 'CONSTRAINT';
CONTINUE : 'CONTINUE';
CONVERT : 'CONVERT';
CREATE : 'CREATE';
CROSS : 'CROSS';
CURRENT : 'CURRENT';
CURRENT_ROLE : 'CURRENT_ROLE';
CURRENT_USER : 'CURRENT_USER';
CURSOR : 'CURSOR';
DATABASE : 'DATABASE';
DATABASES : 'DATABASES';
DECLARE : 'DECLARE';
DEFAULT : 'DEFAULT';
DELAYED : 'DELAYED';
DELETE : 'DELETE';
DESC : 'DESC';
DESCRIBE : 'DESCRIBE';
DETERMINISTIC : 'DETERMINISTIC';
DIAGNOSTICS : 'DIAGNOSTICS';
DISTINCT : 'DISTINCT';
DISTINCTROW : 'DISTINCTROW';
DROP : 'DROP';
EACH : 'EACH';
ELSE : 'ELSE';
ELSEIF : 'ELSEIF';
EMPTY : 'EMPTY';
ENCLOSED : 'ENCLOSED';
ENFORCED : 'ENFORCED';
ESCAPED : 'ESCAPED';
EXCEPT : 'EXCEPT';
EXISTS : 'EXISTS';
EXIT : 'EXIT';
EXPLAIN : 'EXPLAIN';
FALSE : 'FALSE';
FETCH : 'FETCH';
FOR : 'FOR';
FORCE : 'FORCE';
FOREIGN : 'FOREIGN';
FROM : 'FROM';
FULLTEXT : 'FULLTEXT';
GENERATED : 'GENERATED';
GET : 'GET';
GRANT : 'GRANT';
GROUP : 'GROUP';
HAVING : 'HAVING';
HIGH_PRIORITY : 'HIGH_PRIORITY';
HISTOGRAM : 'HISTOGRAM';
IF : 'IF';
IGNORE : 'IGNORE';
IGNORED : 'IGNORED';
IN : 'IN';
INDEX : 'INDEX';
INFILE : 'INFILE';
INNER : 'INNER';
INOUT : 'INOUT';
INSERT : 'INSERT';
INTERVAL : 'INTERVAL';
INTO : 'INTO';
IS : 'IS';
ITERATE : 'ITERATE';
JOIN : 'JOIN';
KEY : 'KEY';
KEYS : 'KEYS';
KILL : 'KILL';
LATERAL : 'LATERAL';
LEADING : 'LEADING';
LEAVE : 'LEAVE';
LEFT : 'LEFT';
LIKE : 'LIKE';
LIMIT : 'LIMIT';
LINEAR : 'LINEAR';
LINES : 'LINES';
LOAD : 'LOAD';
LOCK : 'LOCK';
LOCKED : 'LOCKED';
LOOP : 'LOOP';
LOW_PRIORITY : 'LOW_PRIORITY';
MASTER_BIND : 'MASTER_BIND';
MASTER_SSL_VERIFY_SERVER_CERT : 'MASTER_SSL_VERIFY_SERVER_CERT';
MATCH : 'MATCH';
MAXVALUE : 'MAXVALUE';
MINVALUE : 'MINVALUE';
MODIFIES : 'MODIFIES';
NATURAL : 'NATURAL';
NOT : 'NOT';
NO_WRITE_TO_BINLOG : 'NO_WRITE_TO_BINLOG';
NULL_LITERAL : 'NULL';
NUMBER : 'NUMBER';
ON : 'ON';
OPTIMIZE : 'OPTIMIZE';
OPTION : 'OPTION';
OPTIONAL : 'OPTIONAL';
OPTIONALLY : 'OPTIONALLY';
OR : 'OR';
ORDER : 'ORDER';
OUT : 'OUT';
OUTER : 'OUTER';
OUTFILE : 'OUTFILE';
OVER : 'OVER';
PARTITION : 'PARTITION';
PRIMARY : 'PRIMARY';
PROCEDURE : 'PROCEDURE';
PURGE : 'PURGE';
RANGE : 'RANGE';
READ : 'READ';
READS : 'READS';
REFERENCES : 'REFERENCES';
REGEXP : 'REGEXP';
RELEASE : 'RELEASE';
RENAME : 'RENAME';
REPEAT : 'REPEAT';
REPLACE : 'REPLACE';
REQUIRE : 'REQUIRE';
RESIGNAL : 'RESIGNAL';
RESTRICT : 'RESTRICT';
RETAIN : 'RETAIN';
RETURN : 'RETURN';
REVOKE : 'REVOKE';
RIGHT : 'RIGHT';
RLIKE : 'RLIKE';
SCHEMA : 'SCHEMA';
SCHEMAS : 'SCHEMAS';
SELECT : 'SELECT';
SET : 'SET';
SEPARATOR : 'SEPARATOR';
SHOW : 'SHOW';
SIGNAL : 'SIGNAL';
SKIP_ : 'SKIP';
SKIP_QUERY_REWRITE : 'SKIP_QUERY_REWRITE';
SPATIAL : 'SPATIAL';
SQL : 'SQL';
SQLEXCEPTION : 'SQLEXCEPTION';
SQLSTATE : 'SQLSTATE';
SQLWARNING : 'SQLWARNING';
SQL_BIG_RESULT : 'SQL_BIG_RESULT';
SQL_CALC_FOUND_ROWS : 'SQL_CALC_FOUND_ROWS';
SQL_SMALL_RESULT : 'SQL_SMALL_RESULT';
SSL : 'SSL';
STACKED : 'STACKED';
STARTING : 'STARTING';
STATEMENT : 'STATEMENT';
STRAIGHT_JOIN : 'STRAIGHT_JOIN';
TABLE : 'TABLE';
TERMINATED : 'TERMINATED';
THEN : 'THEN';
TO : 'TO';
TRAILING : 'TRAILING';
TRIGGER : 'TRIGGER';
TRUE : 'TRUE';
UNDO : 'UNDO';
UNION : 'UNION';
UNIQUE : 'UNIQUE';
UNLOCK : 'UNLOCK';
UNSIGNED : 'UNSIGNED';
UPDATE : 'UPDATE';
USAGE : 'USAGE';
USE : 'USE';
USING : 'USING';
VALUES : 'VALUES';
WHEN : 'WHEN';
WHERE : 'WHERE';
WHILE : 'WHILE';
WITH : 'WITH';
WRITE : 'WRITE';
XOR : 'XOR';
ZEROFILL : 'ZEROFILL';
// DATA TYPE Keywords
TINYINT : 'TINYINT';
SMALLINT : 'SMALLINT';
MEDIUMINT : 'MEDIUMINT';
MIDDLEINT : 'MIDDLEINT';
INT : 'INT';
INT1 : 'INT1';
INT2 : 'INT2';
INT3 : 'INT3';
INT4 : 'INT4';
INT8 : 'INT8';
INTEGER : 'INTEGER';
BIGINT : 'BIGINT';
REAL : 'REAL';
DOUBLE : 'DOUBLE';
PRECISION : 'PRECISION';
FLOAT : 'FLOAT';
FLOAT4 : 'FLOAT4';
FLOAT8 : 'FLOAT8';
DECIMAL : 'DECIMAL';
DEC : 'DEC';
NUMERIC : 'NUMERIC';
DATE : 'DATE';
TIME : 'TIME';
TIMESTAMP : 'TIMESTAMP';
DATETIME : 'DATETIME';
YEAR : 'YEAR';
CHAR : 'CHAR';
VARCHAR : 'VARCHAR';
NVARCHAR : 'NVARCHAR';
NATIONAL : 'NATIONAL';
BINARY : 'BINARY';
VARBINARY : 'VARBINARY';
TINYBLOB : 'TINYBLOB';
BLOB : 'BLOB';
MEDIUMBLOB : 'MEDIUMBLOB';
LONG : 'LONG';
LONGBLOB : 'LONGBLOB';
TINYTEXT : 'TINYTEXT';
TEXT : 'TEXT';
MEDIUMTEXT : 'MEDIUMTEXT';
LONGTEXT : 'LONGTEXT';
ENUM : 'ENUM';
VARYING : 'VARYING';
SERIAL : 'SERIAL';
VECTOR : 'VECTOR';
// Interval type Keywords
YEAR_MONTH : 'YEAR_MONTH';
DAY_HOUR : 'DAY_HOUR';
DAY_MINUTE : 'DAY_MINUTE';
DAY_SECOND : 'DAY_SECOND';
HOUR_MINUTE : 'HOUR_MINUTE';
HOUR_SECOND : 'HOUR_SECOND';
MINUTE_SECOND : 'MINUTE_SECOND';
SECOND_MICROSECOND : 'SECOND_MICROSECOND';
MINUTE_MICROSECOND : 'MINUTE_MICROSECOND';
HOUR_MICROSECOND : 'HOUR_MICROSECOND';
DAY_MICROSECOND : 'DAY_MICROSECOND';
// JSON keywords
JSON_ARRAY : 'JSON_ARRAY';
JSON_ARRAYAGG : 'JSON_ARRAYAGG';
JSON_ARRAY_APPEND : 'JSON_ARRAY_APPEND';
JSON_ARRAY_INSERT : 'JSON_ARRAY_INSERT';
JSON_CONTAINS : 'JSON_CONTAINS';
JSON_CONTAINS_PATH : 'JSON_CONTAINS_PATH';
JSON_DEPTH : 'JSON_DEPTH';
JSON_EXTRACT : 'JSON_EXTRACT';
JSON_INSERT : 'JSON_INSERT';
JSON_KEYS : 'JSON_KEYS';
JSON_LENGTH : 'JSON_LENGTH';
JSON_MERGE : 'JSON_MERGE';
JSON_MERGE_PATCH : 'JSON_MERGE_PATCH';
JSON_MERGE_PRESERVE : 'JSON_MERGE_PRESERVE';
JSON_OBJECT : 'JSON_OBJECT';
JSON_OBJECTAGG : 'JSON_OBJECTAGG';
JSON_OVERLAPS : 'JSON_OVERLAPS';
JSON_PRETTY : 'JSON_PRETTY';
JSON_QUOTE : 'JSON_QUOTE';
JSON_REMOVE : 'JSON_REMOVE';
JSON_REPLACE : 'JSON_REPLACE';
JSON_SCHEMA_VALID : 'JSON_SCHEMA_VALID';
JSON_SCHEMA_VALIDATION_REPORT : 'JSON_SCHEMA_VALIDATION_REPORT';
JSON_SEARCH : 'JSON_SEARCH';
JSON_SET : 'JSON_SET';
JSON_STORAGE_FREE : 'JSON_STORAGE_FREE';
JSON_STORAGE_SIZE : 'JSON_STORAGE_SIZE';
JSON_TABLE : 'JSON_TABLE';
JSON_TYPE : 'JSON_TYPE';
JSON_UNQUOTE : 'JSON_UNQUOTE';
JSON_VALID : 'JSON_VALID';
JSON_VALUE : 'JSON_VALUE';
NESTED : 'NESTED';
ORDINALITY : 'ORDINALITY';
PATH : 'PATH';
// Group function Keywords
AVG : 'AVG';
BIT_AND : 'BIT_AND';
BIT_OR : 'BIT_OR';
BIT_XOR : 'BIT_XOR';
COUNT : 'COUNT';
CUME_DIST : 'CUME_DIST';
DENSE_RANK : 'DENSE_RANK';
FIRST_VALUE : 'FIRST_VALUE';
GROUP_CONCAT : 'GROUP_CONCAT';
LAG : 'LAG';
LAST_VALUE : 'LAST_VALUE';
LEAD : 'LEAD';
MAX : 'MAX';
MIN : 'MIN';
NTILE : 'NTILE';
NTH_VALUE : 'NTH_VALUE';
PERCENT_RANK : 'PERCENT_RANK';
RANK : 'RANK';
ROW_NUMBER : 'ROW_NUMBER';
STD : 'STD';
STDDEV : 'STDDEV';
STDDEV_POP : 'STDDEV_POP';
STDDEV_SAMP : 'STDDEV_SAMP';
SUM : 'SUM';
VAR_POP : 'VAR_POP';
VAR_SAMP : 'VAR_SAMP';
VARIANCE : 'VARIANCE';
// Common function Keywords
CURRENT_DATE : 'CURRENT_DATE';
CURRENT_TIME : 'CURRENT_TIME';
CURRENT_TIMESTAMP : 'CURRENT_TIMESTAMP';
LOCALTIME : 'LOCALTIME';
CURDATE : 'CURDATE';
CURTIME : 'CURTIME';
DATE_ADD : 'DATE_ADD';
DATE_SUB : 'DATE_SUB';
EXTRACT : 'EXTRACT';
LOCALTIMESTAMP : 'LOCALTIMESTAMP';
NOW : 'NOW';
POSITION : 'POSITION';
SUBSTR : 'SUBSTR';
SUBSTRING : 'SUBSTRING';
SYSDATE : 'SYSDATE';
TRIM : 'TRIM';
UTC_DATE : 'UTC_DATE';
UTC_TIME : 'UTC_TIME';
UTC_TIMESTAMP : 'UTC_TIMESTAMP';
// Keywords, but can be ID
// Common Keywords, but can be ID
ACCOUNT : 'ACCOUNT';
ACTION : 'ACTION';
AFTER : 'AFTER';
AGGREGATE : 'AGGREGATE';
ALGORITHM : 'ALGORITHM';
ANY : 'ANY';
AT : 'AT';
AUTHORS : 'AUTHORS';
AUTOCOMMIT : 'AUTOCOMMIT';
AUTOEXTEND_SIZE : 'AUTOEXTEND_SIZE';
AUTO_INCREMENT : 'AUTO_INCREMENT';
AVG_ROW_LENGTH : 'AVG_ROW_LENGTH';
BEGIN : 'BEGIN';
BINLOG : 'BINLOG';
BIT : 'BIT';
BLOCK : 'BLOCK';
BOOL : 'BOOL';
BOOLEAN : 'BOOLEAN';
BTREE : 'BTREE';
CACHE : 'CACHE';
CASCADED : 'CASCADED';
CHAIN : 'CHAIN';
CHANGED : 'CHANGED';
CHANNEL : 'CHANNEL';
CHECKSUM : 'CHECKSUM';
PAGE_CHECKSUM : 'PAGE_CHECKSUM';
CIPHER : 'CIPHER';
CLASS_ORIGIN : 'CLASS_ORIGIN';
CLIENT : 'CLIENT';
CLOSE : 'CLOSE';
CLUSTERING : 'CLUSTERING';
COALESCE : 'COALESCE';
CODE : 'CODE';
COLUMNS : 'COLUMNS';
COLUMN_FORMAT : 'COLUMN_FORMAT';
COLUMN_NAME : 'COLUMN_NAME';
COMMENT : 'COMMENT';
COMMIT : 'COMMIT';
COMPACT : 'COMPACT';
COMPLETION : 'COMPLETION';
COMPRESSED : 'COMPRESSED';
COMPRESSION : 'COMPRESSION' | QUOTE_SYMB? 'COMPRESSION' QUOTE_SYMB?;
CONCURRENT : 'CONCURRENT';
CONNECT : 'CONNECT';
CONNECTION : 'CONNECTION';
CONSISTENT : 'CONSISTENT';
CONSTRAINT_CATALOG : 'CONSTRAINT_CATALOG';
CONSTRAINT_SCHEMA : 'CONSTRAINT_SCHEMA';
CONSTRAINT_NAME : 'CONSTRAINT_NAME';
CONTAINS : 'CONTAINS';
CONTEXT : 'CONTEXT';
CONTRIBUTORS : 'CONTRIBUTORS';
COPY : 'COPY';
CPU : 'CPU';
CYCLE : 'CYCLE';
CURSOR_NAME : 'CURSOR_NAME';
DATA : 'DATA';
DATAFILE : 'DATAFILE';
DEALLOCATE : 'DEALLOCATE';
DEFAULT_AUTH : 'DEFAULT_AUTH';
DEFINER : 'DEFINER';
DELAY_KEY_WRITE : 'DELAY_KEY_WRITE';
DES_KEY_FILE : 'DES_KEY_FILE';
DIRECTORY : 'DIRECTORY';
DISABLE : 'DISABLE';
DISCARD : 'DISCARD';
DISK : 'DISK';
DO : 'DO';
DUMPFILE : 'DUMPFILE';
DUPLICATE : 'DUPLICATE';
DYNAMIC : 'DYNAMIC';
ENABLE : 'ENABLE';
ENCRYPTED : 'ENCRYPTED';
ENCRYPTION : 'ENCRYPTION';
ENCRYPTION_KEY_ID : 'ENCRYPTION_KEY_ID';
END : 'END';
ENDS : 'ENDS';
ENGINE : 'ENGINE';
ENGINES : 'ENGINES';
ERROR : 'ERROR';
ERRORS : 'ERRORS';
ESCAPE : 'ESCAPE';
EVEN : 'EVEN';
EVENT : 'EVENT';
EVENTS : 'EVENTS';
EVERY : 'EVERY';
EXCHANGE : 'EXCHANGE';
EXCLUSIVE : 'EXCLUSIVE';
EXPIRE : 'EXPIRE';
EXPORT : 'EXPORT';
EXTENDED : 'EXTENDED';
EXTENT_SIZE : 'EXTENT_SIZE';
FAILED_LOGIN_ATTEMPTS : 'FAILED_LOGIN_ATTEMPTS';
FAST : 'FAST';
FAULTS : 'FAULTS';
FIELDS : 'FIELDS';
FILE_BLOCK_SIZE : 'FILE_BLOCK_SIZE';
FILTER : 'FILTER';
FIRST : 'FIRST';
FIXED : 'FIXED';
FLUSH : 'FLUSH';
FOLLOWING : 'FOLLOWING';
FOLLOWS : 'FOLLOWS';
FOUND : 'FOUND';
FULL : 'FULL';
FUNCTION : 'FUNCTION';
GENERAL : 'GENERAL';
GLOBAL : 'GLOBAL';
GRANTS : 'GRANTS';
GROUP_REPLICATION : 'GROUP_REPLICATION';
HANDLER : 'HANDLER';
HASH : 'HASH';
HELP : 'HELP';
HISTORY : 'HISTORY';
HOST : 'HOST';
HOSTS : 'HOSTS';
IDENTIFIED : 'IDENTIFIED';
IGNORE_SERVER_IDS : 'IGNORE_SERVER_IDS';
IMPORT : 'IMPORT';
INCREMENT : 'INCREMENT';
INDEXES : 'INDEXES';
INITIAL_SIZE : 'INITIAL_SIZE';
INPLACE : 'INPLACE';
INSERT_METHOD : 'INSERT_METHOD';
INSTALL : 'INSTALL';
INSTANCE : 'INSTANCE';
INSTANT : 'INSTANT';
INVISIBLE : 'INVISIBLE';
INVOKER : 'INVOKER';
IO : 'IO';
IO_THREAD : 'IO_THREAD';
IPC : 'IPC';
ISOLATION : 'ISOLATION';
ISSUER : 'ISSUER';
JSON : 'JSON';
KEY_BLOCK_SIZE : 'KEY_BLOCK_SIZE';
LANGUAGE : 'LANGUAGE';
LAST : 'LAST';
LEAVES : 'LEAVES';
LESS : 'LESS';
LEVEL : 'LEVEL';
LIST : 'LIST';
LOCAL : 'LOCAL';
LOGFILE : 'LOGFILE';
LOGS : 'LOGS';
MASTER : 'MASTER';
MASTER_AUTO_POSITION : 'MASTER_AUTO_POSITION';
MASTER_CONNECT_RETRY : 'MASTER_CONNECT_RETRY';
MASTER_DELAY : 'MASTER_DELAY';
MASTER_HEARTBEAT_PERIOD : 'MASTER_HEARTBEAT_PERIOD';
MASTER_HOST : 'MASTER_HOST';
MASTER_LOG_FILE : 'MASTER_LOG_FILE';
MASTER_LOG_POS : 'MASTER_LOG_POS';
MASTER_PASSWORD : 'MASTER_PASSWORD';
MASTER_PORT : 'MASTER_PORT';
MASTER_RETRY_COUNT : 'MASTER_RETRY_COUNT';
MASTER_SSL : 'MASTER_SSL';
MASTER_SSL_CA : 'MASTER_SSL_CA';
MASTER_SSL_CAPATH : 'MASTER_SSL_CAPATH';
MASTER_SSL_CERT : 'MASTER_SSL_CERT';
MASTER_SSL_CIPHER : 'MASTER_SSL_CIPHER';
MASTER_SSL_CRL : 'MASTER_SSL_CRL';
MASTER_SSL_CRLPATH : 'MASTER_SSL_CRLPATH';
MASTER_SSL_KEY : 'MASTER_SSL_KEY';
MASTER_TLS_VERSION : 'MASTER_TLS_VERSION';
MASTER_USER : 'MASTER_USER';
MAX_CONNECTIONS_PER_HOUR : 'MAX_CONNECTIONS_PER_HOUR';
MAX_QUERIES_PER_HOUR : 'MAX_QUERIES_PER_HOUR';
MAX_ROWS : 'MAX_ROWS';
MAX_SIZE : 'MAX_SIZE';
MAX_UPDATES_PER_HOUR : 'MAX_UPDATES_PER_HOUR';
MAX_USER_CONNECTIONS : 'MAX_USER_CONNECTIONS';
MEDIUM : 'MEDIUM';
MEMBER : 'MEMBER';
MERGE : 'MERGE';
MESSAGE_TEXT : 'MESSAGE_TEXT';
MID : 'MID';
MIGRATE : 'MIGRATE';
MIN_ROWS : 'MIN_ROWS';
MODE : 'MODE';
MODIFY : 'MODIFY';
MUTEX : 'MUTEX';
MYSQL : 'MYSQL';
MYSQL_ERRNO : 'MYSQL_ERRNO';
NAME : 'NAME';
NAMES : 'NAMES';
NCHAR : 'NCHAR';
NEVER : 'NEVER';
NEXT : 'NEXT';
NO : 'NO';
NOCACHE : 'NOCACHE';
NOCOPY : 'NOCOPY';
NOCYCLE : 'NOCYCLE';
NOMAXVALUE : 'NOMAXVALUE';
NOMINVALUE : 'NOMINVALUE';
NOWAIT : 'NOWAIT';
NODEGROUP : 'NODEGROUP';
NONE : 'NONE';
ODBC : 'ODBC';
OFFLINE : 'OFFLINE';
OFFSET : 'OFFSET';
OF : 'OF';
OJ : 'OJ';
OLD_PASSWORD : 'OLD_PASSWORD';
ONE : 'ONE';
ONLINE : 'ONLINE';
ONLY : 'ONLY';
OPEN : 'OPEN';
OPTIMIZER_COSTS : 'OPTIMIZER_COSTS';
OPTIONS : 'OPTIONS';
OWNER : 'OWNER';
PACK_KEYS : 'PACK_KEYS';
PAGE : 'PAGE';
PAGE_COMPRESSED : 'PAGE_COMPRESSED';
PAGE_COMPRESSION_LEVEL : 'PAGE_COMPRESSION_LEVEL';
PARSER : 'PARSER';
PARTIAL : 'PARTIAL';
PARTITIONING : 'PARTITIONING';
PARTITIONS : 'PARTITIONS';
PASSWORD : 'PASSWORD';
PASSWORD_LOCK_TIME : 'PASSWORD_LOCK_TIME';
PHASE : 'PHASE';
PLUGIN : 'PLUGIN';
PLUGIN_DIR : 'PLUGIN_DIR';
PLUGINS : 'PLUGINS';
PORT : 'PORT';
PRECEDES : 'PRECEDES';
PRECEDING : 'PRECEDING';
PREPARE : 'PREPARE';
PRESERVE : 'PRESERVE';
PREV : 'PREV';
PROCESSLIST : 'PROCESSLIST';
PROFILE : 'PROFILE';
PROFILES : 'PROFILES';
PROXY : 'PROXY';
QUERY : 'QUERY';
QUICK : 'QUICK';
REBUILD : 'REBUILD';
RECOVER : 'RECOVER';
RECURSIVE : 'RECURSIVE';
REDO_BUFFER_SIZE : 'REDO_BUFFER_SIZE';
REDUNDANT : 'REDUNDANT';
RELAY : 'RELAY';
RELAY_LOG_FILE : 'RELAY_LOG_FILE';
RELAY_LOG_POS : 'RELAY_LOG_POS';
RELAYLOG : 'RELAYLOG';
REMOVE : 'REMOVE';
REORGANIZE : 'REORGANIZE';
REPAIR : 'REPAIR';
REPLICATE_DO_DB : 'REPLICATE_DO_DB';
REPLICATE_DO_TABLE : 'REPLICATE_DO_TABLE';
REPLICATE_IGNORE_DB : 'REPLICATE_IGNORE_DB';
REPLICATE_IGNORE_TABLE : 'REPLICATE_IGNORE_TABLE';
REPLICATE_REWRITE_DB : 'REPLICATE_REWRITE_DB';
REPLICATE_WILD_DO_TABLE : 'REPLICATE_WILD_DO_TABLE';
REPLICATE_WILD_IGNORE_TABLE : 'REPLICATE_WILD_IGNORE_TABLE';
REPLICATION : 'REPLICATION';
RESET : 'RESET';
RESTART : 'RESTART';
RESUME : 'RESUME';
RETURNED_SQLSTATE : 'RETURNED_SQLSTATE';
RETURNING : 'RETURNING';
RETURNS : 'RETURNS';
REUSE : 'REUSE';
ROLE : 'ROLE';
ROLLBACK : 'ROLLBACK';
ROLLUP : 'ROLLUP';
ROTATE : 'ROTATE';
ROW : 'ROW';
ROWS : 'ROWS';
ROW_FORMAT : 'ROW_FORMAT';
RTREE : 'RTREE';
SAVEPOINT : 'SAVEPOINT';
SCHEDULE : 'SCHEDULE';
SECURITY : 'SECURITY';
SEQUENCE : 'SEQUENCE';
SERVER : 'SERVER';
SESSION : 'SESSION';
SHARE : 'SHARE';
SHARED : 'SHARED';
SIGNED : 'SIGNED';
SIMPLE : 'SIMPLE';
SLAVE : 'SLAVE';
SLOW : 'SLOW';
SNAPSHOT : 'SNAPSHOT';
SOCKET : 'SOCKET';
SOME : 'SOME';
SONAME : 'SONAME';
SOUNDS : 'SOUNDS';
SOURCE : 'SOURCE';
SQL_AFTER_GTIDS : 'SQL_AFTER_GTIDS';
SQL_AFTER_MTS_GAPS : 'SQL_AFTER_MTS_GAPS';
SQL_BEFORE_GTIDS : 'SQL_BEFORE_GTIDS';
SQL_BUFFER_RESULT : 'SQL_BUFFER_RESULT';
SQL_CACHE : 'SQL_CACHE';
SQL_NO_CACHE : 'SQL_NO_CACHE';
SQL_THREAD : 'SQL_THREAD';
START : 'START';
STARTS : 'STARTS';
STATS_AUTO_RECALC : 'STATS_AUTO_RECALC';
STATS_PERSISTENT : 'STATS_PERSISTENT';
STATS_SAMPLE_PAGES : 'STATS_SAMPLE_PAGES';
STATUS : 'STATUS';
STOP : 'STOP';
STORAGE : 'STORAGE';
STORED : 'STORED';
STRING : 'STRING';
SUBCLASS_ORIGIN : 'SUBCLASS_ORIGIN';
SUBJECT : 'SUBJECT';
SUBPARTITION : 'SUBPARTITION';
SUBPARTITIONS : 'SUBPARTITIONS';
SUSPEND : 'SUSPEND';
SWAPS : 'SWAPS';
SWITCHES : 'SWITCHES';
TABLE_NAME : 'TABLE_NAME';
TABLESPACE : 'TABLESPACE';
TABLE_TYPE : 'TABLE_TYPE';
TEMPORARY : 'TEMPORARY';
TEMPTABLE : 'TEMPTABLE';
THAN : 'THAN';
TRADITIONAL : 'TRADITIONAL';
TRANSACTION : 'TRANSACTION';
TRANSACTIONAL : 'TRANSACTIONAL';
TRIGGERS : 'TRIGGERS';
TRUNCATE : 'TRUNCATE';
UNBOUNDED : 'UNBOUNDED';
UNDEFINED : 'UNDEFINED';
UNDOFILE : 'UNDOFILE';
UNDO_BUFFER_SIZE : 'UNDO_BUFFER_SIZE';
UNINSTALL : 'UNINSTALL';
UNKNOWN : 'UNKNOWN';
UNTIL : 'UNTIL';
UPGRADE : 'UPGRADE';
USER : 'USER';
USE_FRM : 'USE_FRM';
USER_RESOURCES : 'USER_RESOURCES';
VALIDATION : 'VALIDATION';
VALUE : 'VALUE';
VARIABLES : 'VARIABLES';
VIEW : 'VIEW';
VIRTUAL : 'VIRTUAL';
VISIBLE : 'VISIBLE';
WAIT : 'WAIT';
WARNINGS : 'WARNINGS';
WINDOW : 'WINDOW';
WITHOUT : 'WITHOUT';
WORK : 'WORK';
WRAPPER : 'WRAPPER';
X509 : 'X509';
XA : 'XA';
XML : 'XML';
YES : 'YES';
// Date format Keywords
EUR : 'EUR';
USA : 'USA';
JIS : 'JIS';
ISO : 'ISO';
INTERNAL : 'INTERNAL';
// Interval type Keywords
QUARTER : 'QUARTER';
MONTH : 'MONTH';
DAY : 'DAY';
HOUR : 'HOUR';
MINUTE : 'MINUTE';
WEEK : 'WEEK';
SECOND : 'SECOND';
MICROSECOND : 'MICROSECOND';
// Azure Database for MySQL Single Server instance:
FIREWALL_RULES: 'FIREWALL_RULES';
// PRIVILEGES
ADMIN : 'ADMIN';
APPLICATION_PASSWORD_ADMIN : 'APPLICATION_PASSWORD_ADMIN';
AUDIT_ABORT_EXEMPT : 'AUDIT_ABORT_EXEMPT';
AUDIT_ADMIN : 'AUDIT_ADMIN';
AUTHENTICATION_POLICY_ADMIN : 'AUTHENTICATION_POLICY_ADMIN';
BACKUP_ADMIN : 'BACKUP_ADMIN';
BINLOG_ADMIN : 'BINLOG_ADMIN';
BINLOG_ENCRYPTION_ADMIN : 'BINLOG_ENCRYPTION_ADMIN';
CLONE_ADMIN : 'CLONE_ADMIN';
CONNECTION_ADMIN : 'CONNECTION_ADMIN';
ENCRYPTION_KEY_ADMIN : 'ENCRYPTION_KEY_ADMIN';
EXECUTE : 'EXECUTE';
FILE : 'FILE';
FIREWALL_ADMIN : 'FIREWALL_ADMIN';
FIREWALL_EXEMPT : 'FIREWALL_EXEMPT';
FIREWALL_USER : 'FIREWALL_USER';
FLUSH_OPTIMIZER_COSTS : 'FLUSH_OPTIMIZER_COSTS';
FLUSH_STATUS : 'FLUSH_STATUS';
FLUSH_TABLES : 'FLUSH_TABLES';
FLUSH_USER_RESOURCES : 'FLUSH_USER_RESOURCES';
GROUP_REPLICATION_ADMIN : 'GROUP_REPLICATION_ADMIN';
INNODB_REDO_LOG_ARCHIVE : 'INNODB_REDO_LOG_ARCHIVE';
INNODB_REDO_LOG_ENABLE : 'INNODB_REDO_LOG_ENABLE';
INVOKE : 'INVOKE';
LAMBDA : 'LAMBDA';
NDB_STORED_USER : 'NDB_STORED_USER';
PASSWORDLESS_USER_ADMIN : 'PASSWORDLESS_USER_ADMIN';
PERSIST_RO_VARIABLES_ADMIN : 'PERSIST_RO_VARIABLES_ADMIN';
PRIVILEGES : 'PRIVILEGES';
PROCESS : 'PROCESS';
RELOAD : 'RELOAD';
REPLICATION_APPLIER : 'REPLICATION_APPLIER';
REPLICATION_SLAVE_ADMIN : 'REPLICATION_SLAVE_ADMIN';
RESOURCE_GROUP_ADMIN : 'RESOURCE_GROUP_ADMIN';
RESOURCE_GROUP_USER : 'RESOURCE_GROUP_USER';
ROLE_ADMIN : 'ROLE_ADMIN';
ROUTINE : 'ROUTINE';
S3 : 'S3';
SERVICE_CONNECTION_ADMIN : 'SERVICE_CONNECTION_ADMIN';
SESSION_VARIABLES_ADMIN : QUOTE_SYMB? 'SESSION_VARIABLES_ADMIN' QUOTE_SYMB?;
SET_USER_ID : 'SET_USER_ID';
SHOW_ROUTINE : 'SHOW_ROUTINE';
SHUTDOWN : 'SHUTDOWN';
SUPER : 'SUPER';
SYSTEM_VARIABLES_ADMIN : 'SYSTEM_VARIABLES_ADMIN';
TABLES : 'TABLES';
TABLE_ENCRYPTION_ADMIN : 'TABLE_ENCRYPTION_ADMIN';
VERSION_TOKEN_ADMIN : 'VERSION_TOKEN_ADMIN';
XA_RECOVER_ADMIN : 'XA_RECOVER_ADMIN';
// Charsets
ARMSCII8 : 'ARMSCII8';
ASCII : 'ASCII';
BIG5 : 'BIG5';
CP1250 : 'CP1250';
CP1251 : 'CP1251';
CP1256 : 'CP1256';
CP1257 : 'CP1257';
CP850 : 'CP850';
CP852 : 'CP852';
CP866 : 'CP866';
CP932 : 'CP932';
DEC8 : 'DEC8';
EUCJPMS : 'EUCJPMS';
EUCKR : 'EUCKR';
GB18030 : 'GB18030';
GB2312 : 'GB2312';
GBK : 'GBK';
GEOSTD8 : 'GEOSTD8';
GREEK : 'GREEK';
HEBREW : 'HEBREW';
HP8 : 'HP8';
KEYBCS2 : 'KEYBCS2';
KOI8R : 'KOI8R';
KOI8U : 'KOI8U';
LATIN1 : 'LATIN1';
LATIN2 : 'LATIN2';
LATIN5 : 'LATIN5';
LATIN7 : 'LATIN7';
MACCE : 'MACCE';
MACROMAN : 'MACROMAN';
SJIS : 'SJIS';
SWE7 : 'SWE7';
TIS620 : 'TIS620';
UCS2 : 'UCS2';
UJIS : 'UJIS';
UTF16 : 'UTF16';
UTF16LE : 'UTF16LE';
UTF32 : 'UTF32';
UTF8 : 'UTF8';
UTF8MB3 : 'UTF8MB3';
UTF8MB4 : 'UTF8MB4';
// DB Engines
ARCHIVE : 'ARCHIVE';
BLACKHOLE : 'BLACKHOLE';
CSV : 'CSV';
FEDERATED : 'FEDERATED';
INNODB : 'INNODB';
MEMORY : 'MEMORY';
MRG_MYISAM : 'MRG_MYISAM';
MYISAM : 'MYISAM';
NDB : 'NDB';
NDBCLUSTER : 'NDBCLUSTER';
PERFORMANCE_SCHEMA : 'PERFORMANCE_SCHEMA';
TOKUDB : 'TOKUDB';
// Transaction Levels
REPEATABLE : 'REPEATABLE';
COMMITTED : 'COMMITTED';
UNCOMMITTED : 'UNCOMMITTED';
SERIALIZABLE : 'SERIALIZABLE';
// Spatial data types
GEOMETRYCOLLECTION : 'GEOMETRYCOLLECTION';
GEOMCOLLECTION : 'GEOMCOLLECTION';
GEOMETRY : 'GEOMETRY';
LINESTRING : 'LINESTRING';
MULTILINESTRING : 'MULTILINESTRING';
MULTIPOINT : 'MULTIPOINT';
MULTIPOLYGON : 'MULTIPOLYGON';
POINT : 'POINT';
POLYGON : 'POLYGON';
// Common function names
ABS : 'ABS';
ACOS : 'ACOS';
ADDDATE : 'ADDDATE';
ADDTIME : 'ADDTIME';
AES_DECRYPT : 'AES_DECRYPT';
AES_ENCRYPT : 'AES_ENCRYPT';
AREA : 'AREA';
ASBINARY : 'ASBINARY';
ASIN : 'ASIN';
ASTEXT : 'ASTEXT';
ASWKB : 'ASWKB';
ASWKT : 'ASWKT';
ASYMMETRIC_DECRYPT : 'ASYMMETRIC_DECRYPT';
ASYMMETRIC_DERIVE : 'ASYMMETRIC_DERIVE';
ASYMMETRIC_ENCRYPT : 'ASYMMETRIC_ENCRYPT';
ASYMMETRIC_SIGN : 'ASYMMETRIC_SIGN';
ASYMMETRIC_VERIFY : 'ASYMMETRIC_VERIFY';
ATAN : 'ATAN';
ATAN2 : 'ATAN2';
BENCHMARK : 'BENCHMARK';
BIN : 'BIN';
BIT_COUNT : 'BIT_COUNT';
BIT_LENGTH : 'BIT_LENGTH';
BUFFER : 'BUFFER';
CATALOG_NAME : 'CATALOG_NAME';
CEIL : 'CEIL';
CEILING : 'CEILING';
CENTROID : 'CENTROID';
CHARACTER_LENGTH : 'CHARACTER_LENGTH';
CHARSET : 'CHARSET';
CHAR_LENGTH : 'CHAR_LENGTH';
COERCIBILITY : 'COERCIBILITY';
COLLATION : 'COLLATION';
COMPRESS : 'COMPRESS';
CONCAT : 'CONCAT';
CONCAT_WS : 'CONCAT_WS';
CONNECTION_ID : 'CONNECTION_ID';
CONV : 'CONV';
CONVERT_TZ : 'CONVERT_TZ';
COS : 'COS';
COT : 'COT';
CRC32 : 'CRC32';
CREATE_ASYMMETRIC_PRIV_KEY : 'CREATE_ASYMMETRIC_PRIV_KEY';
CREATE_ASYMMETRIC_PUB_KEY : 'CREATE_ASYMMETRIC_PUB_KEY';
CREATE_DH_PARAMETERS : 'CREATE_DH_PARAMETERS';
CREATE_DIGEST : 'CREATE_DIGEST';
CROSSES : 'CROSSES';
DATEDIFF : 'DATEDIFF';
DATE_FORMAT : 'DATE_FORMAT';
DAYNAME : 'DAYNAME';
DAYOFMONTH : 'DAYOFMONTH';
DAYOFWEEK : 'DAYOFWEEK';
DAYOFYEAR : 'DAYOFYEAR';
DECODE : 'DECODE';
DEGREES : 'DEGREES';
DES_DECRYPT : 'DES_DECRYPT';
DES_ENCRYPT : 'DES_ENCRYPT';
DIMENSION : 'DIMENSION';
DISJOINT : 'DISJOINT';
DISTANCE : 'DISTANCE';
ELT : 'ELT';
ENCODE : 'ENCODE';
ENCRYPT : 'ENCRYPT';
ENDPOINT : 'ENDPOINT';
ENGINE_ATTRIBUTE : 'ENGINE_ATTRIBUTE';
ENVELOPE : 'ENVELOPE';
EQUALS : 'EQUALS';
EXP : 'EXP';
EXPORT_SET : 'EXPORT_SET';
EXTERIORRING : 'EXTERIORRING';
EXTRACTVALUE : 'EXTRACTVALUE';
FIELD : 'FIELD';
FIND_IN_SET : 'FIND_IN_SET';
FLOOR : 'FLOOR';
FORMAT : 'FORMAT';
FOUND_ROWS : 'FOUND_ROWS';
FROM_BASE64 : 'FROM_BASE64';
FROM_DAYS : 'FROM_DAYS';
FROM_UNIXTIME : 'FROM_UNIXTIME';
GEOMCOLLFROMTEXT : 'GEOMCOLLFROMTEXT';
GEOMCOLLFROMWKB : 'GEOMCOLLFROMWKB';
GEOMETRYCOLLECTIONFROMTEXT : 'GEOMETRYCOLLECTIONFROMTEXT';
GEOMETRYCOLLECTIONFROMWKB : 'GEOMETRYCOLLECTIONFROMWKB';
GEOMETRYFROMTEXT : 'GEOMETRYFROMTEXT';
GEOMETRYFROMWKB : 'GEOMETRYFROMWKB';
GEOMETRYN : 'GEOMETRYN';
GEOMETRYTYPE : 'GEOMETRYTYPE';
GEOMFROMTEXT : 'GEOMFROMTEXT';
GEOMFROMWKB : 'GEOMFROMWKB';
GET_FORMAT : 'GET_FORMAT';
GET_LOCK : 'GET_LOCK';
GLENGTH : 'GLENGTH';
GREATEST : 'GREATEST';
GTID_SUBSET : 'GTID_SUBSET';
GTID_SUBTRACT : 'GTID_SUBTRACT';
HEX : 'HEX';
IFNULL : 'IFNULL';
INET6_ATON : 'INET6_ATON';
INET6_NTOA : 'INET6_NTOA';
INET_ATON : 'INET_ATON';
INET_NTOA : 'INET_NTOA';
INSTR : 'INSTR';
INTERIORRINGN : 'INTERIORRINGN';
INTERSECTS : 'INTERSECTS';
ISCLOSED : 'ISCLOSED';
ISEMPTY : 'ISEMPTY';
ISNULL : 'ISNULL';
ISSIMPLE : 'ISSIMPLE';
IS_FREE_LOCK : 'IS_FREE_LOCK';
IS_IPV4 : 'IS_IPV4';
IS_IPV4_COMPAT : 'IS_IPV4_COMPAT';
IS_IPV4_MAPPED : 'IS_IPV4_MAPPED';
IS_IPV6 : 'IS_IPV6';
IS_USED_LOCK : 'IS_USED_LOCK';
LAST_INSERT_ID : 'LAST_INSERT_ID';
LCASE : 'LCASE';
LEAST : 'LEAST';
LENGTH : 'LENGTH';
LINEFROMTEXT : 'LINEFROMTEXT';
LINEFROMWKB : 'LINEFROMWKB';
LINESTRINGFROMTEXT : 'LINESTRINGFROMTEXT';
LINESTRINGFROMWKB : 'LINESTRINGFROMWKB';
LN : 'LN';
LOAD_FILE : 'LOAD_FILE';
LOCATE : 'LOCATE';
LOG : 'LOG';
LOG10 : 'LOG10';
LOG2 : 'LOG2';
LOWER : 'LOWER';
LPAD : 'LPAD';
LTRIM : 'LTRIM';
MAKEDATE : 'MAKEDATE';
MAKETIME : 'MAKETIME';
MAKE_SET : 'MAKE_SET';
MASTER_POS_WAIT : 'MASTER_POS_WAIT';
MBRCONTAINS : 'MBRCONTAINS';
MBRDISJOINT : 'MBRDISJOINT';
MBREQUAL : 'MBREQUAL';
MBRINTERSECTS : 'MBRINTERSECTS';
MBROVERLAPS : 'MBROVERLAPS';
MBRTOUCHES : 'MBRTOUCHES';
MBRWITHIN : 'MBRWITHIN';
MD5 : 'MD5';
MLINEFROMTEXT : 'MLINEFROMTEXT';
MLINEFROMWKB : 'MLINEFROMWKB';
MONTHNAME : 'MONTHNAME';
MPOINTFROMTEXT : 'MPOINTFROMTEXT';
MPOINTFROMWKB : 'MPOINTFROMWKB';
MPOLYFROMTEXT : 'MPOLYFROMTEXT';
MPOLYFROMWKB : 'MPOLYFROMWKB';
MULTILINESTRINGFROMTEXT : 'MULTILINESTRINGFROMTEXT';
MULTILINESTRINGFROMWKB : 'MULTILINESTRINGFROMWKB';
MULTIPOINTFROMTEXT : 'MULTIPOINTFROMTEXT';
MULTIPOINTFROMWKB : 'MULTIPOINTFROMWKB';
MULTIPOLYGONFROMTEXT : 'MULTIPOLYGONFROMTEXT';
MULTIPOLYGONFROMWKB : 'MULTIPOLYGONFROMWKB';
NAME_CONST : 'NAME_CONST';
NULLIF : 'NULLIF';
NUMGEOMETRIES : 'NUMGEOMETRIES';
NUMINTERIORRINGS : 'NUMINTERIORRINGS';
NUMPOINTS : 'NUMPOINTS';
OCT : 'OCT';
OCTET_LENGTH : 'OCTET_LENGTH';
ORD : 'ORD';
OVERLAPS : 'OVERLAPS';
PERCONA_SEQUENCE_TABLE : 'PERCONA_SEQUENCE_TABLE';
PERIOD_ADD : 'PERIOD_ADD';
PERIOD_DIFF : 'PERIOD_DIFF';
PI : 'PI';
POINTFROMTEXT : 'POINTFROMTEXT';
POINTFROMWKB : 'POINTFROMWKB';
POINTN : 'POINTN';
POLYFROMTEXT : 'POLYFROMTEXT';
POLYFROMWKB : 'POLYFROMWKB';
POLYGONFROMTEXT : 'POLYGONFROMTEXT';
POLYGONFROMWKB : 'POLYGONFROMWKB';
POW : 'POW';
POWER : 'POWER';
QUOTE : 'QUOTE';
RADIANS : 'RADIANS';
RAND : 'RAND';
RANDOM : 'RANDOM';
RANDOM_BYTES : 'RANDOM_BYTES';
RELEASE_LOCK : 'RELEASE_LOCK';
REVERSE : 'REVERSE';
ROUND : 'ROUND';
ROW_COUNT : 'ROW_COUNT';
RPAD : 'RPAD';
RTRIM : 'RTRIM';
SEC_TO_TIME : 'SEC_TO_TIME';
SECONDARY_ENGINE : 'SECONDARY_ENGINE';
SECONDARY_ENGINE_ATTRIBUTE : 'SECONDARY_ENGINE_ATTRIBUTE';
SEQUENCE_TABLE : 'SEQUENCE_TABLE';
SESSION_USER : 'SESSION_USER';
SHA : 'SHA';
SHA1 : 'SHA1';
SHA2 : 'SHA2';
SCHEMA_NAME : 'SCHEMA_NAME';
SIGN : 'SIGN';
SIN : 'SIN';
SLEEP : 'SLEEP';
SOUNDEX : 'SOUNDEX';
SQL_THREAD_WAIT_AFTER_GTIDS : 'SQL_THREAD_WAIT_AFTER_GTIDS';
SQRT : 'SQRT';
SRID : 'SRID';
STARTPOINT : 'STARTPOINT';
STRCMP : 'STRCMP';
STR_TO_DATE : 'STR_TO_DATE';
ST_AREA : 'ST_AREA';
ST_ASBINARY : 'ST_ASBINARY';
ST_ASTEXT : 'ST_ASTEXT';
ST_ASWKB : 'ST_ASWKB';
ST_ASWKT : 'ST_ASWKT';
ST_BUFFER : 'ST_BUFFER';
ST_CENTROID : 'ST_CENTROID';
ST_CONTAINS : 'ST_CONTAINS';
ST_CROSSES : 'ST_CROSSES';
ST_DIFFERENCE : 'ST_DIFFERENCE';
ST_DIMENSION : 'ST_DIMENSION';
ST_DISJOINT : 'ST_DISJOINT';
ST_DISTANCE : 'ST_DISTANCE';
ST_ENDPOINT : 'ST_ENDPOINT';
ST_ENVELOPE : 'ST_ENVELOPE';
ST_EQUALS : 'ST_EQUALS';
ST_EXTERIORRING : 'ST_EXTERIORRING';
ST_GEOMCOLLFROMTEXT : 'ST_GEOMCOLLFROMTEXT';
ST_GEOMCOLLFROMTXT : 'ST_GEOMCOLLFROMTXT';
ST_GEOMCOLLFROMWKB : 'ST_GEOMCOLLFROMWKB';
ST_GEOMETRYCOLLECTIONFROMTEXT : 'ST_GEOMETRYCOLLECTIONFROMTEXT';
ST_GEOMETRYCOLLECTIONFROMWKB : 'ST_GEOMETRYCOLLECTIONFROMWKB';
ST_GEOMETRYFROMTEXT : 'ST_GEOMETRYFROMTEXT';
ST_GEOMETRYFROMWKB : 'ST_GEOMETRYFROMWKB';
ST_GEOMETRYN : 'ST_GEOMETRYN';
ST_GEOMETRYTYPE : 'ST_GEOMETRYTYPE';
ST_GEOMFROMTEXT : 'ST_GEOMFROMTEXT';
ST_GEOMFROMWKB : 'ST_GEOMFROMWKB';
ST_INTERIORRINGN : 'ST_INTERIORRINGN';
ST_INTERSECTION : 'ST_INTERSECTION';
ST_INTERSECTS : 'ST_INTERSECTS';
ST_ISCLOSED : 'ST_ISCLOSED';
ST_ISEMPTY : 'ST_ISEMPTY';
ST_ISSIMPLE : 'ST_ISSIMPLE';
ST_LINEFROMTEXT : 'ST_LINEFROMTEXT';
ST_LINEFROMWKB : 'ST_LINEFROMWKB';
ST_LINESTRINGFROMTEXT : 'ST_LINESTRINGFROMTEXT';
ST_LINESTRINGFROMWKB : 'ST_LINESTRINGFROMWKB';
ST_NUMGEOMETRIES : 'ST_NUMGEOMETRIES';
ST_NUMINTERIORRING : 'ST_NUMINTERIORRING';
ST_NUMINTERIORRINGS : 'ST_NUMINTERIORRINGS';
ST_NUMPOINTS : 'ST_NUMPOINTS';
ST_OVERLAPS : 'ST_OVERLAPS';
ST_POINTFROMTEXT : 'ST_POINTFROMTEXT';
ST_POINTFROMWKB : 'ST_POINTFROMWKB';
ST_POINTN : 'ST_POINTN';
ST_POLYFROMTEXT : 'ST_POLYFROMTEXT';
ST_POLYFROMWKB : 'ST_POLYFROMWKB';
ST_POLYGONFROMTEXT : 'ST_POLYGONFROMTEXT';
ST_POLYGONFROMWKB : 'ST_POLYGONFROMWKB';
ST_SRID : 'ST_SRID';
ST_STARTPOINT : 'ST_STARTPOINT';
ST_SYMDIFFERENCE : 'ST_SYMDIFFERENCE';
ST_TOUCHES : 'ST_TOUCHES';
ST_UNION : 'ST_UNION';
ST_WITHIN : 'ST_WITHIN';
ST_X : 'ST_X';
ST_Y : 'ST_Y';
STRING_TO_VECTOR : 'STRING_TO_VECTOR';
SUBDATE : 'SUBDATE';
SUBSTRING_INDEX : 'SUBSTRING_INDEX';
SUBTIME : 'SUBTIME';
SYSTEM_USER : 'SYSTEM_USER';
TAN : 'TAN';
TELEMETRY_LOG_ADMIN : 'TELEMETRY_LOG_ADMIN';
TIMEDIFF : 'TIMEDIFF';
TIMESTAMPADD : 'TIMESTAMPADD';
TIMESTAMPDIFF : 'TIMESTAMPDIFF';
TIME_FORMAT : 'TIME_FORMAT';
TIME_TO_SEC : 'TIME_TO_SEC';
TOUCHES : 'TOUCHES';
TO_BASE64 : 'TO_BASE64';
TO_DAYS : 'TO_DAYS';
TO_SECONDS : 'TO_SECONDS';
TP_CONNECTION_ADMIN : 'TP_CONNECTION_ADMIN';
UCASE : 'UCASE';
UNCOMPRESS : 'UNCOMPRESS';
UNCOMPRESSED_LENGTH : 'UNCOMPRESSED_LENGTH';
UNHEX : 'UNHEX';
UNIX_TIMESTAMP : 'UNIX_TIMESTAMP';
UPDATEXML : 'UPDATEXML';
UPPER : 'UPPER';
UUID : 'UUID';
UUID_SHORT : 'UUID_SHORT';
VALIDATE_PASSWORD_STRENGTH : 'VALIDATE_PASSWORD_STRENGTH';
VECTOR_DIM : 'VECTOR_DIM';
VECTOR_TO_STRING : 'VECTOR_TO_STRING';
VERSION : 'VERSION';
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS : 'WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS';
WEEKDAY : 'WEEKDAY';
WEEKOFYEAR : 'WEEKOFYEAR';
WEIGHT_STRING : 'WEIGHT_STRING';
WITHIN : 'WITHIN';
YEARWEEK : 'YEARWEEK';
Y_FUNCTION : 'Y';
X_FUNCTION : 'X';
// Operators
// Operators. Assigns
VAR_ASSIGN : ':=';
PLUS_ASSIGN : '+=';
MINUS_ASSIGN : '-=';
MULT_ASSIGN : '*=';
DIV_ASSIGN : '/=';
MOD_ASSIGN : '%=';
AND_ASSIGN : '&=';
XOR_ASSIGN : '^=';
OR_ASSIGN : '|=';
// Operators. Arithmetics
STAR : '*';
DIVIDE : '/';
MODULE : '%';
PLUS : '+';
MINUS : '-';
DIV : 'DIV';
MOD : 'MOD';
// Operators. Comparation
EQUAL_SYMBOL : '=';
GREATER_SYMBOL : '>';
LESS_SYMBOL : '<';
EXCLAMATION_SYMBOL : '!';
// Operators. Bit
BIT_NOT_OP : '~';
BIT_OR_OP : '|';
BIT_AND_OP : '&';
BIT_XOR_OP : '^';
// Constructors symbols
DOT : '.';
LR_BRACKET : '(';
RR_BRACKET : ')';
COMMA : ',';
SEMI : ';';
AT_SIGN : '@';
ZERO_DECIMAL : '0';
ONE_DECIMAL : '1';
TWO_DECIMAL : '2';
SINGLE_QUOTE_SYMB : '\'';
DOUBLE_QUOTE_SYMB : '"';
REVERSE_QUOTE_SYMB : '`';
COLON_SYMB : ':';
fragment QUOTE_SYMB: SINGLE_QUOTE_SYMB | DOUBLE_QUOTE_SYMB | REVERSE_QUOTE_SYMB;
// Charsets
CHARSET_REVERSE_QOUTE_STRING: '`' CHARSET_NAME '`';
// File's sizes
FILESIZE_LITERAL: DEC_DIGIT+ ('K' | 'M' | 'G' | 'T');
// Literal Primitives
START_NATIONAL_STRING_LITERAL : 'N' SQUOTA_STRING;
STRING_LITERAL : DQUOTA_STRING | SQUOTA_STRING | BQUOTA_STRING;
DECIMAL_LITERAL : DEC_DIGIT+;
HEXADECIMAL_LITERAL : 'X' '\'' (HEX_DIGIT HEX_DIGIT)+ '\'' | '0X' HEX_DIGIT+;
REAL_LITERAL:
(DEC_DIGIT+)? '.' DEC_DIGIT*
| DEC_DIGIT+ '.' EXPONENT_NUM_PART
| (DEC_DIGIT+)? '.' (DEC_DIGIT+ EXPONENT_NUM_PART)
| DEC_DIGIT+ EXPONENT_NUM_PART
;
NULL_SPEC_LITERAL : '\\' 'N';
BIT_STRING : BIT_STRING_L;
STRING_CHARSET_NAME : '_' CHARSET_NAME;
// Hack for dotID
// Prevent recognize string: .123somelatin AS ((.123), FLOAT_LITERAL), ((somelatin), ID)
// it must recoginze: .123somelatin AS ((.), DOT), (123somelatin, ID)
DOT_ID: '.' ID_LITERAL;
// Identifiers
ID: ID_LITERAL;
// DOUBLE_QUOTE_ID: '"' ~'"'+ '"';
REVERSE_QUOTE_ID : BQUOTA_STRING;
HOST_IP_ADDRESS : (AT_SIGN IP_ADDRESS);
LOCAL_ID : AT_SIGN ( STRING_LITERAL | [A-Z0-9._$\u0080-\uFFFF]+);
GLOBAL_ID : AT_SIGN AT_SIGN ( [A-Z0-9._$\u0080-\uFFFF]+ | BQUOTA_STRING);
// Fragments for Literal primitives
fragment CHARSET_NAME:
ARMSCII8
| ASCII
| BIG5
| BINARY
| CP1250
| CP1251
| CP1256
| CP1257
| CP850
| CP852
| CP866
| CP932
| DEC8
| EUCJPMS
| EUCKR
| GB2312
| GBK
| GEOSTD8
| GREEK
| HEBREW
| HP8
| KEYBCS2
| KOI8R
| KOI8U
| LATIN1
| LATIN2
| LATIN5
| LATIN7
| MACCE
| MACROMAN
| SJIS
| SWE7
| TIS620
| UCS2
| UJIS
| UTF16
| UTF16LE
| UTF32
| UTF8
| UTF8MB3
| UTF8MB4
;
fragment EXPONENT_NUM_PART : 'E' [-+]? DEC_DIGIT+;
fragment ID_LITERAL : [A-Z_$0-9\u0080-\uFFFF]*? [A-Z_$\u0080-\uFFFF]+? [A-Z_$0-9\u0080-\uFFFF]*;
fragment DQUOTA_STRING : '"' ( '\\' . | '""' | ~('"' | '\\'))* '"';
fragment SQUOTA_STRING : '\'' ('\\' . | '\'\'' | ~('\'' | '\\'))* '\'';
fragment BQUOTA_STRING : '`' ( ~'`' | '``')* '`';
fragment HEX_DIGIT : [0-9A-F];
fragment DEC_DIGIT : [0-9];
fragment BIT_STRING_L : 'B' '\'' [01]+ '\'';
fragment IP_ADDRESS : [0-9]+ '.' [0-9.]+ | [0-9A-F]* ':' [0-9A-F]* ':' [0-9A-F:]+;
// Last tokens must generate Errors
ERROR_RECONGNIGION: . -> channel(ERRORCHANNEL);
================================================
FILE: superior-mysql-parser/src/main/antlr4/io/github/melin/superior/parser/mysql/antlr4/MySqlParser.g4
================================================
/*
MySQL (Positive Technologies) grammar
The MIT License (MIT).
Copyright (c) 2015-2017, Ivan Kochurkin (kvanttt@gmail.com), Positive Technologies.
Copyright (c) 2017, Ivan Khudyashev (IHudyashov@ptsecurity.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false
// $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging
parser grammar MySqlParser;
options {
tokenVocab = MySqlLexer;
}
// Top Level Description
root
: sqlStatements? (MINUS MINUS)? EOF
;
sqlStatements
: (sqlStatement (MINUS MINUS)? SEMI? | emptyStatement_)* (
sqlStatement ((MINUS MINUS)? SEMI)?
| emptyStatement_
)
;
sqlStatement
: ddlStatement
| withStatement? dmlStatement
| transactionStatement
| replicationStatement
| preparedStatement
| administrationStatement
| utilityStatement
;
emptyStatement_
: SEMI
;
ddlStatement
: createDatabase
| createEvent
| createIndex
| createLogfileGroup
| createProcedure
| createFunction
| createServer
| createTable
| createTablespaceInnodb
| createTablespaceNdb
| createTrigger
| createView
| createRole
| alterDatabase
| alterEvent
| alterFunction
| alterInstance
| alterLogfileGroup
| alterProcedure
| alterServer
| alterTable
| alterTablespace
| alterView
| dropDatabase
| dropEvent
| dropIndex
| dropLogfileGroup
| dropProcedure
| dropFunction
| dropServer
| dropTable
| dropTablespace
| dropTrigger
| dropView
| dropRole
| setRole
| renameTable
| truncateTable
;
dmlStatement
: selectStatement
| insertStatement
| updateStatement
| deleteStatement
| replaceStatement
| callStatement
| loadDataStatement
| loadXmlStatement
| doStatement
| handlerStatement
| valuesStatement
| tableStatement
;
transactionStatement
: startTransaction
| beginWork
| commitWork
| rollbackWork
| savepointStatement
| rollbackStatement
| releaseStatement
| lockTables
| unlockTables
;
replicationStatement
: changeMaster
| changeReplicationFilter
| purgeBinaryLogs
| resetMaster
| resetSlave
| startSlave
| stopSlave
| startGroupReplication
| stopGroupReplication
| xaStartTransaction
| xaEndTransaction
| xaPrepareStatement
| xaCommitWork
| xaRollbackWork
| xaRecoverWork
;
preparedStatement
: prepareStatement
| executeStatement
| deallocatePrepare
;
// remark: NOT INCLUDED IN sqlStatement, but include in body
// of routine's statements
compoundStatement
: blockStatement
| caseStatement
| ifStatement
| leaveStatement
| loopStatement
| repeatStatement
| whileStatement
| iterateStatement
| returnStatement
| cursorStatement
;
administrationStatement
: alterUser
| createUser
| dropUser
| grantStatement
| grantProxy
| renameUser
| revokeStatement
| revokeProxy
| analyzeTable
| checkTable
| checksumTable
| optimizeTable
| repairTable
| createUdfunction
| installPlugin
| uninstallPlugin
| setStatement
| showStatement
| binlogStatement
| cacheIndexStatement
| flushStatement
| killStatement
| loadIndexIntoCache
| resetStatement
| shutdownStatement
;
utilityStatement
: simpleDescribeStatement
| fullDescribeStatement
| helpStatement
| useStatement
| signalStatement
| resignalStatement
| diagnosticsStatement
;
// Data Definition Language
// Create statements
createDatabase
: CREATE dbFormat = (DATABASE | SCHEMA) ifNotExists? uid createDatabaseOption*
;
createEvent
: CREATE ownerStatement? EVENT ifNotExists? fullId ON SCHEDULE scheduleExpression (
ON COMPLETION NOT? PRESERVE
)? enableType? (COMMENT STRING_LITERAL)? DO routineBody
;
createIndex
: CREATE intimeAction = (ONLINE | OFFLINE)? indexCategory = (UNIQUE | FULLTEXT | SPATIAL)? INDEX uid indexType? ON tableName indexColumnNames
indexOption* (
ALGORITHM EQUAL_SYMBOL? algType = (DEFAULT | INPLACE | COPY)
| LOCK EQUAL_SYMBOL? lockType = (DEFAULT | NONE | SHARED | EXCLUSIVE)
)*
;
createLogfileGroup
: CREATE LOGFILE GROUP uid ADD UNDOFILE undoFile = STRING_LITERAL (
INITIAL_SIZE '='? initSize = fileSizeLiteral
)? (UNDO_BUFFER_SIZE '='? undoSize = fileSizeLiteral)? (
REDO_BUFFER_SIZE '='? redoSize = fileSizeLiteral
)? (NODEGROUP '='? uid)? WAIT? (COMMENT '='? comment = STRING_LITERAL)? ENGINE '='? engineName
;
createProcedure
: CREATE ownerStatement? PROCEDURE ifNotExists? fullId '(' procedureParameter? (',' procedureParameter)* ')' routineOption* routineBody
;
createFunction
: CREATE ownerStatement? AGGREGATE? FUNCTION ifNotExists? fullId '(' functionParameter? (
',' functionParameter
)* ')' RETURNS dataType routineOption* (routineBody | returnStatement)
;
createRole
: CREATE ROLE ifNotExists? roleName (',' roleName)*
;
createServer
: CREATE SERVER uid FOREIGN DATA WRAPPER wrapperName = (MYSQL | STRING_LITERAL) OPTIONS '(' serverOption (
',' serverOption
)* ')'
;
createTable
: CREATE TEMPORARY? TABLE ifNotExists? tableName (
LIKE tableName
| '(' LIKE parenthesisTable = tableName ')'
) # copyCreateTable
| CREATE TEMPORARY? TABLE ifNotExists? tableName createDefinitions? (
tableOption (','? tableOption)*
)? partitionDefinitions? keyViolate = (IGNORE | REPLACE)? AS? selectStatement # queryCreateTable
| CREATE TEMPORARY? TABLE ifNotExists? tableName createDefinitions (
tableOption (','? tableOption)*
)? partitionDefinitions? # columnCreateTable
;
createTablespaceInnodb
: CREATE TABLESPACE uid ADD DATAFILE datafile = STRING_LITERAL (
FILE_BLOCK_SIZE '=' fileBlockSize = fileSizeLiteral
)? (ENGINE '='? engineName)?
;
createTablespaceNdb
: CREATE TABLESPACE uid ADD DATAFILE datafile = STRING_LITERAL USE LOGFILE GROUP uid (
EXTENT_SIZE '='? extentSize = fileSizeLiteral
)? (INITIAL_SIZE '='? initialSize = fileSizeLiteral)? (
AUTOEXTEND_SIZE '='? autoextendSize = fileSizeLiteral
)? (MAX_SIZE '='? maxSize = fileSizeLiteral)? (NODEGROUP '='? uid)? WAIT? (
COMMENT '='? comment = STRING_LITERAL
)? ENGINE '='? engineName
;
createTrigger
: CREATE ownerStatement? TRIGGER ifNotExists? thisTrigger = fullId triggerTime = (
BEFORE
| AFTER
) triggerEvent = (INSERT | UPDATE | DELETE) ON tableName FOR EACH ROW (
triggerPlace = (FOLLOWS | PRECEDES) otherTrigger = fullId
)? routineBody
;
withClause
: WITH RECURSIVE? commonTableExpressions
;
commonTableExpressions
: cteName ('(' cteColumnName (',' cteColumnName)* ')')? AS '(' dmlStatement ')' (
',' commonTableExpressions
)?
;
cteName
: uid
;
cteColumnName
: uid
;
createView
: CREATE orReplace? (ALGORITHM '=' algType = (UNDEFINED | MERGE | TEMPTABLE))? ownerStatement? (
SQL SECURITY secContext = (DEFINER | INVOKER)
)? VIEW fullId ('(' uidList ')')? AS (
'(' withClause? selectStatement ')'
| withClause? selectStatement (WITH checkOption = (CASCADED | LOCAL)? CHECK OPTION)?
)
;
// details
createDatabaseOption
: DEFAULT? charSet '='? (charsetName | DEFAULT)
| DEFAULT? COLLATE '='? collationName
| DEFAULT? ENCRYPTION '='? STRING_LITERAL
| READ ONLY '='? (DEFAULT | ZERO_DECIMAL | ONE_DECIMAL)
;
charSet
: CHARACTER SET
| CHARSET
| CHAR SET
;
currentUserExpression
: CURRENT_USER ('(' ')')?
;
ownerStatement
: DEFINER '=' (userName | currentUserExpression)
;
scheduleExpression
: AT timestampValue intervalExpr* # preciseSchedule
| EVERY (decimalLiteral | expression) intervalType (
STARTS startTimestamp = timestampValue (startIntervals += intervalExpr)*
)? (ENDS endTimestamp = timestampValue (endIntervals += intervalExpr)*)? # intervalSchedule
;
timestampValue
: CURRENT_TIMESTAMP
| stringLiteral
| decimalLiteral
| expression
;
intervalExpr
: '+' INTERVAL (decimalLiteral | expression) intervalType
;
intervalType
: intervalTypeBase
| YEAR
| YEAR_MONTH
| DAY_HOUR
| DAY_MINUTE
| DAY_SECOND
| HOUR_MINUTE
| HOUR_SECOND
| MINUTE_SECOND
| SECOND_MICROSECOND
| MINUTE_MICROSECOND
| HOUR_MICROSECOND
| DAY_MICROSECOND
;
enableType
: ENABLE
| DISABLE
| DISABLE ON SLAVE
;
indexType
: USING (BTREE | HASH)
;
indexOption
: KEY_BLOCK_SIZE EQUAL_SYMBOL? fileSizeLiteral
| indexType
| WITH PARSER uid
| COMMENT STRING_LITERAL
| (VISIBLE | INVISIBLE)
| ENGINE_ATTRIBUTE EQUAL_SYMBOL? STRING_LITERAL
| SECONDARY_ENGINE_ATTRIBUTE EQUAL_SYMBOL? STRING_LITERAL
;
procedureParameter
: direction = (IN | OUT | INOUT)? uid dataType
;
functionParameter
: uid dataType
;
routineOption
: COMMENT STRING_LITERAL # routineComment
| LANGUAGE SQL # routineLanguage
| NOT? DETERMINISTIC # routineBehavior
| ( CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA) # routineData
| SQL SECURITY context = (DEFINER | INVOKER) # routineSecurity
;
serverOption
: HOST STRING_LITERAL
| DATABASE STRING_LITERAL
| USER STRING_LITERAL
| PASSWORD STRING_LITERAL
| SOCKET STRING_LITERAL
| OWNER STRING_LITERAL
| PORT decimalLiteral
;
createDefinitions
: '(' createDefinition (',' createDefinition)* ')'
;
createDefinition
: fullColumnName columnDefinition # columnDeclaration
| tableConstraint NOT? ENFORCED? # constraintDeclaration
| indexColumnDefinition # indexDeclaration
;
columnDefinition
: dataType columnConstraint* NOT? ENFORCED?
;
columnConstraint
: nullNotnull # nullColumnConstraint
| DEFAULT defaultValue # defaultColumnConstraint
| VISIBLE # visibilityColumnConstraint
| INVISIBLE # invisibilityColumnConstraint
| (AUTO_INCREMENT | ON UPDATE currentTimestamp) # autoIncrementColumnConstraint
| PRIMARY? KEY # primaryKeyColumnConstraint
| CLUSTERING KEY # clusteringKeyColumnConstraint // Tokudb-specific only
| UNIQUE KEY? # uniqueKeyColumnConstraint
| COMMENT STRING_LITERAL # commentColumnConstraint
| COLUMN_FORMAT colformat = (FIXED | DYNAMIC | DEFAULT) # formatColumnConstraint
| STORAGE storageval = (DISK | MEMORY | DEFAULT) # storageColumnConstraint
| referenceDefinition # referenceColumnConstraint
| COLLATE collationName # collateColumnConstraint
| (GENERATED ALWAYS)? AS '(' expression ')' (VIRTUAL | STORED)? # generatedColumnConstraint
| SERIAL DEFAULT VALUE # serialDefaultColumnConstraint
| (CONSTRAINT name = uid?)? CHECK '(' expression ')' # checkColumnConstraint
;
tableConstraint
: (CONSTRAINT name = uid?)? PRIMARY KEY index = uid? indexType? indexColumnNames indexOption* # primaryKeyTableConstraint
| (CONSTRAINT name = uid?)? UNIQUE indexFormat = (INDEX | KEY)? index = uid? indexType? indexColumnNames indexOption* # uniqueKeyTableConstraint
| (CONSTRAINT name = uid?)? FOREIGN KEY index = uid? indexColumnNames referenceDefinition # foreignKeyTableConstraint
| (CONSTRAINT name = uid?)? CHECK '(' expression ')' # checkTableConstraint
| CLUSTERING KEY index = uid? indexColumnNames # clusteringKeyTableConstraint
// Tokudb-specific only
;
referenceDefinition
: REFERENCES tableName indexColumnNames? (MATCH matchType = (FULL | PARTIAL | SIMPLE))? referenceAction?
;
referenceAction
: ON DELETE onDelete = referenceControlType (ON UPDATE onUpdate = referenceControlType)?
| ON UPDATE onUpdate = referenceControlType (ON DELETE onDelete = referenceControlType)?
;
referenceControlType
: RESTRICT
| CASCADE
| SET NULL_LITERAL
| NO ACTION
| SET DEFAULT
;
indexColumnDefinition
: indexFormat = (INDEX | KEY) uid? indexType? indexColumnNames indexOption* # simpleIndexDeclaration
| (FULLTEXT | SPATIAL) indexFormat = (INDEX | KEY)? uid? indexColumnNames indexOption* # specialIndexDeclaration
;
tableOption
: ENGINE '='? engineName? # tableOptionEngine
| ENGINE_ATTRIBUTE '='? STRING_LITERAL # tableOptionEngineAttribute
| AUTOEXTEND_SIZE '='? decimalLiteral # tableOptionAutoextendSize
| AUTO_INCREMENT '='? decimalLiteral # tableOptionAutoIncrement
| AVG_ROW_LENGTH '='? decimalLiteral # tableOptionAverage
| DEFAULT? charSet '='? (charsetName | DEFAULT) # tableOptionCharset
| (CHECKSUM | PAGE_CHECKSUM) '='? boolValue = ('0' | '1') # tableOptionChecksum
| DEFAULT? COLLATE '='? collationName # tableOptionCollate
| COMMENT '='? STRING_LITERAL # tableOptionComment
| COMPRESSION '='? (STRING_LITERAL | ID) # tableOptionCompression
| CONNECTION '='? STRING_LITERAL # tableOptionConnection
| (DATA | INDEX) DIRECTORY '='? STRING_LITERAL # tableOptionDataDirectory
| DELAY_KEY_WRITE '='? boolValue = ('0' | '1') # tableOptionDelay
| ENCRYPTION '='? STRING_LITERAL # tableOptionEncryption
| (PAGE_COMPRESSED | STRING_LITERAL) '='? ('0' | '1') # tableOptionPageCompressed
| (PAGE_COMPRESSION_LEVEL | STRING_LITERAL) '='? decimalLiteral # tableOptionPageCompressionLevel
| ENCRYPTION_KEY_ID '='? decimalLiteral # tableOptionEncryptionKeyId
| INDEX DIRECTORY '='? STRING_LITERAL # tableOptionIndexDirectory
| INSERT_METHOD '='? insertMethod = (NO | FIRST | LAST) # tableOptionInsertMethod
| KEY_BLOCK_SIZE '='? fileSizeLiteral # tableOptionKeyBlockSize
| MAX_ROWS '='? decimalLiteral # tableOptionMaxRows
| MIN_ROWS '='? decimalLiteral # tableOptionMinRows
| PACK_KEYS '='? extBoolValue = ('0' | '1' | DEFAULT) # tableOptionPackKeys
| PASSWORD '='? STRING_LITERAL # tableOptionPassword
| ROW_FORMAT '='? rowFormat = (
DEFAULT
| DYNAMIC
| FIXED
| COMPRESSED
| REDUNDANT
| COMPACT
| ID
) # tableOptionRowFormat
| START TRANSACTION # tableOptionStartTransaction
| SECONDARY_ENGINE '='? (ID | STRING_LITERAL) # tableOptionSecondaryEngine
// HeatWave-specific only
| SECONDARY_ENGINE_ATTRIBUTE '='? STRING_LITERAL # tableOptionSecondaryEngineAttribute
| STATS_AUTO_RECALC '='? extBoolValue = (DEFAULT | '0' | '1') # tableOptionRecalculation
| STATS_PERSISTENT '='? extBoolValue = (DEFAULT | '0' | '1') # tableOptionPersistent
| STATS_SAMPLE_PAGES '='? (DEFAULT | decimalLiteral) # tableOptionSamplePage
| TABLESPACE uid tablespaceStorage? # tableOptionTablespace
| TABLE_TYPE '=' tableType # tableOptionTableType
| tablespaceStorage # tableOptionTablespace
| TRANSACTIONAL '='? ('0' | '1') # tableOptionTransactional
| UNION '='? '(' tables ')' # tableOptionUnion
;
tableType
: MYSQL
| ODBC
;
tablespaceStorage
: STORAGE (DISK | MEMORY | DEFAULT)
;
partitionDefinitions
: PARTITION BY partitionFunctionDefinition (PARTITIONS count = decimalLiteral)? (
SUBPARTITION BY subpartitionFunctionDefinition (SUBPARTITIONS subCount = decimalLiteral)?
)? ('(' partitionDefinition (',' partitionDefinition)* ')')?
;
partitionFunctionDefinition
: LINEAR? HASH '(' expression ')' # partitionFunctionHash
| LINEAR? KEY (ALGORITHM '=' algType = ('1' | '2'))? '(' uidList? ')' # partitionFunctionKey // Optional uidList for MySQL only
| RANGE ('(' expression ')' | COLUMNS '(' uidList ')') # partitionFunctionRange
| LIST ('(' expression ')' | COLUMNS '(' uidList ')') # partitionFunctionList
;
subpartitionFunctionDefinition
: LINEAR? HASH '(' expression ')' # subPartitionFunctionHash
| LINEAR? KEY (ALGORITHM '=' algType = ('1' | '2'))? '(' uidList ')' # subPartitionFunctionKey
;
partitionDefinition
: PARTITION uid VALUES LESS THAN '(' partitionDefinerAtom (',' partitionDefinerAtom)* ')' partitionOption* (
'(' subpartitionDefinition (',' subpartitionDefinition)* ')'
)? # partitionComparison
| PARTITION uid VALUES LESS THAN partitionDefinerAtom partitionOption* (
'(' subpartitionDefinition (',' subpartitionDefinition)* ')'
)? # partitionComparison
| PARTITION uid VALUES IN '(' partitionDefinerAtom (',' partitionDefinerAtom)* ')' partitionOption* (
'(' subpartitionDefinition (',' subpartitionDefinition)* ')'
)? # partitionListAtom
| PARTITION uid VALUES IN '(' partitionDefinerVector (',' partitionDefinerVector)* ')' partitionOption* (
'(' subpartitionDefinition (',' subpartitionDefinition)* ')'
)? # partitionListVector
| PARTITION uid partitionOption* ('(' subpartitionDefinition (',' subpartitionDefinition)* ')')? # partitionSimple
;
partitionDefinerAtom
: constant
| expression
| MAXVALUE
;
partitionDefinerVector
: '(' partitionDefinerAtom (',' partitionDefinerAtom)+ ')'
;
subpartitionDefinition
: SUBPARTITION uid partitionOption*
;
partitionOption
: DEFAULT? STORAGE? ENGINE '='? engineName # partitionOptionEngine
| COMMENT '='? comment = STRING_LITERAL # partitionOptionComment
| DATA DIRECTORY '='? dataDirectory = STRING_LITERAL # partitionOptionDataDirectory
| INDEX DIRECTORY '='? indexDirectory = STRING_LITERAL # partitionOptionIndexDirectory
| MAX_ROWS '='? maxRows = decimalLiteral # partitionOptionMaxRows
| MIN_ROWS '='? minRows = decimalLiteral # partitionOptionMinRows
| TABLESPACE '='? tablespace = uid # partitionOptionTablespace
| NODEGROUP '='? nodegroup = uid # partitionOptionNodeGroup
;
// Alter statements
alterDatabase
: ALTER dbFormat = (DATABASE | SCHEMA) uid? createDatabaseOption+ # alterSimpleDatabase
| ALTER dbFormat = (DATABASE | SCHEMA) uid UPGRADE DATA DIRECTORY NAME # alterUpgradeName
;
alterEvent
: ALTER ownerStatement? EVENT fullId (ON SCHEDULE scheduleExpression)? (
ON COMPLETION NOT? PRESERVE
)? (RENAME TO fullId)? enableType? (COMMENT STRING_LITERAL)? (DO routineBody)?
;
alterFunction
: ALTER FUNCTION fullId routineOption*
;
alterInstance
: ALTER INSTANCE ROTATE INNODB MASTER KEY
;
alterLogfileGroup
: ALTER LOGFILE GROUP uid ADD UNDOFILE STRING_LITERAL (INITIAL_SIZE '='? fileSizeLiteral)? WAIT? ENGINE '='? engineName
;
alterProcedure
: ALTER PROCEDURE fullId routineOption*
;
alterServer
: ALTER SERVER uid OPTIONS '(' serverOption (',' serverOption)* ')'
;
alterTable
: ALTER intimeAction = (ONLINE | OFFLINE)? IGNORE? TABLE tableName (
alterSpecification (',' alterSpecification)*
)? partitionDefinitions?
;
alterTablespace
: ALTER TABLESPACE uid objectAction = (ADD | DROP) DATAFILE STRING_LITERAL (
INITIAL_SIZE '=' fileSizeLiteral
)? WAIT? ENGINE '='? engineName
;
alterView
: ALTER (ALGORITHM '=' algType = (UNDEFINED | MERGE | TEMPTABLE))? ownerStatement? (
SQL SECURITY secContext = (DEFINER | INVOKER)
)? VIEW fullId ('(' uidList ')')? AS selectStatement (
WITH checkOpt = (CASCADED | LOCAL)? CHECK OPTION
)?
;
// details
alterSpecification
: tableOption (','? tableOption)* # alterByTableOption
| ADD COLUMN? uid columnDefinition (FIRST | AFTER uid)? # alterByAddColumn
| ADD COLUMN? '(' uid columnDefinition (',' uid columnDefinition)* ')' # alterByAddColumns
| ADD indexFormat = (INDEX | KEY) uid? indexType? indexColumnNames indexOption* # alterByAddIndex
| ADD (CONSTRAINT name = uid?)? PRIMARY KEY index = uid? indexType? indexColumnNames indexOption* # alterByAddPrimaryKey
| ADD (CONSTRAINT name = uid?)? UNIQUE indexFormat = (INDEX | KEY)? indexName = uid? indexType? indexColumnNames indexOption* # alterByAddUniqueKey
| ADD keyType = (FULLTEXT | SPATIAL) indexFormat = (INDEX | KEY)? uid? indexColumnNames indexOption* # alterByAddSpecialIndex
| ADD (CONSTRAINT name = uid?)? FOREIGN KEY indexName = uid? indexColumnNames referenceDefinition # alterByAddForeignKey
| ADD (CONSTRAINT name = uid?)? CHECK (uid | stringLiteral | '(' expression ')') NOT? ENFORCED? # alterByAddCheckTableConstraint
| ALTER (CONSTRAINT name = uid?)? CHECK (uid | stringLiteral | '(' expression ')') NOT? ENFORCED? # alterByAlterCheckTableConstraint
| ADD (CONSTRAINT name = uid?)? CHECK '(' expression ')' # alterByAddCheckTableConstraint
| ALGORITHM '='? algType = (DEFAULT | INSTANT | INPLACE | COPY) # alterBySetAlgorithm
| ALTER COLUMN? uid (SET DEFAULT defaultValue | DROP DEFAULT) # alterByChangeDefault
| CHANGE COLUMN? oldColumn = uid newColumn = uid columnDefinition (
FIRST
| AFTER afterColumn = uid
)? # alterByChangeColumn
| RENAME COLUMN oldColumn = uid TO newColumn = uid # alterByRenameColumn
| LOCK '='? lockType = (DEFAULT | NONE | SHARED | EXCLUSIVE) # alterByLock
| MODIFY COLUMN? uid columnDefinition (FIRST | AFTER uid)? # alterByModifyColumn
| DROP COLUMN? uid RESTRICT? # alterByDropColumn
| DROP (CONSTRAINT | CHECK) uid # alterByDropConstraintCheck
| DROP PRIMARY KEY # alterByDropPrimaryKey
| DROP indexFormat = (INDEX | KEY) uid # alterByDropIndex
| RENAME indexFormat = (INDEX | KEY) uid TO uid # alterByRenameIndex
| ALTER COLUMN? uid (
SET DEFAULT ( stringLiteral | '(' expression ')')
| SET (VISIBLE | INVISIBLE)
| DROP DEFAULT
) # alterByAlterColumnDefault
| ALTER INDEX uid (VISIBLE | INVISIBLE) # alterByAlterIndexVisibility
| DROP FOREIGN KEY uid dottedId? # alterByDropForeignKey
| DISABLE KEYS # alterByDisableKeys
| ENABLE KEYS # alterByEnableKeys
| RENAME renameFormat = (TO | AS)? (uid | fullId) # alterByRename
| ORDER BY uidList # alterByOrder
| CONVERT TO (CHARSET | CHARACTER SET) charsetName (COLLATE collationName)? # alterByConvertCharset
| DEFAULT? CHARACTER SET '=' charsetName (COLLATE '=' collationName)? # alterByDefaultCharset
| DISCARD TABLESPACE # alterByDiscardTablespace
| IMPORT TABLESPACE # alterByImportTablespace
| FORCE # alterByForce
| validationFormat = (WITHOUT | WITH) VALIDATION # alterByValidate
| ADD COLUMN? '(' createDefinition (',' createDefinition)* ')' # alterByAddDefinitions
| alterPartitionSpecification # alterPartition
;
alterPartitionSpecification
: ADD PARTITION '(' partitionDefinition (',' partitionDefinition)* ')' # alterByAddPartition
| DROP PARTITION uidList # alterByDropPartition
| DISCARD PARTITION (uidList | ALL) TABLESPACE # alterByDiscardPartition
| IMPORT PARTITION (uidList | ALL) TABLESPACE # alterByImportPartition
| TRUNCATE PARTITION (uidList | ALL) # alterByTruncatePartition
| COALESCE PARTITION decimalLiteral # alterByCoalescePartition
| REORGANIZE PARTITION uidList INTO '(' partitionDefinition (',' partitionDefinition)* ')' # alterByReorganizePartition
| EXCHANGE PARTITION uid WITH TABLE tableName (validationFormat = (WITH | WITHOUT) VALIDATION)? # alterByExchangePartition
| ANALYZE PARTITION (uidList | ALL) # alterByAnalyzePartition
| CHECK PARTITION (uidList | ALL) # alterByCheckPartition
| OPTIMIZE PARTITION (uidList | ALL) # alterByOptimizePartition
| REBUILD PARTITION (uidList | ALL) # alterByRebuildPartition
| REPAIR PARTITION (uidList | ALL) # alterByRepairPartition
| REMOVE PARTITIONING # alterByRemovePartitioning
| UPGRADE PARTITIONING # alterByUpgradePartitioning
;
// Drop statements
dropDatabase
: DROP dbFormat = (DATABASE | SCHEMA) ifExists? uid
;
dropEvent
: DROP EVENT ifExists? fullId
;
dropIndex
: DROP INDEX intimeAction = (ONLINE | OFFLINE)? uid ON tableName (
ALGORITHM '='? algType = (DEFAULT | INPLACE | COPY)
| LOCK '='? lockType = (DEFAULT | NONE | SHARED | EXCLUSIVE)
)*
;
dropLogfileGroup
: DROP LOGFILE GROUP uid ENGINE '=' engineName
;
dropProcedure
: DROP PROCEDURE ifExists? fullId
;
dropFunction
: DROP FUNCTION ifExists? fullId
;
dropServer
: DROP SERVER ifExists? uid
;
dropTable
: DROP TEMPORARY? TABLE ifExists? tables dropType = (RESTRICT | CASCADE)?
;
dropTablespace
: DROP TABLESPACE uid (ENGINE '='? engineName)?
;
dropTrigger
: DROP TRIGGER ifExists? fullId
;
dropView
: DROP VIEW ifExists? fullId (',' fullId)* dropType = (RESTRICT | CASCADE)?
;
dropRole
: DROP ROLE ifExists? roleName (',' roleName)*
;
setRole
: SET DEFAULT ROLE (NONE | ALL | roleName (',' roleName)*) TO (userName | uid) (
',' (userName | uid)
)*
| SET ROLE roleOption
;
// Other DDL statements
renameTable
: RENAME TABLE renameTableClause (',' renameTableClause)*
;
renameTableClause
: tableName TO tableName
;
truncateTable
: TRUNCATE TABLE? tableName
;
// Data Manipulation Language
// Primary DML Statements
callStatement
: CALL fullId ('(' (constants | expressions)? ')')?
;
deleteStatement
: singleDeleteStatement
| multipleDeleteStatement
;
doStatement
: DO expressions
;
handlerStatement
: handlerOpenStatement
| handlerReadIndexStatement
| handlerReadStatement
| handlerCloseStatement
;
insertStatement
: INSERT priority = (LOW_PRIORITY | DELAYED | HIGH_PRIORITY)? IGNORE? INTO? tableName (
PARTITION '(' partitions = uidList? ')'
)? (
('(' columns = fullColumnNameList? ')')? insertStatementValue (AS? uid)?
| SET setFirst = updatedElement (',' setElements += updatedElement)*
) (
ON DUPLICATE KEY UPDATE duplicatedFirst = updatedElement (
',' duplicatedElements += updatedElement
)*
)?
;
loadDataStatement
: LOAD DATA priority = (LOW_PRIORITY | CONCURRENT)? LOCAL? INFILE filename = STRING_LITERAL violation = (
REPLACE
| IGNORE
)? INTO TABLE tableName (PARTITION '(' uidList ')')? (CHARACTER SET charset = charsetName)? (
fieldsFormat = (FIELDS | COLUMNS) selectFieldsInto+
)? (LINES selectLinesInto+)? (IGNORE decimalLiteral linesFormat = (LINES | ROWS))? (
'(' assignmentField (',' assignmentField)* ')'
)? (SET updatedElement (',' updatedElement)*)?
;
loadXmlStatement
: LOAD XML priority = (LOW_PRIORITY | CONCURRENT)? LOCAL? INFILE filename = STRING_LITERAL violation = (
REPLACE
| IGNORE
)? INTO TABLE tableName (CHARACTER SET charset = charsetName)? (
ROWS IDENTIFIED BY '<' tag = STRING_LITERAL '>'
)? (IGNORE decimalLiteral linesFormat = (LINES | ROWS))? (
'(' assignmentField (',' assignmentField)* ')'
)? (SET updatedElement (',' updatedElement)*)?
;
replaceStatement
: REPLACE priority = (LOW_PRIORITY | DELAYED)? INTO? tableName (
PARTITION '(' partitions = uidList ')'
)? (
('(' columns = uidList ')')? insertStatementValue
| SET setFirst = updatedElement (',' setElements += updatedElement)*
)
;
selectStatement
: withStatement? querySpecification lockClause?
| withStatement? queryExpression lockClause?
| withStatement? (querySpecificationNointo | queryExpressionNointo) unionStatement+ (
UNION unionType = (ALL | DISTINCT)? (querySpecification | queryExpression)
)? orderByClause? limitClause? lockClause?
| withStatement? queryExpressionNointo unionParenthesis+ (UNION unionType = (ALL | DISTINCT)? queryExpression)? orderByClause? limitClause? lockClause?
| withStatement? querySpecificationNointo (',' lateralStatement)+
;
updateStatement
: singleUpdateStatement
| multipleUpdateStatement
;
// https://dev.mysql.com/doc/refman/8.0/en/values.html
valuesStatement
: VALUES '(' expressionsWithDefaults? ')' (',' '(' expressionsWithDefaults? ')')*
;
// details
insertStatementValue
: selectStatement
| insertFormat = (VALUES | VALUE) '(' expressionsWithDefaults? ')' (
',' '(' expressionsWithDefaults? ')'
)*
;
updatedElement
: fullColumnName '=' (expression | DEFAULT)
;
assignmentField
: uid
| LOCAL_ID
;
lockClause
: FOR UPDATE
| LOCK IN SHARE MODE
;
// Detailed DML Statements
singleDeleteStatement
: DELETE priority = LOW_PRIORITY? QUICK? IGNORE? FROM tableName (AS? uid)? (
PARTITION '(' uidList ')'
)? (WHERE expression)? orderByClause? (LIMIT limitClauseAtom)?
;
multipleDeleteStatement
: DELETE priority = LOW_PRIORITY? QUICK? IGNORE? (
tableName ('.' '*')? ( ',' tableName ('.' '*')?)* FROM tableSources
| FROM tableName ('.' '*')? ( ',' tableName ('.' '*')?)* USING tableSources
) (WHERE expression)?
;
handlerOpenStatement
: HANDLER tableName OPEN (AS? uid)?
;
handlerReadIndexStatement
: HANDLER tableName READ index = uid (
comparisonOperator '(' constants ')'
| moveOrder = (FIRST | NEXT | PREV | LAST)
) (WHERE expression)? (LIMIT limitClauseAtom)?
;
handlerReadStatement
: HANDLER tableName READ moveOrder = (FIRST | NEXT) (WHERE expression)? (LIMIT limitClauseAtom)?
;
handlerCloseStatement
: HANDLER tableName CLOSE
;
singleUpdateStatement
: UPDATE priority = LOW_PRIORITY? IGNORE? tableSources (AS? uid)? SET updatedElement (
',' updatedElement
)* (WHERE expression)? orderByClause? limitClause?
;
multipleUpdateStatement
: UPDATE priority = LOW_PRIORITY? IGNORE? tableSources SET updatedElement (',' updatedElement)* (
WHERE expression
)?
;
// details
orderByClause
: ORDER BY orderByExpression (',' orderByExpression)*
;
orderByExpression
: expression order = (ASC | DESC)?
;
tableSources
: tableSource (',' tableSource)*
;
tableSource
: tableSourceItem joinPart* # tableSourceBase
| '(' tableSourceItem joinPart* ')' # tableSourceNested
| jsonTable # tableJson
;
tableSourceItem
: tableName (PARTITION '(' uidList ')')? (AS? alias = uid)? (indexHint (',' indexHint)*)? # atomTableItem
| sequenceFunctionName '(' DECIMAL_LITERAL ')' (AS? alias = uid)? # sequenceTableItem
| (selectStatement | '(' parenthesisSubquery = selectStatement ')') AS? alias = uid # subqueryTableItem
| '(' tableSources ')' # tableSourcesItem
;
indexHint
: indexHintAction = (USE | IGNORE | FORCE) keyFormat = (INDEX | KEY) (FOR indexHintType)? '(' uidList ')'
;
indexHintType
: JOIN
| ORDER BY
| GROUP BY
;
joinPart
: (INNER | CROSS)? JOIN LATERAL? tableSourceItem joinSpec* # innerJoin
| STRAIGHT_JOIN tableSourceItem (ON expression)* # straightJoin
| (LEFT | RIGHT) OUTER? JOIN LATERAL? tableSourceItem joinSpec* # outerJoin
| NATURAL ((LEFT | RIGHT) OUTER?)? JOIN tableSourceItem # naturalJoin
;
joinSpec
: (ON expression)
| USING '(' uidList ')'
;
// Select Statement's Details
queryExpression
: '(' querySpecification ')'
| '(' queryExpression ')'
;
queryExpressionNointo
: '(' querySpecificationNointo ')'
| '(' queryExpressionNointo ')'
;
querySpecification
: SELECT selectSpec* selectElements selectIntoExpression? fromClause? groupByClause? havingClause? windowClause? orderByClause? limitClause?
| SELECT selectSpec* selectElements fromClause? groupByClause? havingClause? windowClause? orderByClause? limitClause? selectIntoExpression?
;
querySpecificationNointo
: SELECT selectSpec* selectElements fromClause? groupByClause? havingClause? windowClause? orderByClause? limitClause? unionStatement?
;
unionParenthesis
: UNION unionType = (ALL | DISTINCT)? queryExpressionNointo
;
unionStatement
: UNION unionType = (ALL | DISTINCT)? (querySpecificationNointo | queryExpressionNointo)
;
lateralStatement
: LATERAL (
querySpecificationNointo
| queryExpressionNointo
| ('(' (querySpecificationNointo | queryExpressionNointo) ')' (AS? uid)?)
)
;
// JSON
// https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html
jsonTable
: JSON_TABLE '(' expression ',' STRING_LITERAL COLUMNS '(' jsonColumnList ')' ')' (AS? uid)?
;
jsonColumnList
: jsonColumn (',' jsonColumn)*
;
jsonColumn
: fullColumnName (
FOR ORDINALITY
| dataType (PATH STRING_LITERAL jsonOnEmpty? jsonOnError? | EXISTS PATH STRING_LITERAL)
)
| NESTED PATH? STRING_LITERAL COLUMNS '(' jsonColumnList ')'
;
jsonOnEmpty
: (NULL_LITERAL | ERROR | DEFAULT defaultValue) ON EMPTY
;
jsonOnError
: (NULL_LITERAL | ERROR | DEFAULT defaultValue) ON ERROR
;
// details
selectSpec
: (ALL | DISTINCT | DISTINCTROW)
| HIGH_PRIORITY
| STRAIGHT_JOIN
| SQL_SMALL_RESULT
| SQL_BIG_RESULT
| SQL_BUFFER_RESULT
| (SQL_CACHE | SQL_NO_CACHE)
| SQL_CALC_FOUND_ROWS
;
selectElements
: (star = '*' | selectElement) (',' selectElement)*
;
selectElement
: fullId '.' '*' # selectStarElement
| fullColumnName (AS? uid)? # selectColumnElement
| functionCall (AS? uid)? # selectFunctionElement
| (LOCAL_ID VAR_ASSIGN)? expression (AS? uid)? # selectExpressionElement
;
selectIntoExpression
: INTO assignmentField (',' assignmentField)* # selectIntoVariables
| INTO DUMPFILE STRING_LITERAL # selectIntoDumpFile
| (
INTO OUTFILE filename = STRING_LITERAL (CHARACTER SET charset = charsetName)? (
fieldsFormat = (FIELDS | COLUMNS) selectFieldsInto+
)? (LINES selectLinesInto+)?
) # selectIntoTextFile
;
selectFieldsInto
: TERMINATED BY terminationField = STRING_LITERAL
| OPTIONALLY? ENCLOSED BY enclosion = STRING_LITERAL
| ESCAPED BY escaping = STRING_LITERAL
;
selectLinesInto
: STARTING BY starting = STRING_LITERAL
| TERMINATED BY terminationLine = STRING_LITERAL
;
fromClause
: (FROM tableSources)? (WHERE whereExpr = expression)?
;
groupByClause
: GROUP BY groupByItem (',' groupByItem)* (WITH ROLLUP)?
;
havingClause
: HAVING havingExpr = expression
;
windowClause
: WINDOW windowName AS '(' windowSpec ')' (',' windowName AS '(' windowSpec ')')*
;
groupByItem
: expression order = (ASC | DESC)?
;
limitClause
: LIMIT (
(offset = limitClauseAtom ',')? limit = limitClauseAtom
| limit = limitClauseAtom OFFSET offset = limitClauseAtom
)
;
limitClauseAtom
: decimalLiteral
| mysqlVariable
| simpleId
;
// Transaction's Statements
startTransaction
: START TRANSACTION (transactionMode (',' transactionMode)*)?
;
beginWork
: BEGIN WORK?
;
commitWork
: COMMIT WORK? (AND nochain = NO? CHAIN)? (norelease = NO? RELEASE)?
;
rollbackWork
: ROLLBACK WORK? (AND nochain = NO? CHAIN)? (norelease = NO? RELEASE)?
;
savepointStatement
: SAVEPOINT uid
;
rollbackStatement
: ROLLBACK WORK? TO SAVEPOINT? uid
;
releaseStatement
: RELEASE SAVEPOINT uid
;
lockTables
: LOCK (TABLE | TABLES) lockTableElement (',' lockTableElement)*
;
unlockTables
: UNLOCK TABLES
;
// details
setAutocommitStatement
: SET AUTOCOMMIT '=' autocommitValue = ('0' | '1')
;
setTransactionStatement
: SET transactionContext = (GLOBAL | SESSION)? TRANSACTION transactionOption (
',' transactionOption
)*
;
transactionMode
: WITH CONSISTENT SNAPSHOT
| READ WRITE
| READ ONLY
;
lockTableElement
: tableName (AS? uid)? lockAction
;
lockAction
: READ LOCAL?
| LOW_PRIORITY? WRITE
;
transactionOption
: ISOLATION LEVEL transactionLevel
| READ WRITE
| READ ONLY
;
transactionLevel
: REPEATABLE READ
| READ COMMITTED
| READ UNCOMMITTED
| SERIALIZABLE
;
// Replication's Statements
// Base Replication
changeMaster
: CHANGE MASTER TO masterOption (',' masterOption)* channelOption?
;
changeReplicationFilter
: CHANGE REPLICATION FILTER replicationFilter (',' replicationFilter)*
;
purgeBinaryLogs
: PURGE purgeFormat = (BINARY | MASTER) LOGS (
TO fileName = STRING_LITERAL
| BEFORE timeValue = STRING_LITERAL
)
;
resetMaster
: RESET MASTER
;
resetSlave
: RESET SLAVE ALL? channelOption?
;
startSlave
: START SLAVE (threadType (',' threadType)*)? (UNTIL untilOption)? connectionOption* channelOption?
;
stopSlave
: STOP SLAVE (threadType (',' threadType)*)?
;
startGroupReplication
: START GROUP_REPLICATION
;
stopGroupReplication
: STOP GROUP_REPLICATION
;
// details
masterOption
: stringMasterOption '=' STRING_LITERAL # masterStringOption
| decimalMasterOption '=' decimalLiteral # masterDecimalOption
| boolMasterOption '=' boolVal = ('0' | '1') # masterBoolOption
| MASTER_HEARTBEAT_PERIOD '=' REAL_LITERAL # masterRealOption
| IGNORE_SERVER_IDS '=' '(' (uid (',' uid)*)? ')' # masterUidListOption
;
stringMasterOption
: MASTER_BIND
| MASTER_HOST
| MASTER_USER
| MASTER_PASSWORD
| MASTER_LOG_FILE
| RELAY_LOG_FILE
| MASTER_SSL_CA
| MASTER_SSL_CAPATH
| MASTER_SSL_CERT
| MASTER_SSL_CRL
| MASTER_SSL_CRLPATH
| MASTER_SSL_KEY
| MASTER_SSL_CIPHER
| MASTER_TLS_VERSION
;
decimalMasterOption
: MASTER_PORT
| MASTER_CONNECT_RETRY
| MASTER_RETRY_COUNT
| MASTER_DELAY
| MASTER_LOG_POS
| RELAY_LOG_POS
;
boolMasterOption
: MASTER_AUTO_POSITION
| MASTER_SSL
| MASTER_SSL_VERIFY_SERVER_CERT
;
channelOption
: FOR CHANNEL STRING_LITERAL
;
replicationFilter
: REPLICATE_DO_DB '=' '(' uidList ')' # doDbReplication
| REPLICATE_IGNORE_DB '=' '(' uidList ')' # ignoreDbReplication
| REPLICATE_DO_TABLE '=' '(' tables ')' # doTableReplication
| REPLICATE_IGNORE_TABLE '=' '(' tables ')' # ignoreTableReplication
| REPLICATE_WILD_DO_TABLE '=' '(' simpleStrings ')' # wildDoTableReplication
| REPLICATE_WILD_IGNORE_TABLE '=' '(' simpleStrings ')' # wildIgnoreTableReplication
| REPLICATE_REWRITE_DB '=' '(' tablePair (',' tablePair)* ')' # rewriteDbReplication
;
tablePair
: '(' firstTable = tableName ',' secondTable = tableName ')'
;
threadType
: IO_THREAD
| SQL_THREAD
;
untilOption
: gtids = (SQL_BEFORE_GTIDS | SQL_AFTER_GTIDS) '=' gtuidSet # gtidsUntilOption
| MASTER_LOG_FILE '=' STRING_LITERAL ',' MASTER_LOG_POS '=' decimalLiteral # masterLogUntilOption
| RELAY_LOG_FILE '=' STRING_LITERAL ',' RELAY_LOG_POS '=' decimalLiteral # relayLogUntilOption
| SQL_AFTER_MTS_GAPS # sqlGapsUntilOption
;
connectionOption
: USER '=' conOptUser = STRING_LITERAL # userConnectionOption
| PASSWORD '=' conOptPassword = STRING_LITERAL # passwordConnectionOption
| DEFAULT_AUTH '=' conOptDefAuth = STRING_LITERAL # defaultAuthConnectionOption
| PLUGIN_DIR '=' conOptPluginDir = STRING_LITERAL # pluginDirConnectionOption
;
gtuidSet
: uuidSet (',' uuidSet)*
| STRING_LITERAL
;
// XA Transactions
xaStartTransaction
: XA xaStart = (START | BEGIN) xid xaAction = (JOIN | RESUME)?
;
xaEndTransaction
: XA END xid (SUSPEND (FOR MIGRATE)?)?
;
xaPrepareStatement
: XA PREPARE xid
;
xaCommitWork
: XA COMMIT xid (ONE PHASE)?
;
xaRollbackWork
: XA ROLLBACK xid
;
xaRecoverWork
: XA RECOVER (CONVERT xid)?
;
// Prepared Statements
prepareStatement
: PREPARE uid FROM (query = STRING_LITERAL | variable = LOCAL_ID)
;
executeStatement
: EXECUTE uid (USING userVariables)?
;
deallocatePrepare
: dropFormat = (DEALLOCATE | DROP) PREPARE uid
;
// Compound Statements
routineBody
: blockStatement
| sqlStatement
;
// details
blockStatement
: (uid ':')? BEGIN (declareVariable SEMI)* (declareCondition SEMI)* (declareCursor SEMI)* (
declareHandler SEMI
)* procedureSqlStatement* END uid?
;
caseStatement
: CASE (uid | expression)? caseAlternative+ (ELSE procedureSqlStatement+)? END CASE
;
ifStatement
: IF expression THEN thenStatements += procedureSqlStatement+ elifAlternative* (
ELSE elseStatements += procedureSqlStatement+
)? END IF
;
iterateStatement
: ITERATE uid
;
leaveStatement
: LEAVE uid
;
loopStatement
: (uid ':')? LOOP procedureSqlStatement+ END LOOP uid?
;
repeatStatement
: (uid ':')? REPEAT procedureSqlStatement+ UNTIL expression END REPEAT uid?
;
returnStatement
: RETURN expression
;
whileStatement
: (uid ':')? WHILE expression DO procedureSqlStatement+ END WHILE uid?
;
cursorStatement
: CLOSE uid # CloseCursor
| FETCH (NEXT? FROM)? uid INTO uidList # FetchCursor
| OPEN uid # OpenCursor
;
// details
declareVariable
: DECLARE uidList dataType (DEFAULT expression)?
;
declareCondition
: DECLARE uid CONDITION FOR (decimalLiteral | SQLSTATE VALUE? STRING_LITERAL)
;
declareCursor
: DECLARE uid CURSOR FOR selectStatement
;
declareHandler
: DECLARE handlerAction = (CONTINUE | EXIT | UNDO) HANDLER FOR handlerConditionValue (
',' handlerConditionValue
)* routineBody
;
handlerConditionValue
: decimalLiteral # handlerConditionCode
| SQLSTATE VALUE? STRING_LITERAL # handlerConditionState
| uid # handlerConditionName
| SQLWARNING # handlerConditionWarning
| NOT FOUND # handlerConditionNotfound
| SQLEXCEPTION # handlerConditionException
;
procedureSqlStatement
: (compoundStatement | sqlStatement) SEMI
;
caseAlternative
: WHEN (constant | expression) THEN procedureSqlStatement+
;
elifAlternative
: ELSEIF expression THEN procedureSqlStatement+
;
// Administration Statements
// Account management statements
alterUser
: ALTER USER userSpecification (',' userSpecification)* # alterUserMysqlV56
| ALTER USER ifExists? userAuthOption (',' userAuthOption)* (
REQUIRE (tlsNone = NONE | tlsOption (AND? tlsOption)*)
)? (WITH userResourceOption+)? (userPasswordOption | userLockOption)* (
COMMENT STRING_LITERAL
| ATTRIBUTE STRING_LITERAL
)? # alterUserMysqlV80
| ALTER USER ifExists? (userName | uid) DEFAULT ROLE roleOption # alterUserMysqlV80
;
createUser
: CREATE USER userAuthOption (',' userAuthOption)* # createUserMysqlV56
| CREATE USER ifNotExists? userAuthOption (',' userAuthOption)* (DEFAULT ROLE roleOption)? (
REQUIRE (tlsNone = NONE | tlsOption (AND? tlsOption)*)
)? (WITH userResourceOption+)? (userPasswordOption | userLockOption)* (
COMMENT STRING_LITERAL
| ATTRIBUTE STRING_LITERAL
)? # createUserMysqlV80
;
dropUser
: DROP USER ifExists? userName (',' userName)*
;
grantStatement
: GRANT privelegeClause (',' privelegeClause)* ON privilegeObject = (
TABLE
| FUNCTION
| PROCEDURE
)? privilegeLevel TO userAuthOption (',' userAuthOption)* (
REQUIRE (tlsNone = NONE | tlsOption (AND? tlsOption)*)
)? (WITH (GRANT OPTION | userResourceOption)*)? (AS userName WITH ROLE roleOption)?
| GRANT (userName | uid) (',' (userName | uid))* TO (userName | uid) (',' (userName | uid))* (
WITH ADMIN OPTION
)?
;
roleOption
: DEFAULT
| NONE
| ALL (EXCEPT userName (',' userName)*)?
| userName (',' userName)*
;
grantProxy
: GRANT PROXY ON fromFirst = userName TO toFirst = userName (',' toOther += userName)* (
WITH GRANT OPTION
)?
;
renameUser
: RENAME USER renameUserClause (',' renameUserClause)*
;
revokeStatement
: REVOKE ifExists? (privelegeClause | uid) (',' privelegeClause | uid)* ON privilegeObject = (
TABLE
| FUNCTION
| PROCEDURE
)? privilegeLevel FROM userName (',' userName)* (IGNORE UNKNOWN USER)? # detailRevoke
| REVOKE ifExists? ALL PRIVILEGES? ',' GRANT OPTION FROM userName (',' userName)* (
IGNORE UNKNOWN USER
)? # shortRevoke
| REVOKE ifExists? (userName | uid) (',' (userName | uid))* FROM (userName | uid) (
',' (userName | uid)
)* (IGNORE UNKNOWN USER)? # roleRevoke
;
revokeProxy
: REVOKE PROXY ON onUser = userName FROM fromFirst = userName (',' fromOther += userName)*
;
setPasswordStatement
: SET PASSWORD (FOR userName)? '=' (passwordFunctionClause | STRING_LITERAL)
;
// details
userSpecification
: userName userPasswordOption
;
userAuthOption
: userName IDENTIFIED BY PASSWORD hashed = STRING_LITERAL # hashAuthOption
| userName IDENTIFIED BY RANDOM PASSWORD authOptionClause # randomAuthOption
| userName IDENTIFIED BY STRING_LITERAL authOptionClause # stringAuthOption
| userName IDENTIFIED WITH authenticationRule # moduleAuthOption
| userName # simpleAuthOption
;
authOptionClause
: (REPLACE STRING_LITERAL)? (RETAIN CURRENT PASSWORD)?
;
authenticationRule
: authPlugin ((BY | USING | AS) (STRING_LITERAL | RANDOM PASSWORD) authOptionClause)? # module
| authPlugin USING passwordFunctionClause # passwordModuleOption
;
tlsOption
: SSL
| X509
| CIPHER STRING_LITERAL
| ISSUER STRING_LITERAL
| SUBJECT STRING_LITERAL
;
userResourceOption
: MAX_QUERIES_PER_HOUR decimalLiteral
| MAX_UPDATES_PER_HOUR decimalLiteral
| MAX_CONNECTIONS_PER_HOUR decimalLiteral
| MAX_USER_CONNECTIONS decimalLiteral
;
userPasswordOption
: PASSWORD EXPIRE (
expireType = DEFAULT
| expireType = NEVER
| expireType = INTERVAL decimalLiteral DAY
)?
| PASSWORD HISTORY (DEFAULT | decimalLiteral)
| PASSWORD REUSE INTERVAL (DEFAULT | decimalLiteral DAY)
| PASSWORD REQUIRE CURRENT (OPTIONAL | DEFAULT)?
| FAILED_LOGIN_ATTEMPTS decimalLiteral
| PASSWORD_LOCK_TIME (decimalLiteral | UNBOUNDED)
;
userLockOption
: ACCOUNT lockType = (LOCK | UNLOCK)
;
privelegeClause
: privilege ('(' uidList ')')?
;
privilege
: ALL PRIVILEGES?
| ALTER ROUTINE?
| CREATE (TEMPORARY TABLES | ROUTINE | VIEW | USER | TABLESPACE | ROLE)?
| DELETE
| DROP (ROLE)?
| EVENT
| EXECUTE
| FILE
| GRANT OPTION
| INDEX
| INSERT
| LOCK TABLES
| PROCESS
| PROXY
| REFERENCES
| RELOAD
| REPLICATION (CLIENT | SLAVE)
| SELECT
| SHOW (VIEW | DATABASES)
| SHUTDOWN
| SUPER
| TRIGGER
| UPDATE
| USAGE
| APPLICATION_PASSWORD_ADMIN
| AUDIT_ABORT_EXEMPT
| AUDIT_ADMIN
| AUTHENTICATION_POLICY_ADMIN
| BACKUP_ADMIN
| BINLOG_ADMIN
| BINLOG_ENCRYPTION_ADMIN
| CLONE_ADMIN
| CONNECTION_ADMIN
| ENCRYPTION_KEY_ADMIN
| FIREWALL_ADMIN
| FIREWALL_EXEMPT
| FIREWALL_USER
| FLUSH_OPTIMIZER_COSTS
| FLUSH_STATUS
| FLUSH_TABLES
| FLUSH_USER_RESOURCES
| GROUP_REPLICATION_ADMIN
| INNODB_REDO_LOG_ARCHIVE
| INNODB_REDO_LOG_ENABLE
| NDB_STORED_USER
| PASSWORDLESS_USER_ADMIN
| PERSIST_RO_VARIABLES_ADMIN
| REPLICATION_APPLIER
| REPLICATION_SLAVE_ADMIN
| RESOURCE_GROUP_ADMIN
| RESOURCE_GROUP_USER
| ROLE_ADMIN
| SERVICE_CONNECTION_ADMIN
| SESSION_VARIABLES_ADMIN
| SET_USER_ID
| SKIP_QUERY_REWRITE
| SHOW_ROUTINE
| SYSTEM_USER
| SYSTEM_VARIABLES_ADMIN
| TABLE_ENCRYPTION_ADMIN
| TELEMETRY_LOG_ADMIN
| TP_CONNECTION_ADMIN
| VERSION_TOKEN_ADMIN
| XA_RECOVER_ADMIN
// MySQL on Amazon RDS
| LOAD FROM S3
| SELECT INTO S3
| INVOKE LAMBDA
;
privilegeLevel
: '*' # currentSchemaPriviLevel
| '*' '.' '*' # globalPrivLevel
| uid '.' '*' # definiteSchemaPrivLevel
| uid '.' uid # definiteFullTablePrivLevel
| uid dottedId # definiteFullTablePrivLevel2
| uid # definiteTablePrivLevel
;
renameUserClause
: fromFirst = userName TO toFirst = userName
;
// Table maintenance statements
analyzeTable
: ANALYZE actionOption = (NO_WRITE_TO_BINLOG | LOCAL)? (TABLE | TABLES) tables (
UPDATE HISTOGRAM ON fullColumnName (',' fullColumnName)* (WITH decimalLiteral BUCKETS)?
)? (DROP HISTOGRAM ON fullColumnName (',' fullColumnName)*)?
;
checkTable
: CHECK TABLE tables checkTableOption*
;
checksumTable
: CHECKSUM TABLE tables actionOption = (QUICK | EXTENDED)?
;
optimizeTable
: OPTIMIZE actionOption = (NO_WRITE_TO_BINLOG | LOCAL)? (TABLE | TABLES) tables
;
repairTable
: REPAIR actionOption = (NO_WRITE_TO_BINLOG | LOCAL)? TABLE tables QUICK? EXTENDED? USE_FRM?
;
// details
checkTableOption
: FOR UPGRADE
| QUICK
| FAST
| MEDIUM
| EXTENDED
| CHANGED
;
// Plugin and udf statements
createUdfunction
: CREATE AGGREGATE? FUNCTION ifNotExists? uid RETURNS returnType = (
STRING
| INTEGER
| REAL
| DECIMAL
) SONAME STRING_LITERAL
;
installPlugin
: INSTALL PLUGIN uid SONAME STRING_LITERAL
;
uninstallPlugin
: UNINSTALL PLUGIN uid
;
// Set and show statements
setStatement
: SET variableClause ('=' | ':=') (expression | ON) (
',' variableClause ('=' | ':=') (expression | ON)
)* # setVariable
| SET charSet (charsetName | DEFAULT) # setCharset
| SET NAMES (charsetName (COLLATE collationName)? | DEFAULT) # setNames
| setPasswordStatement # setPassword
| setTransactionStatement # setTransaction
| setAutocommitStatement # setAutocommit
| SET fullId ('=' | ':=') expression (',' fullId ('=' | ':=') expression)* # setNewValueInsideTrigger
;
showStatement
: SHOW logFormat = (BINARY | MASTER) LOGS # showMasterLogs
| SHOW logFormat = (BINLOG | RELAYLOG) EVENTS (IN filename = STRING_LITERAL)? (
FROM fromPosition = decimalLiteral
)? (LIMIT (offset = decimalLiteral ',')? rowCount = decimalLiteral)? # showLogEvents
| SHOW showCommonEntity showFilter? # showObjectFilter
| SHOW FULL? columnsFormat = (COLUMNS | FIELDS) tableFormat = (FROM | IN) tableName (
schemaFormat = (FROM | IN) uid
)? showFilter? # showColumns
| SHOW CREATE schemaFormat = (DATABASE | SCHEMA) ifNotExists? uid # showCreateDb
| SHOW CREATE namedEntity = (EVENT | FUNCTION | PROCEDURE | TABLE | TRIGGER | VIEW) fullId # showCreateFullIdObject
| SHOW CREATE USER userName # showCreateUser
| SHOW ENGINE engineName engineOption = (STATUS | MUTEX) # showEngine
| SHOW showGlobalInfoClause # showGlobalInfo
| SHOW errorFormat = (ERRORS | WARNINGS) (
LIMIT (offset = decimalLiteral ',')? rowCount = decimalLiteral
)? # showErrors
| SHOW COUNT '(' '*' ')' errorFormat = (ERRORS | WARNINGS) # showCountErrors
| SHOW showSchemaEntity (schemaFormat = (FROM | IN) uid)? showFilter? # showSchemaFilter
| SHOW routine = (FUNCTION | PROCEDURE) CODE fullId # showRoutine
| SHOW GRANTS (FOR userName)? # showGrants
| SHOW indexFormat = (INDEX | INDEXES | KEYS) tableFormat = (FROM | IN) tableName (
schemaFormat = (FROM | IN) uid
)? (WHERE expression)? # showIndexes
| SHOW OPEN TABLES (schemaFormat = (FROM | IN) uid)? showFilter? # showOpenTables
| SHOW PROFILE showProfileType (',' showProfileType)* (FOR QUERY queryCount = decimalLiteral)? (
LIMIT (offset = decimalLiteral ',')? rowCount = decimalLiteral
) # showProfile
| SHOW SLAVE STATUS (FOR CHANNEL STRING_LITERAL)? # showSlaveStatus
;
// details
variableClause
: LOCAL_ID
| GLOBAL_ID
| ( ('@' '@')? (GLOBAL | SESSION | LOCAL))? uid
;
showCommonEntity
: CHARACTER SET
| COLLATION
| DATABASES
| SCHEMAS
| FUNCTION STATUS
| PROCEDURE STATUS
| (GLOBAL | SESSION)? (STATUS | VARIABLES)
;
showFilter
: LIKE STRING_LITERAL
| WHERE expression
;
showGlobalInfoClause
: STORAGE? ENGINES
| MASTER STATUS
| PLUGINS
| PRIVILEGES
| FULL? PROCESSLIST
| PROFILES
| SLAVE HOSTS
| AUTHORS
| CONTRIBUTORS
;
showSchemaEntity
: EVENTS
| TABLE STATUS
| FULL? TABLES
| TRIGGERS
;
showProfileType
: ALL
| BLOCK IO
| CONTEXT SWITCHES
| CPU
| IPC
| MEMORY
| PAGE FAULTS
| SOURCE
| SWAPS
;
// Other administrative statements
binlogStatement
: BINLOG STRING_LITERAL
;
cacheIndexStatement
: CACHE INDEX tableIndexes (',' tableIndexes)* (PARTITION '(' (uidList | ALL) ')')? IN schema = uid
;
flushStatement
: FLUSH flushFormat = (NO_WRITE_TO_BINLOG | LOCAL)? flushOption (',' flushOption)*
// Specific for Azure Database for MySQL Single Server instance.
| FLUSH FIREWALL_RULES
;
killStatement
: KILL connectionFormat = (CONNECTION | QUERY)? expression
;
loadIndexIntoCache
: LOAD INDEX INTO CACHE loadedTableIndexes (',' loadedTableIndexes)*
;
// remark reset (maser | slave) describe in replication's
// statements section
resetStatement
: RESET QUERY CACHE
;
shutdownStatement
: SHUTDOWN
;
// details
tableIndexes
: tableName (indexFormat = (INDEX | KEY)? '(' uidList ')')?
;
flushOption
: (
DES_KEY_FILE
| HOSTS
| ( BINARY | ENGINE | ERROR | GENERAL | RELAY | SLOW)? LOGS
| OPTIMIZER_COSTS
| PRIVILEGES
| QUERY CACHE
| STATUS
| USER_RESOURCES
| TABLES (WITH READ LOCK)?
) # simpleFlushOption
| RELAY LOGS channelOption? # channelFlushOption
| (TABLE | TABLES) tables? flushTableOption? # tableFlushOption
;
flushTableOption
: WITH READ LOCK
| FOR EXPORT
;
loadedTableIndexes
: tableName (PARTITION '(' (partitionList = uidList | ALL) ')')? (
indexFormat = (INDEX | KEY)? '(' indexList = uidList ')'
)? (IGNORE LEAVES)?
;
// Utility Statements
simpleDescribeStatement
: command = (EXPLAIN | DESCRIBE | DESC) tableName (column = uid | pattern = STRING_LITERAL)?
;
fullDescribeStatement
: command = (EXPLAIN | DESCRIBE | DESC) (
formatType = (EXTENDED | PARTITIONS | FORMAT) '=' formatValue = (TRADITIONAL | JSON)
)? describeObjectClause
;
helpStatement
: HELP STRING_LITERAL
;
useStatement
: USE uid
;
signalStatement
: SIGNAL (( SQLSTATE VALUE? stringLiteral) | ID | REVERSE_QUOTE_ID) (
SET signalConditionInformation ( ',' signalConditionInformation)*
)?
;
resignalStatement
: RESIGNAL (( SQLSTATE VALUE? stringLiteral) | ID | REVERSE_QUOTE_ID)? (
SET signalConditionInformation ( ',' signalConditionInformation)*
)?
;
signalConditionInformation
: (
CLASS_ORIGIN
| SUBCLASS_ORIGIN
| MESSAGE_TEXT
| MYSQL_ERRNO
| CONSTRAINT_CATALOG
| CONSTRAINT_SCHEMA
| CONSTRAINT_NAME
| CATALOG_NAME
| SCHEMA_NAME
| TABLE_NAME
| COLUMN_NAME
| CURSOR_NAME
) '=' (stringLiteral | DECIMAL_LITERAL | mysqlVariable | simpleId)
;
withStatement
: WITH RECURSIVE? commonTableExpressions (',' commonTableExpressions)*
;
tableStatement
: TABLE tableName orderByClause? limitClause?
;
diagnosticsStatement
: GET (CURRENT | STACKED)? DIAGNOSTICS (
(variableClause '=' ( NUMBER | ROW_COUNT) ( ',' variableClause '=' ( NUMBER | ROW_COUNT))*)
| (
CONDITION (decimalLiteral | variableClause) variableClause '=' diagnosticsConditionInformationName (
',' variableClause '=' diagnosticsConditionInformationName
)*
)
)
;
diagnosticsConditionInformationName
: CLASS_ORIGIN
| SUBCLASS_ORIGIN
| RETURNED_SQLSTATE
| MESSAGE_TEXT
| MYSQL_ERRNO
| CONSTRAINT_CATALOG
| CONSTRAINT_SCHEMA
| CONSTRAINT_NAME
| CATALOG_NAME
| SCHEMA_NAME
| TABLE_NAME
| COLUMN_NAME
| CURSOR_NAME
;
// details
describeObjectClause
: (selectStatement | deleteStatement | insertStatement | replaceStatement | updateStatement) # describeStatements
| FOR CONNECTION uid # describeConnection
;
// Common Clauses
// DB Objects
fullId
: uid (DOT_ID | '.' uid)?
;
tableName
: fullId
;
roleName
: userName
| uid
;
fullColumnName
: uid (dottedId dottedId?)?
| .? dottedId dottedId?
;
indexColumnName
: ((uid | STRING_LITERAL) ('(' decimalLiteral ')')? | expression) sortType = (ASC | DESC)?
;
simpleUserName
: STRING_LITERAL
| ID
| ADMIN
| keywordsCanBeId
;
hostName
: (LOCAL_ID | HOST_IP_ADDRESS | '@')
;
userName
: simpleUserName
| simpleUserName hostName
| currentUserExpression
;
mysqlVariable
: LOCAL_ID
| GLOBAL_ID
;
charsetName
: BINARY
| charsetNameBase
| STRING_LITERAL
| CHARSET_REVERSE_QOUTE_STRING
;
collationName
: uid
| STRING_LITERAL
;
engineName
: engineNameBase
| ID
| STRING_LITERAL
;
engineNameBase
: ARCHIVE
| BLACKHOLE
| CONNECT
| CSV
| FEDERATED
| INNODB
| MEMORY
| MRG_MYISAM
| MYISAM
| NDB
| NDBCLUSTER
| PERFORMANCE_SCHEMA
| TOKUDB
;
uuidSet
: decimalLiteral '-' decimalLiteral '-' decimalLiteral '-' decimalLiteral '-' decimalLiteral (
':' decimalLiteral '-' decimalLiteral
)+
;
xid
: globalTableUid = xuidStringId (',' qualifier = xuidStringId (',' idFormat = decimalLiteral)?)?
;
xuidStringId
: STRING_LITERAL
| BIT_STRING
| HEXADECIMAL_LITERAL+
;
authPlugin
: uid
| STRING_LITERAL
;
uid
: simpleId
//| DOUBLE_QUOTE_ID
//| REVERSE_QUOTE_ID
| CHARSET_REVERSE_QOUTE_STRING
| STRING_LITERAL
;
simpleId
: ID
| charsetNameBase
| transactionLevelBase
| engineNameBase
| privilegesBase
| intervalTypeBase
| dataTypeBase
| keywordsCanBeId
| scalarFunctionName
;
dottedId
: DOT_ID
| '.' uid
;
// Literals
decimalLiteral
: DECIMAL_LITERAL
| ZERO_DECIMAL
| ONE_DECIMAL
| TWO_DECIMAL
| REAL_LITERAL
;
fileSizeLiteral
: FILESIZE_LITERAL
| decimalLiteral
;
stringLiteral
: (STRING_CHARSET_NAME? STRING_LITERAL | START_NATIONAL_STRING_LITERAL) STRING_LITERAL+
| (STRING_CHARSET_NAME? STRING_LITERAL | START_NATIONAL_STRING_LITERAL) (COLLATE collationName)?
;
booleanLiteral
: TRUE
| FALSE
;
hexadecimalLiteral
: STRING_CHARSET_NAME? HEXADECIMAL_LITERAL
;
nullNotnull
: NOT? (NULL_LITERAL | NULL_SPEC_LITERAL)
;
constant
: stringLiteral
| decimalLiteral
| '-' decimalLiteral
| hexadecimalLiteral
| booleanLiteral
| REAL_LITERAL
| BIT_STRING
| NOT? nullLiteral = (NULL_LITERAL | NULL_SPEC_LITERAL)
;
// Data Types
dataType
: typeName = (
CHAR
| CHARACTER
| VARCHAR
| TINYTEXT
| TEXT
| MEDIUMTEXT
| LONGTEXT
| NCHAR
| NVARCHAR
| LONG
) VARYING? lengthOneDimension? BINARY? (charSet charsetName)? (COLLATE collationName | BINARY)? # stringDataType
| NATIONAL typeName = (CHAR | CHARACTER) VARYING lengthOneDimension? BINARY? # nationalVaryingStringDataType
| NATIONAL typeName = (VARCHAR | CHARACTER | CHAR) lengthOneDimension? BINARY? # nationalStringDataType
| NCHAR typeName = VARCHAR lengthOneDimension? BINARY? # nationalStringDataType
| typeName = (
TINYINT
| SMALLINT
| MEDIUMINT
| INT
| INTEGER
| BIGINT
| MIDDLEINT
| INT1
| INT2
| INT3
| INT4
| INT8
) lengthOneDimension? (SIGNED | UNSIGNED | ZEROFILL)* # dimensionDataType
| typeName = REAL lengthTwoDimension? (SIGNED | UNSIGNED | ZEROFILL)* # dimensionDataType
| typeName = DOUBLE PRECISION? lengthTwoDimension? (SIGNED | UNSIGNED | ZEROFILL)* # dimensionDataType
| typeName = (DECIMAL | DEC | FIXED | NUMERIC | FLOAT | FLOAT4 | FLOAT8) lengthTwoOptionalDimension? (
SIGNED
| UNSIGNED
| ZEROFILL
)* # dimensionDataType
| typeName = (DATE | TINYBLOB | MEDIUMBLOB | LONGBLOB | BOOL | BOOLEAN | SERIAL) # simpleDataType
| typeName = (BIT | TIME | TIMESTAMP | DATETIME | BINARY | VARBINARY | BLOB | YEAR | VECTOR) lengthOneDimension? # dimensionDataType
| typeName = (ENUM | SET) collectionOptions BINARY? (charSet charsetName)? # collectionDataType
| typeName = (
GEOMETRYCOLLECTION
| GEOMCOLLECTION
| LINESTRING
| MULTILINESTRING
| MULTIPOINT
| MULTIPOLYGON
| POINT
| POLYGON
| JSON
| GEOMETRY
) (SRID decimalLiteral)? # spatialDataType
| typeName = LONG VARCHAR? BINARY? (charSet charsetName)? (COLLATE collationName)? # longVarcharDataType // LONG VARCHAR is the same as LONG
| LONG VARBINARY # longVarbinaryDataType
;
collectionOptions
: '(' collectionOption (',' collectionOption)* ')'
;
collectionOption
: STRING_LITERAL
;
convertedDataType
: (
typeName = (BINARY | NCHAR | FLOAT) lengthOneDimension?
| typeName = CHAR lengthOneDimension? (charSet charsetName)?
| typeName = (DATE | DATETIME | TIME | YEAR | JSON | INT | INTEGER | DOUBLE)
| typeName = (DECIMAL | DEC) lengthTwoOptionalDimension?
| (SIGNED | UNSIGNED) (INTEGER | INT)?
) ARRAY?
;
lengthOneDimension
: '(' decimalLiteral ')'
;
lengthTwoDimension
: '(' decimalLiteral ',' decimalLiteral ')'
;
lengthTwoOptionalDimension
: '(' decimalLiteral (',' decimalLiteral)? ')'
;
// Common Lists
uidList
: uid (',' uid)*
;
fullColumnNameList
: fullColumnName (',' fullColumnName)*
;
tables
: tableName (',' tableName)*
;
indexColumnNames
: '(' indexColumnName (',' indexColumnName)* ')'
;
expressions
: expression (',' expression)*
;
expressionsWithDefaults
: expressionOrDefault (',' expressionOrDefault)*
;
constants
: constant (',' constant)*
;
simpleStrings
: STRING_LITERAL (',' STRING_LITERAL)*
;
userVariables
: LOCAL_ID (',' LOCAL_ID)*
;
// Common Expressons
defaultValue
: NULL_LITERAL
| CAST '(' expression AS convertedDataType ')'
| unaryOperator? constant
| currentTimestamp (ON UPDATE currentTimestamp)?
| '(' expression ')'
| '(' fullId ')'
;
currentTimestamp
: (
(CURRENT_TIMESTAMP | LOCALTIME | LOCALTIMESTAMP) ('(' decimalLiteral? ')')?
| NOW '(' decimalLiteral? ')'
)
;
expressionOrDefault
: expression
| DEFAULT
;
ifExists
: IF EXISTS
;
ifNotExists
: IF NOT EXISTS
;
orReplace
: OR REPLACE
;
// Functions
functionCall
: specificFunction # specificFunctionCall
| aggregateWindowedFunction # aggregateFunctionCall
| nonAggregateWindowedFunction # nonAggregateFunctionCall
| scalarFunctionName '(' functionArgs? ')' # scalarFunctionCall
| fullId '(' functionArgs? ')' # udfFunctionCall
| passwordFunctionClause # passwordFunctionCall
;
specificFunction
: (CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP | LOCALTIME | UTC_TIMESTAMP | SCHEMA) (
'(' ')'
)? # simpleFunctionCall
| currentUserExpression # currentUser
| CONVERT '(' expression separator = ',' convertedDataType ')' # dataTypeFunctionCall
| CONVERT '(' expression USING charsetName ')' # dataTypeFunctionCall
| CAST '(' expression AS convertedDataType ')' # dataTypeFunctionCall
| VALUES '(' fullColumnName ')' # valuesFunctionCall
| CASE expression caseFuncAlternative+ (ELSE elseArg = functionArg)? END # caseExpressionFunctionCall
| CASE caseFuncAlternative+ (ELSE elseArg = functionArg)? END # caseFunctionCall
| CHAR '(' functionArgs (USING charsetName)? ')' # charFunctionCall
| POSITION '(' (positionString = stringLiteral | positionExpression = expression) IN (
inString = stringLiteral
| inExpression = expression
) ')' # positionFunctionCall
| (SUBSTR | SUBSTRING) '(' (sourceString = stringLiteral | sourceExpression = expression) FROM (
fromDecimal = decimalLiteral
| fromExpression = expression
) (FOR ( forDecimal = decimalLiteral | forExpression = expression))? ')' # substrFunctionCall
| TRIM '(' positioinForm = (BOTH | LEADING | TRAILING) (
sourceString = stringLiteral
| sourceExpression = expression
)? FROM (fromString = stringLiteral | fromExpression = expression) ')' # trimFunctionCall
| TRIM '(' (sourceString = stringLiteral | sourceExpression = expression) FROM (
fromString = stringLiteral
| fromExpression = expression
) ')' # trimFunctionCall
| WEIGHT_STRING '(' (stringLiteral | expression) (
AS stringFormat = (CHAR | BINARY) '(' decimalLiteral ')'
)? levelsInWeightString? ')' # weightFunctionCall
| EXTRACT '(' intervalType FROM (sourceString = stringLiteral | sourceExpression = expression) ')' # extractFunctionCall
| GET_FORMAT '(' datetimeFormat = (DATE | TIME | DATETIME) ',' stringLiteral ')' # getFormatFunctionCall
| JSON_VALUE '(' expression ',' expression (RETURNING convertedDataType)? jsonOnEmpty? jsonOnError? ')' # jsonValueFunctionCall
;
caseFuncAlternative
: WHEN condition = functionArg THEN consequent = functionArg
;
levelsInWeightString
: LEVEL levelInWeightListElement (',' levelInWeightListElement)* # levelWeightList
| LEVEL firstLevel = decimalLiteral '-' lastLevel = decimalLiteral # levelWeightRange
;
levelInWeightListElement
: decimalLiteral orderType = (ASC | DESC | REVERSE)?
;
aggregateWindowedFunction
: (AVG | MAX | MIN | SUM) '(' aggregator = (ALL | DISTINCT)? functionArg ')' overClause?
| COUNT '(' (
starArg = '*'
| aggregator = ALL? functionArg
| aggregator = DISTINCT functionArgs
) ')' overClause?
| (
BIT_AND
| BIT_OR
| BIT_XOR
| STD
| STDDEV
| STDDEV_POP
| STDDEV_SAMP
| VAR_POP
| VAR_SAMP
| VARIANCE
) '(' aggregator = ALL? functionArg ')' overClause?
| GROUP_CONCAT '(' aggregator = DISTINCT? functionArgs (
ORDER BY orderByExpression (',' orderByExpression)*
)? (SEPARATOR separator = STRING_LITERAL)? ')'
;
nonAggregateWindowedFunction
: (LAG | LEAD) '(' expression (',' decimalLiteral)? (',' (decimalLiteral | NULL_LITERAL))? ')' overClause
| (FIRST_VALUE | LAST_VALUE) '(' expression ')' overClause
| (CUME_DIST | DENSE_RANK | PERCENT_RANK | RANK | ROW_NUMBER) '(' ')' overClause
| NTH_VALUE '(' expression ',' decimalLiteral ')' overClause
| NTILE '(' decimalLiteral ')' overClause
;
overClause
: OVER ('(' windowSpec? ')' | windowName)
;
windowSpec
: windowName? partitionClause? orderByClause? frameClause?
;
windowName
: uid
;
frameClause
: frameUnits frameExtent
;
frameUnits
: ROWS
| RANGE
;
frameExtent
: frameRange
| frameBetween
;
frameBetween
: BETWEEN frameRange AND frameRange
;
frameRange
: CURRENT ROW
| UNBOUNDED (PRECEDING | FOLLOWING)
| expression (PRECEDING | FOLLOWING)
;
partitionClause
: PARTITION BY expression (',' expression)*
;
sequenceFunctionName
: SEQUENCE_TABLE
| PERCONA_SEQUENCE_TABLE
;
scalarFunctionName
: functionNameBase
| ASCII
| CURDATE
| CURRENT_DATE
| CURRENT_TIME
| CURRENT_TIMESTAMP
| CURTIME
| DATE_ADD
| DATE_SUB
| IF
| INSERT
| LOCALTIME
| LOCALTIMESTAMP
| MID
| NOW
| REPEAT
| REPLACE
| SUBSTR
| SUBSTRING
| SYSDATE
| TRIM
| UTC_DATE
| UTC_TIME
| UTC_TIMESTAMP
;
passwordFunctionClause
: functionName = (PASSWORD | OLD_PASSWORD) '(' functionArg ')'
;
functionArgs
: (constant | fullColumnName | functionCall | expression) (
',' (constant | fullColumnName | functionCall | expression)
)*
;
functionArg
: constant
| fullColumnName
| functionCall
| expression
;
// Expressions, predicates
// Simplified approach for expression
expression
: notOperator = (NOT | '!') expression # notExpression
| expression logicalOperator expression # logicalExpression
| predicate IS NOT? testValue = (TRUE | FALSE | UNKNOWN) # isExpression
| predicate # predicateExpression
;
predicate
: predicate NOT? IN '(' (selectStatement | expressions) ')' # inPredicate
| predicate IS nullNotnull # isNullPredicate
| left = predicate comparisonOperator right = predicate # binaryComparisonPredicate
| predicate comparisonOperator quantifier = (ALL | ANY | SOME) '(' selectStatement ')' # subqueryComparisonPredicate
| predicate NOT? BETWEEN predicate AND predicate # betweenPredicate
| predicate SOUNDS LIKE predicate # soundsLikePredicate
| predicate NOT? LIKE predicate (ESCAPE STRING_LITERAL)? # likePredicate
| predicate NOT? regex = (REGEXP | RLIKE) predicate # regexpPredicate
| predicate MEMBER OF '(' predicate ')' # jsonMemberOfPredicate
| expressionAtom # expressionAtomPredicate
;
// Add in ASTVisitor nullNotnull in constant
expressionAtom
: constant # constantExpressionAtom
| fullColumnName # fullColumnNameExpressionAtom
| functionCall # functionCallExpressionAtom
| expressionAtom COLLATE collationName # collateExpressionAtom
| mysqlVariable # mysqlVariableExpressionAtom
| unaryOperator expressionAtom # unaryExpressionAtom
| BINARY expressionAtom # binaryExpressionAtom
| LOCAL_ID VAR_ASSIGN expressionAtom # variableAssignExpressionAtom
| '(' expression (',' expression)* ')' # nestedExpressionAtom
| ROW '(' expression (',' expression)+ ')' # nestedRowExpressionAtom
| EXISTS '(' selectStatement ')' # existsExpressionAtom
| '(' selectStatement ')' # subqueryExpressionAtom
| INTERVAL expression intervalType # intervalExpressionAtom
| left = expressionAtom bitOperator right = expressionAtom # bitExpressionAtom
| left = expressionAtom multOperator right = expressionAtom # mathExpressionAtom
| left = expressionAtom addOperator right = expressionAtom # mathExpressionAtom
| left = expressionAtom jsonOperator right = expressionAtom # jsonExpressionAtom
;
unaryOperator
: '!'
| '~'
| '+'
| '-'
| NOT
;
comparisonOperator
: '='
| '>'
| '<'
| '<' '='
| '>' '='
| '<' '>'
| '!' '='
| '<' '=' '>'
;
logicalOperator
: AND
| '&' '&'
| XOR
| OR
| '|' '|'
;
bitOperator
: '<' '<'
| '>' '>'
| '&'
| '^'
| '|'
;
multOperator
: '*'
| '/'
| '%'
| DIV
| MOD
;
addOperator
: '+'
| '-'
;
jsonOperator
: '-' '>'
| '-' '>' '>'
;
// Simple id sets
// (that keyword, which can be id)
charsetNameBase
: ARMSCII8
| ASCII
| BIG5
| BINARY
| CP1250
| CP1251
| CP1256
| CP1257
| CP850
| CP852
| CP866
| CP932
| DEC8
| EUCJPMS
| EUCKR
| GB18030
| GB2312
| GBK
| GEOSTD8
| GREEK
| HEBREW
| HP8
| KEYBCS2
| KOI8R
| KOI8U
| LATIN1
| LATIN2
| LATIN5
| LATIN7
| MACCE
| MACROMAN
| SJIS
| SWE7
| TIS620
| UCS2
| UJIS
| UTF16
| UTF16LE
| UTF32
| UTF8
| UTF8MB3
| UTF8MB4
;
transactionLevelBase
: REPEATABLE
| COMMITTED
| UNCOMMITTED
| SERIALIZABLE
;
privilegesBase
: TABLES
| ROUTINE
| EXECUTE
| FILE
| PROCESS
| RELOAD
| SHUTDOWN
| SUPER
| PRIVILEGES
;
intervalTypeBase
: QUARTER
| MONTH
| DAY
| HOUR
| MINUTE
| WEEK
| SECOND
| MICROSECOND
;
dataTypeBase
: DATE
| TIME
| TIMESTAMP
| DATETIME
| YEAR
| ENUM
| TEXT
;
keywordsCanBeId
: ACCOUNT
| ACTION
| ADMIN
| AFTER
| AGGREGATE
| ALGORITHM
| ANY
| APPLICATION_PASSWORD_ADMIN
| ARRAY
| AT
| AUDIT_ADMIN
| AUDIT_ABORT_EXEMPT
| AUTHORS
| AUTOCOMMIT
| AUTOEXTEND_SIZE
| AUTO_INCREMENT
| AUTHENTICATION_POLICY_ADMIN
| AVG
| AVG_ROW_LENGTH
| ATTRIBUTE
| BACKUP_ADMIN
| BEGIN
| BINLOG
| BINLOG_ADMIN
| BINLOG_ENCRYPTION_ADMIN
| BIT
| BIT_AND
| BIT_OR
| BIT_XOR
| BLOCK
| BOOL
| BOOLEAN
| BTREE
| BUCKETS
| CACHE
| CASCADED
| CHAIN
| CHANGED
| CHANNEL
| CHECKSUM
| PAGE_CHECKSUM
| CATALOG_NAME
| CIPHER
| CLASS_ORIGIN
| CLIENT
| CLONE_ADMIN
| CLOSE
| CLUSTERING
| COALESCE
| CODE
| COLUMNS
| COLUMN_FORMAT
| COLUMN_NAME
| COMMENT
| COMMIT
| COMPACT
| COMPLETION
| COMPRESSED
| COMPRESSION
| CONCURRENT
| CONDITION
| CONNECT
| CONNECTION
| CONNECTION_ADMIN
| CONSISTENT
| CONSTRAINT_CATALOG
| CONSTRAINT_NAME
| CONSTRAINT_SCHEMA
| CONTAINS
| CONTEXT
| CONTRIBUTORS
| COPY
| COUNT
| CPU
| CURRENT
| CURRENT_USER
| CURSOR_NAME
| DATA
| DATAFILE
| DEALLOCATE
| DEFAULT
| DEFAULT_AUTH
| DEFINER
| DELAY_KEY_WRITE
| DES_KEY_FILE
| DIAGNOSTICS
| DIRECTORY
| DISABLE
| DISCARD
| DISK
| DO
| DUMPFILE
| DUPLICATE
| DYNAMIC
| EMPTY
| ENABLE
| ENCRYPTION
| ENCRYPTION_KEY_ADMIN
| END
| ENDS
| ENGINE
| ENGINE_ATTRIBUTE
| ENGINES
| ENFORCED
| ERROR
| ERRORS
| ESCAPE
| EUR
| EVEN
| EVENT
| EVENTS
| EVERY
| EXCEPT
| EXCHANGE
| EXCLUSIVE
| EXPIRE
| EXPORT
| EXTENDED
| EXTENT_SIZE
| FAILED_LOGIN_ATTEMPTS
| FAST
| FAULTS
| FIELDS
| FILE_BLOCK_SIZE
| FILTER
| FIREWALL_ADMIN
| FIREWALL_EXEMPT
| FIREWALL_USER
| FIRST
| FIXED
| FLUSH
| FLUSH_OPTIMIZER_COSTS
| FLUSH_STATUS
| FLUSH_TABLES
| FLUSH_USER_RESOURCES
| FOLLOWS
| FOUND
| FULL
| FUNCTION
| GENERAL
| GEOMETRY
| GLOBAL
| GRANTS
| GROUP
| GROUP_CONCAT
| GROUP_REPLICATION
| GROUP_REPLICATION_ADMIN
| HANDLER
| HASH
| HELP
| HISTORY
| HOST
| HOSTS
| IDENTIFIED
| IGNORED
| IGNORE_SERVER_IDS
| IMPORT
| INDEXES
| INITIAL_SIZE
| INNODB_REDO_LOG_ARCHIVE
| INNODB_REDO_LOG_ENABLE
| INPLACE
| INSERT_METHOD
| INSTALL
| INSTANCE
| INSTANT
| INTERNAL
| INVOKE
| INVOKER
| IO
| IO_THREAD
| IPC
| ISO
| ISOLATION
| ISSUER
| JIS
| JSON
| KEY_BLOCK_SIZE
| LAMBDA
| LANGUAGE
| LAST
| LATERAL
| LEAVES
| LESS
| LEVEL
| LIST
| LOCAL
| LOGFILE
| LOGS
| MASTER
| MASTER_AUTO_POSITION
| MASTER_CONNECT_RETRY
| MASTER_DELAY
| MASTER_HEARTBEAT_PERIOD
| MASTER_HOST
| MASTER_LOG_FILE
| MASTER_LOG_POS
| MASTER_PASSWORD
| MASTER_PORT
| MASTER_RETRY_COUNT
| MASTER_SSL
| MASTER_SSL_CA
| MASTER_SSL_CAPATH
| MASTER_SSL_CERT
| MASTER_SSL_CIPHER
| MASTER_SSL_CRL
| MASTER_SSL_CRLPATH
| MASTER_SSL_KEY
| MASTER_TLS_VERSION
| MASTER_USER
| MAX_CONNECTIONS_PER_HOUR
| MAX_QUERIES_PER_HOUR
| MAX
| MAX_ROWS
| MAX_SIZE
| MAX_UPDATES_PER_HOUR
| MAX_USER_CONNECTIONS
| MEDIUM
| MEMBER
| MEMORY
| MERGE
| MESSAGE_TEXT
| MID
| MIGRATE
| MIN
| MIN_ROWS
| MODE
| MODIFY
| MUTEX
| MYSQL
| MYSQL_ERRNO
| NAME
| NAMES
| NATIONAL
| NCHAR
| NDB_STORED_USER
| NESTED
| NEVER
| NEXT
| NO
| NOCOPY
| NODEGROUP
| NONE
| NOWAIT
| NUMBER
| ODBC
| OFFLINE
| OFFSET
| OF
| OJ
| OLD_PASSWORD
| ONE
| ONLINE
| ONLY
| OPEN
| OPTIMIZER_COSTS
| OPTIONAL
| OPTIONS
| ORDER
| ORDINALITY
| OWNER
| PACK_KEYS
| PAGE
| PARSER
| PARTIAL
| PARTITIONING
| PARTITIONS
| PASSWORD
| PASSWORDLESS_USER_ADMIN
| PASSWORD_LOCK_TIME
| PATH
| PERCONA_SEQUENCE_TABLE
| PERSIST_RO_VARIABLES_ADMIN
| PHASE
| PLUGINS
| PLUGIN_DIR
| PLUGIN
| PORT
| PRECEDES
| PREPARE
| PRESERVE
| PREV
| PRIMARY
| PROCESSLIST
| PROFILE
| PROFILES
| PROXY
| QUERY
| QUICK
| REBUILD
| RECOVER
| RECURSIVE
| REDO_BUFFER_SIZE
| REDUNDANT
| RELAY
| RELAYLOG
| RELAY_LOG_FILE
| RELAY_LOG_POS
| REMOVE
| REORGANIZE
| REPAIR
| REPLICATE_DO_DB
| REPLICATE_DO_TABLE
| REPLICATE_IGNORE_DB
| REPLICATE_IGNORE_TABLE
| REPLICATE_REWRITE_DB
| REPLICATE_WILD_DO_TABLE
| REPLICATE_WILD_IGNORE_TABLE
| REPLICATION
| REPLICATION_APPLIER
| REPLICATION_SLAVE_ADMIN
| RESET
| RESOURCE_GROUP_ADMIN
| RESOURCE_GROUP_USER
| RESUME
| RETURNED_SQLSTATE
| RETURNING
| RETURNS
| REUSE
| ROLE
| ROLE_ADMIN
| ROLLBACK
| ROLLUP
| ROTATE
| ROW
| ROWS
| ROW_FORMAT
| RTREE
| S3
| SAVEPOINT
| SCHEDULE
| SCHEMA_NAME
| SECURITY
| SECONDARY_ENGINE_ATTRIBUTE
| SEQUENCE_TABLE
| SERIAL
| SERVER
| SESSION
| SESSION_VARIABLES_ADMIN
| SET_USER_ID
| SHARE
| SHARED
| SHOW_ROUTINE
| SIGNED
| SIMPLE
| SLAVE
| SLOW
| SKIP_QUERY_REWRITE
| SNAPSHOT
| SOCKET
| SOME
| SONAME
| SOUNDS
| SOURCE
| SQL_AFTER_GTIDS
| SQL_AFTER_MTS_GAPS
| SQL_BEFORE_GTIDS
| SQL_BUFFER_RESULT
| SQL_CACHE
| SQL_NO_CACHE
| SQL_THREAD
| STACKED
| START
| STARTS
| STATS_AUTO_RECALC
| STATS_PERSISTENT
| STATS_SAMPLE_PAGES
| STATUS
| STD
| STDDEV
| STDDEV_POP
| STDDEV_SAMP
| STOP
| STORAGE
| STRING
| SUBCLASS_ORIGIN
| SUBJECT
| SUBPARTITION
| SUBPARTITIONS
| SUM
| SUSPEND
| SWAPS
| SWITCHES
| SYSTEM_VARIABLES_ADMIN
| SYSTEM_USER
| TABLE_NAME
| TABLESPACE
| TABLE_ENCRYPTION_ADMIN
| TABLE_TYPE
| TELEMETRY_LOG_ADMIN
| TEMPORARY
| TEMPTABLE
| THAN
| TP_CONNECTION_ADMIN
| TRADITIONAL
| TRANSACTION
| TRANSACTIONAL
| TRIGGERS
| TRUNCATE
| UNBOUNDED
| UNDEFINED
| UNDOFILE
| UNDO_BUFFER_SIZE
| UNINSTALL
| UNKNOWN
| UNTIL
| UPGRADE
| USA
| USER
| USE_FRM
| USER_RESOURCES
| VALIDATION
| VALUE
| VAR_POP
| VAR_SAMP
| VARIABLES
| VARIANCE
| VERSION_TOKEN_ADMIN
| VIEW
| VIRTUAL
| WAIT
| WARNINGS
| WITHOUT
| WORK
| WRAPPER
| X509
| XA
| XA_RECOVER_ADMIN
| XML
| YES
;
functionNameBase
: ABS
| ACOS
| ADDDATE
| ADDTIME
| AES_DECRYPT
| AES_ENCRYPT
| AREA
| ASBINARY
| ASIN
| ASTEXT
| ASWKB
| ASWKT
| ASYMMETRIC_DECRYPT
| ASYMMETRIC_DERIVE
| ASYMMETRIC_ENCRYPT
| ASYMMETRIC_SIGN
| ASYMMETRIC_VERIFY
| ATAN
| ATAN2
| BENCHMARK
| BIN
| BIT_COUNT
| BIT_LENGTH
| BUFFER
| CEIL
| CEILING
| CENTROID
| CHARACTER_LENGTH
| CHARSET
| CHAR_LENGTH
| COERCIBILITY
| COLLATION
| COMPRESS
| CONCAT
| CONCAT_WS
| CONNECTION_ID
| CONV
| CONVERT_TZ
| COS
| COT
| COUNT
| CRC32
| CREATE_ASYMMETRIC_PRIV_KEY
| CREATE_ASYMMETRIC_PUB_KEY
| CREATE_DH_PARAMETERS
| CREATE_DIGEST
| CROSSES
| CUME_DIST
| DATABASE
| DATE
| DATEDIFF
| DATE_FORMAT
| DAY
| DAYNAME
| DAYOFMONTH
| DAYOFWEEK
| DAYOFYEAR
| DECODE
| DEGREES
| DENSE_RANK
| DES_DECRYPT
| DES_ENCRYPT
| DIMENSION
| DISJOINT
| DISTANCE
| ELT
| ENCODE
| ENCRYPT
| ENDPOINT
| ENVELOPE
| EQUALS
| EXP
| EXPORT_SET
| EXTERIORRING
| EXTRACTVALUE
| FIELD
| FIND_IN_SET
| FIRST_VALUE
| FLOOR
| FORMAT
| FOUND_ROWS
| FROM_BASE64
| FROM_DAYS
| FROM_UNIXTIME
| GEOMCOLLFROMTEXT
| GEOMCOLLFROMWKB
| GEOMETRYCOLLECTION
| GEOMETRYCOLLECTIONFROMTEXT
| GEOMETRYCOLLECTIONFROMWKB
| GEOMETRYFROMTEXT
| GEOMETRYFROMWKB
| GEOMETRYN
| GEOMETRYTYPE
| GEOMFROMTEXT
| GEOMFROMWKB
| GET_FORMAT
| GET_LOCK
| GLENGTH
| GREATEST
| GTID_SUBSET
| GTID_SUBTRACT
| HEX
| HOUR
| IFNULL
| INET6_ATON
| INET6_NTOA
| INET_ATON
| INET_NTOA
| INSTR
| INTERIORRINGN
| INTERSECTS
| INVISIBLE
| ISCLOSED
| ISEMPTY
| ISNULL
| ISSIMPLE
| IS_FREE_LOCK
| IS_IPV4
| IS_IPV4_COMPAT
| IS_IPV4_MAPPED
| IS_IPV6
| IS_USED_LOCK
| LAG
| LAST_INSERT_ID
| LAST_VALUE
| LCASE
| LEAD
| LEAST
| LEFT
| LENGTH
| LINEFROMTEXT
| LINEFROMWKB
| LINESTRING
| LINESTRINGFROMTEXT
| LINESTRINGFROMWKB
| LN
| LOAD_FILE
| LOCATE
| LOG
| LOG10
| LOG2
| LOWER
| LPAD
| LTRIM
| MAKEDATE
| MAKETIME
| MAKE_SET
| MASTER_POS_WAIT
| MBRCONTAINS
| MBRDISJOINT
| MBREQUAL
| MBRINTERSECTS
| MBROVERLAPS
| MBRTOUCHES
| MBRWITHIN
| MD5
| MICROSECOND
| MINUTE
| MLINEFROMTEXT
| MLINEFROMWKB
| MOD
| MONTH
| MONTHNAME
| MPOINTFROMTEXT
| MPOINTFROMWKB
| MPOLYFROMTEXT
| MPOLYFROMWKB
| MULTILINESTRING
| MULTILINESTRINGFROMTEXT
| MULTILINESTRINGFROMWKB
| MULTIPOINT
| MULTIPOINTFROMTEXT
| MULTIPOINTFROMWKB
| MULTIPOLYGON
| MULTIPOLYGONFROMTEXT
| MULTIPOLYGONFROMWKB
| NAME_CONST
| NTH_VALUE
| NTILE
| NULLIF
| NUMGEOMETRIES
| NUMINTERIORRINGS
| NUMPOINTS
| OCT
| OCTET_LENGTH
| ORD
| OVERLAPS
| PERCENT_RANK
| PERIOD_ADD
| PERIOD_DIFF
| PI
| POINT
| POINTFROMTEXT
| POINTFROMWKB
| POINTN
| POLYFROMTEXT
| POLYFROMWKB
| POLYGON
| POLYGONFROMTEXT
| POLYGONFROMWKB
| POSITION
| POW
| POWER
| QUARTER
| QUOTE
| RADIANS
| RAND
| RANDOM
| RANK
| RANDOM_BYTES
| RELEASE_LOCK
| REVERSE
| RIGHT
| ROUND
| ROW_COUNT
| ROW_NUMBER
| RPAD
| RTRIM
| SCHEMA
| SECOND
| SEC_TO_TIME
| SESSION_USER
| SESSION_VARIABLES_ADMIN
| SHA
| SHA1
| SHA2
| SIGN
| SIN
| SLEEP
| SOUNDEX
| SQL_THREAD_WAIT_AFTER_GTIDS
| SQRT
| SRID
| STARTPOINT
| STRCMP
| STR_TO_DATE
| ST_AREA
| ST_ASBINARY
| ST_ASTEXT
| ST_ASWKB
| ST_ASWKT
| ST_BUFFER
| ST_CENTROID
| ST_CONTAINS
| ST_CROSSES
| ST_DIFFERENCE
| ST_DIMENSION
| ST_DISJOINT
| ST_DISTANCE
| ST_ENDPOINT
| ST_ENVELOPE
| ST_EQUALS
| ST_EXTERIORRING
| ST_GEOMCOLLFROMTEXT
| ST_GEOMCOLLFROMTXT
| ST_GEOMCOLLFROMWKB
| ST_GEOMETRYCOLLECTIONFROMTEXT
| ST_GEOMETRYCOLLECTIONFROMWKB
| ST_GEOMETRYFROMTEXT
| ST_GEOMETRYFROMWKB
| ST_GEOMETRYN
| ST_GEOMETRYTYPE
| ST_GEOMFROMTEXT
| ST_GEOMFROMWKB
| ST_INTERIORRINGN
| ST_INTERSECTION
| ST_INTERSECTS
| ST_ISCLOSED
| ST_ISEMPTY
| ST_ISSIMPLE
| ST_LINEFROMTEXT
| ST_LINEFROMWKB
| ST_LINESTRINGFROMTEXT
| ST_LINESTRINGFROMWKB
| ST_NUMGEOMETRIES
| ST_NUMINTERIORRING
| ST_NUMINTERIORRINGS
| ST_NUMPOINTS
| ST_OVERLAPS
| ST_POINTFROMTEXT
| ST_POINTFROMWKB
| ST_POINTN
| ST_POLYFROMTEXT
| ST_POLYFROMWKB
| ST_POLYGONFROMTEXT
| ST_POLYGONFROMWKB
| ST_SRID
| ST_STARTPOINT
| ST_SYMDIFFERENCE
| ST_TOUCHES
| ST_UNION
| ST_WITHIN
| ST_X
| ST_Y
| STRING_TO_VECTOR
| SUBDATE
| SUBSTRING_INDEX
| SUBTIME
| SYSTEM_USER
| TAN
| TIME
| TIMEDIFF
| TIMESTAMP
| TIMESTAMPADD
| TIMESTAMPDIFF
| TIME_FORMAT
| TIME_TO_SEC
| TOUCHES
| TO_BASE64
| TO_DAYS
| TO_SECONDS
| UCASE
| UNCOMPRESS
| UNCOMPRESSED_LENGTH
| UNHEX
| UNIX_TIMESTAMP
| UPDATEXML
| UPPER
| UUID
| UUID_SHORT
| VALIDATE_PASSWORD_STRENGTH
| VECTOR_DIM
| VECTOR_TO_STRING
| VERSION
| VISIBLE
| WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS
| WEEK
| WEEKDAY
| WEEKOFYEAR
| WEIGHT_STRING
| WITHIN
| YEAR
| YEARWEEK
| Y_FUNCTION
| X_FUNCTION
| JSON_ARRAY
| JSON_OBJECT
| JSON_QUOTE
| JSON_CONTAINS
| JSON_CONTAINS_PATH
| JSON_EXTRACT
| JSON_KEYS
| JSON_OVERLAPS
| JSON_SEARCH
| JSON_VALUE
| JSON_ARRAY_APPEND
| JSON_ARRAY_INSERT
| JSON_INSERT
| JSON_MERGE
| JSON_MERGE_PATCH
| JSON_MERGE_PRESERVE
| JSON_REMOVE
| JSON_REPLACE
| JSON_SET
| JSON_UNQUOTE
| JSON_DEPTH
| JSON_LENGTH
| JSON_TYPE
| JSON_VALID
| JSON_TABLE
| JSON_SCHEMA_VALID
| JSON_SCHEMA_VALIDATION_REPORT
| JSON_PRETTY
| JSON_STORAGE_FREE
| JSON_STORAGE_SIZE
| JSON_ARRAYAGG
| JSON_OBJECTAGG
| STATEMENT
;
================================================
FILE: superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/AbstractSqlParser.kt
================================================
package io.github.melin.superior.parser.mysql
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.parser.mysql.antlr4.MySqlParser
import java.util.concurrent.atomic.AtomicReference
object AbstractSqlParser {
private val parserCaches = AtomicReference(AntlrCaches(MySqlParser._ATN))
/**
* Install the parser caches into the given parser.
*
* This method should be called before parsing any input.
*/
fun installCaches(parser: MySqlParser): Unit = parserCaches.get().installCaches(parser)
/**
* Drop the existing parser caches and create a new one.
*
* ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can
* consume a lot of memory depending on the input seen so far.
*
* This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL
* inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.
*/
fun refreshParserCaches() {
parserCaches.set(AntlrCaches(MySqlParser._ATN))
}
}
================================================
FILE: superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/MySqlAntlr4Visitor.kt
================================================
package io.github.melin.superior.parser.mysql
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.*
import io.github.melin.superior.common.AlterActionType.*
import io.github.melin.superior.common.antlr4.ParserUtils.source
import io.github.melin.superior.common.relational.*
import io.github.melin.superior.common.relational.alter.*
import io.github.melin.superior.common.relational.common.ShowStatement
import io.github.melin.superior.common.relational.common.UseDatabase
import io.github.melin.superior.common.relational.create.*
import io.github.melin.superior.common.relational.dml.*
import io.github.melin.superior.common.relational.drop.DropDatabase
import io.github.melin.superior.common.relational.drop.DropTable
import io.github.melin.superior.common.relational.table.ColumnRel
import io.github.melin.superior.common.relational.table.TruncateTable
import io.github.melin.superior.parser.mysql.antlr4.MySqlParser
import io.github.melin.superior.parser.mysql.antlr4.MySqlParser.AlterByAddIndexContext
import io.github.melin.superior.parser.mysql.antlr4.MySqlParser.AlterByAddPrimaryKeyContext
import io.github.melin.superior.parser.mysql.antlr4.MySqlParser.AlterByDropPrimaryKeyContext
import io.github.melin.superior.parser.mysql.antlr4.MySqlParser.AlterByTruncatePartitionContext
import io.github.melin.superior.parser.mysql.antlr4.MySqlParser.PartitionFunctionHashContext
import io.github.melin.superior.parser.mysql.antlr4.MySqlParser.PartitionFunctionKeyContext
import io.github.melin.superior.parser.mysql.antlr4.MySqlParser.PartitionFunctionListContext
import io.github.melin.superior.parser.mysql.antlr4.MySqlParser.PartitionFunctionRangeContext
import io.github.melin.superior.parser.mysql.antlr4.MySqlParserBaseVisitor
import org.antlr.v4.runtime.tree.TerminalNodeImpl
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2018/2/8. */
class MySqlAntlr4Visitor(val splitSql: Boolean = false) : MySqlParserBaseVisitor() {
private var currentOptType: StatementType = StatementType.UNKOWN
private var limit: Int? = null
private var offset: Int? = null
private val primaryKeys = ArrayList()
private var inputTables: ArrayList = arrayListOf()
private var inCte = false
private var cteTempTables: ArrayList = arrayListOf()
// 多语句解析结果
private var statements: ArrayList = arrayListOf()
// 存储过程和函数中包含的子语句
private var childStatements: ArrayList = arrayListOf()
private val sqls: ArrayList = arrayListOf()
fun getSqlStatements(): List {
return statements
}
fun getSplitSqls(): List {
return sqls
}
override fun visitSqlStatements(ctx: MySqlParser.SqlStatementsContext): Statement? {
ctx.sqlStatement().forEach {
var sql = source(it)
if (splitSql) {
if (StringUtils.endsWith(sql, ";")) {
sql = StringUtils.substringBeforeLast(sql, ";")
}
sqls.add(sql)
} else {
val startNode = it.start.text
val statement =
if (StringUtils.equalsIgnoreCase("show", startNode)) {
val keyWords: ArrayList = arrayListOf()
CommonUtils.findShowStatementKeyWord(keyWords, it)
ShowStatement(*keyWords.toTypedArray())
} else {
var statement = this.visitSqlStatement(it)
if (statement == null) {
statement = DefaultStatement(StatementType.UNKOWN)
}
statement
}
statement.setSql(sql)
statements.add(statement)
clean()
}
}
return null
}
override fun visitSqlStatement(ctx: MySqlParser.SqlStatementContext): Statement? {
val statement = super.visitSqlStatement(ctx)
if (
statement != null &&
statement.statementType != StatementType.CREATE_FUNCTION &&
statement.statementType != StatementType.CREATE_PROCEDURE
) {
childStatements.add(statement)
}
return statement
}
override fun visitDeclareCursor(ctx: MySqlParser.DeclareCursorContext): Statement? {
val statement = super.visitDeclareCursor(ctx)
if (
statement != null &&
statement.statementType != StatementType.CREATE_FUNCTION &&
statement.statementType != StatementType.CREATE_PROCEDURE
) {
childStatements.add(statement)
}
return statement
}
private fun clean() {
currentOptType = StatementType.UNKOWN
limit = null
offset = null
inputTables = arrayListOf()
inCte = false
cteTempTables = arrayListOf()
}
// -----------------------------------database-------------------------------------------------
override fun visitCreateDatabase(ctx: MySqlParser.CreateDatabaseContext): Statement {
val databaseName = CommonUtils.cleanQuote(ctx.uid().text)
return CreateDatabase(databaseName)
}
override fun visitDropDatabase(ctx: MySqlParser.DropDatabaseContext): Statement {
val databaseName = CommonUtils.cleanQuote(ctx.uid().text)
return DropDatabase(databaseName)
}
// -----------------------------------table-------------------------------------------------
override fun visitColumnCreateTable(ctx: MySqlParser.ColumnCreateTableContext): Statement {
val tableId = parseFullId(ctx.tableName().fullId())
var comment: String? = null
ctx.tableOption().forEach {
when (it) {
is MySqlParser.TableOptionCommentContext -> {
comment = CommonUtils.cleanQuote(it.STRING_LITERAL().text)
}
}
}
val columnRels = ArrayList()
ctx.createDefinitions().children.forEach { column ->
if (column is MySqlParser.ColumnDeclarationContext) {
val name = CommonUtils.cleanQuote(column.fullColumnName().text)
var dataType = column.columnDefinition().dataType().getChild(0).text.lowercase()
val count = column.columnDefinition().dataType().childCount
if (count > 1) {
val item = column.columnDefinition().dataType().getChild(1)
if (
item is MySqlParser.LengthOneDimensionContext ||
item is MySqlParser.LengthTwoDimensionContext ||
item is MySqlParser.LengthTwoOptionalDimensionContext
) {
dataType = dataType + item.text
}
}
var colComment: String? = null
column.columnDefinition().columnConstraint().forEach {
if (it is MySqlParser.CommentColumnConstraintContext) {
colComment = CommonUtils.cleanQuote(it.STRING_LITERAL().text)
}
}
columnRels.add(ColumnRel(name, dataType, colComment))
}
}
super.visitColumnCreateTable(ctx)
val ifNotExists: Boolean = if (ctx.ifNotExists() != null) true else false
columnRels.forEach { columnRel: ColumnRel ->
if (primaryKeys.contains(columnRel.columnName)) {
columnRel.primaryKey = true
}
}
val createTable =
CreateTable(tableId, TableType.MYSQL, comment, null, null, columnRels, null, null, ifNotExists)
if (ctx.partitionDefinitions() != null) {
val def = ctx.partitionDefinitions().partitionFunctionDefinition()
if (def is PartitionFunctionHashContext) {
createTable.partitionType = PartitionType.HASH
} else if (def is PartitionFunctionKeyContext) {
createTable.partitionType = PartitionType.KEY
} else if (def is PartitionFunctionRangeContext) {
createTable.partitionType = PartitionType.RANGE
} else if (def is PartitionFunctionListContext) {
createTable.partitionType = PartitionType.LIST
}
}
return createTable
}
override fun visitQueryCreateTable(ctx: MySqlParser.QueryCreateTableContext): Statement {
currentOptType = StatementType.CREATE_TABLE_AS_SELECT
val tableId = parseFullId(ctx.tableName().fullId())
var comment: String? = null
ctx.tableOption().forEach {
when (it) {
is MySqlParser.TableOptionCommentContext -> {
comment = CommonUtils.cleanQuote(it.STRING_LITERAL().text)
}
}
}
val ifNotExists: Boolean = if (ctx.ifNotExists() != null) true else false
val queryStmt = this.visitSelectStatement(ctx.selectStatement()) as QueryStmt
val createTable = CreateTableAsSelect(tableId, queryStmt, comment, null, null, null, null, null, ifNotExists)
return createTable
}
override fun visitCopyCreateTable(ctx: MySqlParser.CopyCreateTableContext): Statement? {
currentOptType = StatementType.CREATE_TABLE_AS_LIKE
val tableId = parseFullId(ctx.tableName().get(0).fullId())
var likeTableId = parseFullId(ctx.tableName().get(1).fullId())
var createTableLike = CreateTableLike(likeTableId, tableId, false, false, false);
return createTableLike;
}
override fun visitPrimaryKeyTableConstraint(ctx: MySqlParser.PrimaryKeyTableConstraintContext): Statement? {
val count = ctx.indexColumnNames().childCount
for (i in 1..(count - 2)) {
var column = ctx.indexColumnNames().getChild(i).text
column = CommonUtils.cleanQuote(column)
primaryKeys.add(column)
}
return null
}
override fun visitDropTable(ctx: MySqlParser.DropTableContext): Statement {
if (ctx.tables().tableName().size > 1) {
throw SQLParserException("不支持drop多个表")
}
val tableId = parseFullId(ctx.tables().tableName(0).fullId())
val dropTable = DropTable(tableId)
dropTable.ifExists = if (ctx.ifExists() != null) true else false
return dropTable
}
override fun visitTruncateTable(ctx: MySqlParser.TruncateTableContext): Statement {
val tableId = parseFullId(ctx.tableName().fullId())
return TruncateTable(tableId)
}
override fun visitRenameTable(ctx: MySqlParser.RenameTableContext): Statement {
val tableId = parseFullId(ctx.renameTableClause().get(0).tableName(0).fullId())
val newTableId = parseFullId(ctx.renameTableClause().get(0).tableName(1).fullId())
val action = RenameAction(newTableId)
return AlterTable(tableId, action)
}
override fun visitUseStatement(ctx: MySqlParser.UseStatementContext): Statement {
val databaseName = ctx.uid().text
return UseDatabase(databaseName)
}
// -----------------------------------Alter-----------------------------------------------
override fun visitAlterTable(ctx: MySqlParser.AlterTableContext): Statement? {
val tableId = parseFullId(ctx.tableName().fullId())
val alterTable = AlterTable(tableId)
ctx.alterSpecification().forEach { statement ->
if (statement is MySqlParser.AlterByChangeColumnContext) {
val columnName = CommonUtils.cleanQuote(statement.oldColumn.text)
val newColumnName = CommonUtils.cleanQuote(statement.newColumn.text)
val dataType = source(statement.columnDefinition().dataType())
var comment: String? = null
var nullable: Boolean = true
var defaultExpr: String? = null
statement.columnDefinition().children.forEach {
if (it is MySqlParser.CommentColumnConstraintContext) {
comment = CommonUtils.cleanQuote(it.STRING_LITERAL().text)
} else if (it is MySqlParser.NullColumnConstraintContext) {
nullable = it.nullNotnull().NOT() == null
} else if (it is MySqlParser.DefaultColumnConstraintContext) {
defaultExpr = source(it.defaultValue())
}
}
val action = AlterColumnAction(ALTER_COLUMN, columnName, dataType, comment)
action.newColumName = newColumnName
action.nullable = nullable
action.defaultExpression = defaultExpr
alterTable.addAction(action)
} else if (statement is MySqlParser.AlterByAddColumnContext) {
val columnName = CommonUtils.cleanQuote(statement.uid().get(0).text)
val dataType = statement.columnDefinition().dataType().text
var comment: String? = null
var nullable: Boolean = true
var defaultExpr: String? = null
statement.columnDefinition().children.forEach {
if (it is MySqlParser.CommentColumnConstraintContext) {
comment = CommonUtils.cleanQuote(it.STRING_LITERAL().text)
} else if (it is MySqlParser.NullColumnConstraintContext) {
nullable = it.nullNotnull().NOT() == null
} else if (it is MySqlParser.DefaultColumnConstraintContext) {
defaultExpr = source(it.defaultValue())
}
}
val action = AlterColumnAction(ADD_COLUMN, columnName, dataType, comment)
action.nullable = nullable
action.defaultExpression = defaultExpr
alterTable.addAction(action)
} else if (statement is MySqlParser.AlterByDropColumnContext) {
val columnName = CommonUtils.cleanQuote(statement.uid().text)
val action = DropColumnAction(columnName)
return AlterTable(tableId, action)
} else if (statement is MySqlParser.AlterByModifyColumnContext) {
val columnName = CommonUtils.cleanQuote(statement.uid().get(0).text)
val dataType = statement.columnDefinition().dataType().text
val action = AlterColumnAction(ALTER_COLUMN, columnName, dataType)
alterTable.addAction(action)
} else if (statement is AlterByAddIndexContext) {
val createIndex = CreateIndex(statement.uid().text)
alterTable.addAction(createIndex)
} else if (statement is MySqlParser.AlterByDropIndexContext) {
val dropIndex = DropIndex(statement.uid().text)
alterTable.addAction(dropIndex)
} else if (statement is AlterByAddPrimaryKeyContext) {
val action = AlterTableAction(ADD_PRIMARY_KEY)
alterTable.addAction(action)
} else if (statement is AlterByDropPrimaryKeyContext) {
val action = AlterTableAction(DROP_PRIMARY_KEY)
alterTable.addAction(action)
} else if (statement is MySqlParser.AlterByAddUniqueKeyContext) {
val action = AlterTableAction(ADD_UNIQUE_KEY)
alterTable.addAction(action)
} else if (statement is MySqlParser.AlterPartitionContext) {
val alterPartition = statement.alterPartitionSpecification()
if (alterPartition is AlterByTruncatePartitionContext) {
val action = AlterTableAction(TRUNCATE_PARTITION)
alterTable.addAction(action)
} else if (alterPartition is MySqlParser.AlterByDropPartitionContext) {
val action = AlterTableAction(DROP_PARTITION)
alterTable.addAction(action)
} else if (alterPartition is MySqlParser.AlterByAddPartitionContext) {
val action = AlterTableAction(ADD_PARTITION)
alterTable.addAction(action)
}
}
}
if (alterTable.actions.size > 0) {
return alterTable
} else {
return super.visitAlterTable(ctx)
}
}
override fun visitAnalyzeTable(ctx: MySqlParser.AnalyzeTableContext): Statement {
val tables = ArrayList()
ctx.tables().tableName().forEach { context ->
val tableId = parseFullId(context.fullId())
tables.add(tableId)
}
return AnalyzeTable(tables)
}
// -----------------------------------DML-------------------------------------------------
override fun visitSelectStatement(ctx: MySqlParser.SelectStatementContext): Statement {
if (currentOptType == StatementType.UNKOWN) {
currentOptType = StatementType.SELECT
}
super.visitSelectStatement(ctx)
return QueryStmt(inputTables, limit, offset)
}
override fun visitInsertStatement(ctx: MySqlParser.InsertStatementContext): Statement {
val tableId = parseFullId(ctx.tableName().fullId())
currentOptType = StatementType.INSERT
if (ctx.insertStatementValue().selectStatement() != null) {
val queryStmt = this.visitSelectStatement(ctx.insertStatementValue().selectStatement()) as QueryStmt
val insertTable = InsertTable(InsertMode.INTO, queryStmt, tableId)
insertTable?.setSql(source(ctx))
return insertTable
} else {
val insertTable = InsertTable(InsertMode.INTO, QueryStmt(), tableId)
insertTable?.setSql(source(ctx))
return insertTable
}
}
override fun visitReplaceStatement(ctx: MySqlParser.ReplaceStatementContext): Statement {
val tableId = parseFullId(ctx.tableName().fullId())
currentOptType = StatementType.INSERT
if (ctx.insertStatementValue().selectStatement() != null) {
val queryStmt = this.visitSelectStatement(ctx.insertStatementValue().selectStatement()) as QueryStmt
val insertTable = InsertTable(InsertMode.INTO, queryStmt, tableId)
insertTable.mysqlReplace = true
return insertTable
} else {
return InsertTable(InsertMode.INTO, QueryStmt(), tableId)
}
}
override fun visitDeleteStatement(ctx: MySqlParser.DeleteStatementContext): Statement {
currentOptType = StatementType.DELETE
val deleteTable =
if (ctx.multipleDeleteStatement() != null) {
this.visit(ctx.multipleDeleteStatement().expression())
val outputTables = ctx.multipleDeleteStatement().tableName().map { parseFullId(it.fullId()) }
val deleteTable = DeleteTable(outputTables.first(), inputTables)
super.visitTableSources(ctx.multipleDeleteStatement().tableSources())
deleteTable.outputTables.addAll(outputTables.subList(1, outputTables.size))
deleteTable
} else {
if (ctx.singleDeleteStatement().expression() != null) {
this.visit(ctx.singleDeleteStatement().expression())
}
val tableId = parseFullId(ctx.singleDeleteStatement().tableName().fullId())
DeleteTable(tableId, inputTables)
}
return deleteTable
}
override fun visitUpdateStatement(ctx: MySqlParser.UpdateStatementContext): Statement {
currentOptType = StatementType.UPDATE
val updateTable =
if (ctx.multipleUpdateStatement() != null) {
super.visitTableSources(ctx.multipleUpdateStatement().tableSources())
val expression = ctx.singleUpdateStatement().expression()
if (expression != null) {
this.visit(expression)
}
val updateTable = UpdateTable(inputTables.first(), inputTables.toMutableList())
updateTable
} else {
super.visitTableSources(ctx.singleUpdateStatement().tableSources())
val expression = ctx.singleUpdateStatement().expression()
if (expression != null) {
this.visit(expression)
}
val updateTable = UpdateTable(inputTables.first(), inputTables.toMutableList())
updateTable
}
return updateTable
}
override fun visitCreateIndex(ctx: MySqlParser.CreateIndexContext): Statement {
val tableId = parseFullId(ctx.tableName().fullId())
val createIndex = CreateIndex(ctx.uid().text)
return AlterTable(tableId, createIndex)
}
override fun visitDropIndex(ctx: MySqlParser.DropIndexContext): Statement {
val tableId = parseFullId(ctx.tableName().fullId())
val dropIndex = DropIndex(ctx.uid().text)
return AlterTable(tableId, dropIndex)
}
override fun visitCreateProcedure(ctx: MySqlParser.CreateProcedureContext): Statement {
super.visitCreateProcedure(ctx)
val tableId = parseFullId(ctx.fullId())
val procedureId = ProcedureId(tableId.schemaName, tableId.tableName)
return CreateProcedure(procedureId, childStatements, false)
}
override fun visitCreateFunction(ctx: MySqlParser.CreateFunctionContext): Statement {
super.visitCreateFunction(ctx)
val tableId = parseFullId(ctx.fullId())
val functionId = FunctionId(tableId.schemaName, tableId.tableName)
return CreateFunction(functionId, childStatements, false)
}
// -----------------------------------private
// method-------------------------------------------------
override fun visitWithStatement(ctx: MySqlParser.WithStatementContext): Statement? {
inCte = true
ctx.commonTableExpressions().forEach {
val tableId = TableId(it.cteName().text)
cteTempTables.add(tableId)
super.visitDmlStatement(it.dmlStatement())
}
inCte = false
return null
}
override fun visitTableName(ctx: MySqlParser.TableNameContext): Statement? {
if (
StatementType.SELECT == currentOptType ||
StatementType.INSERT == currentOptType ||
StatementType.UPDATE == currentOptType ||
StatementType.DELETE == currentOptType ||
StatementType.CREATE_TABLE_AS_SELECT == currentOptType
) {
val tableId = parseFullId(ctx.fullId())
// 别名和表名一样的场景
if (inCte && cteTempTables.last() == tableId) {
cteTempTables.remove(tableId)
}
if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {
inputTables.add(tableId)
}
}
return null
}
override fun visitLimitClause(ctx: MySqlParser.LimitClauseContext): Statement? {
if (ctx.limit != null && ctx.limit.decimalLiteral() != null) {
limit = ctx.limit.text.toInt()
}
if (ctx.offset != null && ctx.offset.decimalLiteral() != null) {
offset = ctx.offset.text.toInt()
}
return super.visitLimitClause(ctx)
}
private fun parseFullId(fullId: MySqlParser.FullIdContext): TableId {
var databaseName: String? = null
var tableName: String = ""
if (fullId.childCount == 2) {
databaseName = fullId.uid().get(0).text
tableName = (fullId.getChild(1) as TerminalNodeImpl).text.substring(1)
} else if (fullId.childCount == 3) {
databaseName = CommonUtils.cleanQuote(fullId.uid().get(0).text)
tableName = CommonUtils.cleanQuote((fullId.getChild(2) as MySqlParser.UidContext).text)
} else {
tableName = fullId.uid().get(0).text
}
if (databaseName != null) {
databaseName = CommonUtils.cleanQuote(databaseName)
}
tableName = CommonUtils.cleanQuote(tableName)
return TableId(databaseName, tableName)
}
}
================================================
FILE: superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/MySqlHelper.kt
================================================
package com.github.melin.superior.sql.parser.mysql
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.common.antlr4.ParseErrorListener
import io.github.melin.superior.common.antlr4.ParseException
import io.github.melin.superior.common.antlr4.UpperCaseCharStream
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.parser.mysql.AbstractSqlParser
import io.github.melin.superior.parser.mysql.MySqlAntlr4Visitor
import io.github.melin.superior.parser.mysql.antlr4.MySqlLexer
import io.github.melin.superior.parser.mysql.antlr4.MySqlParser
import io.github.melin.superior.parser.mysql.antlr4.MySqlParserBaseVisitor
import org.antlr.v4.runtime.CharStreams
import org.antlr.v4.runtime.CommonTokenStream
import org.antlr.v4.runtime.atn.PredictionMode
import org.antlr.v4.runtime.misc.ParseCancellationException
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2018/1/10. */
object MySqlHelper {
@JvmStatic
fun sqlKeywords(): List {
val keywords = hashSetOf()
(0 until MySqlLexer.VOCABULARY.maxTokenType).forEach { idx ->
val name = MySqlLexer.VOCABULARY.getLiteralName(idx)
if (name != null) {
val matchResult = CommonUtils.KEYWORD_REGEX.find(name)
if (matchResult != null) {
keywords.add(matchResult.groupValues.get(1))
}
}
}
return keywords.sorted()
}
@JvmStatic
fun parseStatement(command: String): Statement {
val statements = this.parseMultiStatement(command)
if (statements.size != 1) {
throw IllegalStateException("only parser one sql, sql count: " + statements.size)
} else {
return statements.get(0)
}
}
@JvmStatic
fun parseMultiStatement(command: String): List {
val trimCmd = StringUtils.trim(command)
val sqlVisitor = MySqlAntlr4Visitor(false)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSqlStatements()
}
@JvmStatic
fun splitSql(command: String): List {
val trimCmd = StringUtils.trim(command)
val sqlVisitor = MySqlAntlr4Visitor(true)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSplitSqls()
}
@JvmStatic
fun checkSqlSyntax(command: String) {
val sqlVisitor = MySqlParserBaseVisitor()
innerParseStatement(command, sqlVisitor)
}
private fun innerParseStatement(command: String, sqlVisitor: MySqlParserBaseVisitor) {
val charStream = UpperCaseCharStream(CharStreams.fromString(command))
val lexer = MySqlLexer(charStream)
lexer.removeErrorListeners()
lexer.addErrorListener(ParseErrorListener())
val tokenStream = CommonTokenStream(lexer)
val parser = MySqlParser(tokenStream)
AbstractSqlParser.installCaches(parser)
parser.removeErrorListeners()
parser.addErrorListener(ParseErrorListener())
try {
try {
// first, try parsing with potentially faster SLL mode
sqlVisitor.visitSqlStatements(parser.sqlStatements())
} catch (e: ParseCancellationException) {
tokenStream.seek(0) // rewind input stream
parser.reset()
// Try Again.
parser.interpreter.predictionMode = PredictionMode.LL
sqlVisitor.visitSqlStatements(parser.sqlStatements())
}
} catch (e: ParseException) {
if (StringUtils.isNotBlank(e.command)) {
throw e
} else {
throw e.withCommand(command)
}
} finally {
val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)
if (releaseAntlrCache == null || "true".equals(releaseAntlrCache)) {
AbstractSqlParser.refreshParserCaches()
}
}
}
}
================================================
FILE: superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/type/JsonType.kt
================================================
package io.github.melin.superior.parser.mysql.type
import io.github.melin.superior.common.type.AbsType
class JsonType : AbsType() {
override val name: String = "json"
}
================================================
FILE: superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/type/datetime.kt
================================================
package io.github.melin.superior.parser.mysql.type
import io.github.melin.superior.common.type.AbsDataTimeType
class DateType : AbsDataTimeType() {
override val name: String = "date"
}
data class TimeType(val precision: Int = 0) : AbsDataTimeType() {
override val name: String = "time"
}
data class TimeStampType(val precision: Int = 0) : AbsDataTimeType() {
override val name: String = "timestamp"
}
data class DateTimeType(val precision: Int = 0) : AbsDataTimeType() {
override val name: String = "datetime"
}
class YearType : AbsDataTimeType() {
override val name: String = "year"
}
================================================
FILE: superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/type/numeric.kt
================================================
package io.github.melin.superior.parser.mysql.type
import io.github.melin.superior.common.type.AbsNumericType
data class TinyintType(val length: Int, val unsigned: Boolean = false, val zerofill: Boolean = false) :
AbsNumericType() {
override val name: String = "tinyint"
override val alias: String = "int1"
companion object {
const val MIN_VALUE: Short = -128
const val MAX_VALUE: Short = 127
}
}
data class SmallIntType(val length: Int, val unsigned: Boolean = false, val zerofill: Boolean = false) :
AbsNumericType() {
override val name: String = "smallint"
override val alias: String = "int2"
companion object {
const val MIN_VALUE: Int = -32768
const val MAX_VALUE: Int = 32767
}
}
data class MediumIntType(val length: Int, val unsigned: Boolean = false, val zerofill: Boolean = false) :
AbsNumericType() {
override val name: String = "mediumint"
override val alias: String = "int3"
companion object {
const val MIN_VALUE: Int = -8388608
const val MAX_VALUE: Int = 8388607
}
}
data class IntegerType(val length: Int) : AbsNumericType() {
override val name: String = "integer"
override val alias: String = "int"
override val alias2: String = "int4"
companion object {
const val MIN_VALUE: Long = -2147483648L
const val MAX_VALUE: Long = 2147483647L
}
}
data class BigIntType(val length: Int, val unsigned: Boolean = false, val zerofill: Boolean = false) :
AbsNumericType() {
override val name: String = "bigint"
override val alias: String = "int8"
}
data class DecimalType(val precision: Int = 10, val scale: Int = 0) : AbsNumericType() {
override val name: String = "decimal"
}
data class FloatType(val precision: Int, val scale: Int = 0) : AbsNumericType() {
override val name: String = "float"
}
data class DoubleType(val precision: Int, val scale: Int = 0) : AbsNumericType() {
override val name: String = "double"
override val alias: String = "float8"
}
data class RealType(val precision: Int, val scale: Int = 0) : AbsNumericType() {
override val name: String = "real"
override val alias: String = "float4"
}
data class BitType(val length: Int) : AbsNumericType() {
override val name: String = "bit"
}
================================================
FILE: superior-mysql-parser/src/main/kotlin/io/github/melin/superior/parser/mysql/type/string.kt
================================================
package io.github.melin.superior.parser.mysql.type
import io.github.melin.superior.common.type.AbsStringType
data class CharType(val length: Int) : AbsStringType() {
override val name: String = "char"
companion object {
const val MAX_LENGTH: Int = 255
}
}
data class VarcharType(val length: Int) : AbsStringType() {
override val name: String = "varchar"
companion object {
const val MAX_LENGTH: Int = 65535
}
}
data class BinaryType(val length: Int) : AbsStringType() {
override val name: String = "binary"
companion object {
const val MAX_LENGTH: Int = 255
}
}
data class VarbinaryType(val length: Int) : AbsStringType() {
override val name: String = "varbinary"
companion object {
const val MAX_LENGTH: Int = 65535
}
}
class TinyblobType : AbsStringType() {
override val name: String = "tinyblob"
}
class BlobType : AbsStringType() {
override val name: String = "blob"
}
class MediumblobType : AbsStringType() {
override val name: String = "mediumblob"
}
class LongblobType : AbsStringType() {
override val name: String = "longblob"
}
class TinytextType : AbsStringType() {
override val name: String = "tinytext"
}
class TextType : AbsStringType() {
override val name: String = "text"
}
class MediumtextType : AbsStringType() {
override val name: String = "mediumtext"
}
class LongtextType : AbsStringType() {
override val name: String = "longtext"
}
data class EnumType(val values: List) : AbsStringType() {
override val name: String = "enum"
}
data class SetType(val values: List) : AbsStringType() {
override val name: String = "set"
}
================================================
FILE: superior-mysql-parser/src/test/kotlin/io/github/melin/superior/parser/mysql/MySqlParserDdlTest.kt
================================================
package io.github.melin.superior.parser.mysql
import com.github.melin.superior.sql.parser.mysql.MySqlHelper
import io.github.melin.superior.common.*
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.*
import io.github.melin.superior.common.relational.alter.*
import io.github.melin.superior.common.relational.common.UseDatabase
import io.github.melin.superior.common.relational.create.CreateDatabase
import io.github.melin.superior.common.relational.create.CreateTable
import io.github.melin.superior.common.relational.drop.DropDatabase
import io.github.melin.superior.common.relational.drop.DropTable
import io.github.melin.superior.common.relational.table.TruncateTable
import org.junit.Assert
import org.junit.Test
/** Created by libinsong on 2018/1/10. */
class MySqlParserDdlTest {
@Test
fun splitSqlTest() {
val sql =
"""
CREATE DATABASE IF NOT EXISTS bigdata1;
drop DATABASE IF EXISTS bigdata2
"""
.trimIndent()
val statements = MySqlHelper.splitSql(sql)
Assert.assertEquals(2, statements.size)
Assert.assertEquals("CREATE DATABASE IF NOT EXISTS bigdata1", statements.get(0))
}
@Test
fun createDatabaseTest() {
val sql =
"""
CREATE DATABASE IF NOT EXISTS "bigdata1";
drop DATABASE IF EXISTS bigdata2
"""
.trimIndent()
val statements = MySqlHelper.parseMultiStatement(sql)
val createDatabse = statements.get(0)
val dropDatabase = statements.get(1)
if (createDatabse is CreateDatabase) {
Assert.assertEquals("bigdata1", createDatabse.databaseName)
}
if (dropDatabase is CreateDatabase) {
Assert.assertEquals("bigdata2", dropDatabase.databaseName)
}
}
@Test
fun dropDatabaseTest() {
val sql = "DROP DATABASE IF EXISTS bigdata"
val statement = MySqlHelper.parseStatement(sql)
if (statement is DropDatabase) {
val name = statement.databaseName
Assert.assertEquals(StatementType.DROP_DATABASE, statement.statementType)
Assert.assertEquals("bigdata", name)
} else {
Assert.fail()
}
}
@Test
fun createTableTest() {
val sql =
"CREATE TABLE bigdata.dc_config (\n" +
" `id` int(11) NOT NULL AUTO_INCREMENT comment 'id',\n" +
" `appname` varchar(64) NOT NULL,\n" +
" `profile` varchar(64) NOT NULL,\n" +
" `width` DECIMAL(5, 2) NOT NULL,\n" +
" `config_text` longtext,\n" +
" `content` json,\n" +
" `content1` text COLLATE utf8mb4_unicode_ci comment 'test',\n" +
" `creater` varchar(45) NOT NULL,\n" +
" `modifier` varchar(45) DEFAULT NULL,\n" +
" `gmt_created` datetime NOT NULL,\n" +
" `gmt_modified` datetime DEFAULT NULL,\n" +
" PRIMARY KEY (`id`),\n" +
" UNIQUE KEY `appname_UNIQUE` (`appname`,`profile`)\n" +
") ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='系统参数配置';"
val statement = MySqlHelper.parseStatement(sql)
if (statement is CreateTable) {
Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)
Assert.assertEquals("bigdata", statement.tableId.schemaName)
Assert.assertEquals("dc_config", statement.tableId.tableName)
Assert.assertEquals("系统参数配置", statement.comment)
statement.columnRels?.get(0)?.let { Assert.assertTrue(it.primaryKey) }
} else {
Assert.fail()
}
}
@Test
fun createTableTest1() {
val sql =
"CREATE TABLE `box_partner` (\n" +
" `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',\n" +
" `code` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户编码',\n" +
" `name` varchar(256) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '客户名称',\n" +
" `role` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户角色',\n" +
" `key` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户key',\n" +
" `logo` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户logo',\n" +
" `info` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户简介',\n" +
" `contacts` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '联系方式',\n" +
" `token` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户唯一标识',\n" +
" `callback_url` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '客户提供的回调地址',\n" +
" `attachment` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '扩展字段',\n" +
" `create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n" +
" `modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',\n" +
" `callback_url_status` int(11) DEFAULT NULL COMMENT '回调地址状态:成功0,失败1,通讯中断2',\n" +
" `callback_url_detail` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '回调事件',\n" +
" PRIMARY KEY (`id`),\n" +
" UNIQUE KEY `token` (`token`)\n" +
" ) ENGINE=InnoDB AUTO_INCREMENT=7564 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
val statement = MySqlHelper.parseStatement(sql)
if (statement is CreateTable) {
Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)
Assert.assertEquals("box_partner", statement.tableId.tableName)
} else {
Assert.fail()
}
}
@Test
fun createTableTest2() {
val sql =
" CREATE TABLE `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 NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',\n" +
" PRIMARY KEY (`id`)\n" +
") ENGINE=InnoDB AUTO_INCREMENT=4475 DEFAULT CHARSET=utf8 COMMENT='决策流与模型关系表'"
val statement = MySqlHelper.parseStatement(sql)
if (statement is CreateTable) {
Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)
Assert.assertEquals("decision_flow_model", statement.tableId.tableName)
} else {
Assert.fail()
}
}
@Test
fun createTableTest3() {
val sql =
"CREATE TABLE `app_channel_daily_report` (\n" +
" `id` bigint(20) NOT NULL AUTO_INCREMENT,\n" +
" `normal_counting` bigint(20) NOT NULL DEFAULT '0' COMMENT '正常用户',\n" +
" `abnormal_counting` bigint(20) NOT NULL DEFAULT '0' COMMENT '异常用户',\n" +
" `emulator_counting` bigint(20) NOT NULL DEFAULT '0' COMMENT '模拟器用户',\n" +
" `gmt_create` datetime NOT NULL COMMENT '创建时间',\n" +
" `gmt_modified` datetime DEFAULT NULL COMMENT '更新时间',\n" +
" `create_by` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '创建者',\n" +
" `update_by` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '更新者',\n" +
" `event_type` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '事件类型',\n" +
" `partner_code` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '合作方编码',\n" +
" `app_channel` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '渠道',\n" +
" `app_name` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'app名称',\n" +
" `app_version` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'default',\n" +
" PRIMARY KEY (`id`,`gmt_create`),\n" +
" KEY `channel_report_index` (`gmt_create`,`partner_code`,`app_channel`,`app_name`,`app_version`,`event_type`)\n" +
") ENGINE=InnoDB AUTO_INCREMENT=33703438 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='渠道反作弊日统计表'\n" +
" PARTITION BY RANGE (month(gmt_create)-1)\n" +
"(PARTITION part0 VALUES LESS THAN (1) COMMENT = '1月份' ENGINE = InnoDB,\n" +
" PARTITION part1 VALUES LESS THAN (2) COMMENT = '2月份' ENGINE = InnoDB,\n" +
" PARTITION part2 VALUES LESS THAN (3) COMMENT = '3月份' ENGINE = InnoDB,\n" +
" PARTITION part3 VALUES LESS THAN (4) COMMENT = '4月份' ENGINE = InnoDB,\n" +
" PARTITION part4 VALUES LESS THAN (5) COMMENT = '5月份' ENGINE = InnoDB,\n" +
" PARTITION part5 VALUES LESS THAN (6) COMMENT = '6月份' ENGINE = InnoDB,\n" +
" PARTITION part6 VALUES LESS THAN (7) COMMENT = '7月份' ENGINE = InnoDB,\n" +
" PARTITION part7 VALUES LESS THAN (8) COMMENT = '8月份' ENGINE = InnoDB,\n" +
" PARTITION part8 VALUES LESS THAN (9) COMMENT = '9月份' ENGINE = InnoDB,\n" +
" PARTITION part9 VALUES LESS THAN (10) COMMENT = '10月份' ENGINE = InnoDB,\n" +
" PARTITION part10 VALUES LESS THAN (11) COMMENT = '11月份' ENGINE = InnoDB,\n" +
" PARTITION part11 VALUES LESS THAN (12) COMMENT = '12月份' ENGINE = InnoDB)"
val statement = MySqlHelper.parseStatement(sql)
if (statement is CreateTable) {
Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)
Assert.assertEquals("app_channel_daily_report", statement.tableId.tableName)
Assert.assertEquals(PartitionType.RANGE, statement.partitionType)
} else {
Assert.fail()
}
}
@Test
fun createTableTest4() {
val sql =
"""
CREATE TABLE IF NOT EXISTS `decision_flow_model` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`model_uuid` char(32) NOT NULL COMMENT '关联holmes_model表的uuid',
`partner_code` varchar(128) NOT NULL COMMENT '合作方',
`decision_flow_uuid` char(32) NOT NULL COMMENT '关联decision_flow表的uuid',
`gmt_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modify` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=77 DEFAULT CHARSET=utf8
"""
val statement = MySqlHelper.parseStatement(sql)
if (statement is CreateTable) {
Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)
Assert.assertEquals("decision_flow_model", statement.tableId.tableName)
} else {
Assert.fail()
}
}
@Test
fun createTableTest5() {
val sql =
"""
CREATE TABLE `dw_job_analysis_detail` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) DEFAULT NULL,
`job_id` int(11) DEFAULT NULL,
`job_type` varchar(255) DEFAULT NULL,
`job_status` int(255) DEFAULT NULL,
`create_time` timestamp(6) NULL DEFAULT NULL,
`creater` varchar(255) DEFAULT NULL,
`modifier` varchar(255) DEFAULT NULL,
`gmt_created` timestamp(6) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(6),
`gmt_modified` datetime(6) DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=75306 DEFAULT CHARSET=utf8
"""
val statement = MySqlHelper.parseStatement(sql)
if (statement is CreateTable) {
Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)
Assert.assertEquals("dw_job_analysis_detail", statement.tableId.tableName)
} else {
Assert.fail()
}
}
@Test
fun dropTableTest() {
val sql = "DROP table IF EXISTS bigdata.users"
val statement = MySqlHelper.parseStatement(sql)
if (statement is DropTable) {
Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)
Assert.assertEquals("bigdata", statement.tableId.schemaName)
Assert.assertEquals("users", statement.tableId.tableName)
} else {
Assert.fail()
}
}
@Test
fun renameTableTest() {
val sql = "RENAME TABLE `datacompute`.`users_quan` TO `datacompute`.`dc_users`\n"
val statement = MySqlHelper.parseStatement(sql)
if (statement is AlterTable) {
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
Assert.assertEquals("datacompute", statement.tableId.schemaName)
Assert.assertEquals("users_quan", statement.tableId.tableName)
val action = statement.firstAction() as RenameAction
Assert.assertEquals(AlterActionType.RENAME, action.alterType)
Assert.assertEquals("dc_users", action.newTableId.tableName)
} else {
Assert.fail()
}
}
@Test
fun analyzeTableTest() {
val sql = "analyze table bigdata.users"
val statement = MySqlHelper.parseStatement(sql)
if (statement is AnalyzeTable) {
val table = statement.tableIds.get(0)
Assert.assertEquals(StatementType.ANALYZE_TABLE, statement.statementType)
Assert.assertEquals("bigdata", table.schemaName)
Assert.assertEquals("users", table.tableName)
} else {
Assert.fail()
}
}
@Test
fun truncateTableTest() {
val sql = "TRUNCATE TABLE test.user"
val statement = MySqlHelper.parseStatement(sql)
if (statement is TruncateTable) {
Assert.assertEquals(StatementType.TRUNCATE_TABLE, statement.statementType)
Assert.assertEquals("test", statement.tableId.schemaName)
Assert.assertEquals("user", statement.tableId.tableName)
} else {
Assert.fail()
}
}
@Test
fun changeColumnTest() {
val sql =
"ALTER TABLE `datacompute`.`log_collect_config` \n" +
"CHANGE COLUMN `partition_type` `partition_type1` VARCHAR(45) NULL DEFAULT 'day' COMMENT '分区类型:day, hour, minute' ;"
val statement = MySqlHelper.parseStatement(sql)
if (statement is AlterTable) {
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
Assert.assertEquals("datacompute", statement.tableId.schemaName)
Assert.assertEquals("log_collect_config", statement.tableId.tableName)
val action = statement.firstAction() as AlterColumnAction
Assert.assertEquals("partition_type", action.columName)
Assert.assertEquals("partition_type1", action.newColumName)
Assert.assertEquals("分区类型:day, hour, minute", action.comment)
} else {
Assert.fail()
}
}
@Test
fun modifyColumnTest() {
val sql = "ALTER TABLE t1 MODIFY age BIGINT NOT NULL;"
val statement = MySqlHelper.parseStatement(sql)
if (statement is AlterTable) {
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
Assert.assertEquals("t1", statement.tableId.tableName)
val action = statement.firstAction() as AlterColumnAction
Assert.assertEquals(AlterActionType.ALTER_COLUMN, action.alterType)
Assert.assertEquals("age", action.columName)
Assert.assertEquals("BIGINT", action.dataType)
} else {
Assert.fail()
}
}
@Test
fun addColumnTest() {
val sql =
"ALTER TABLE `datacompute`.`users_quan` ADD COLUMN `age` VARCHAR(45) NOT NULL DEFAULT 18 COMMENT '年龄' AFTER `username`"
val statement = MySqlHelper.parseStatement(sql)
if (statement is AlterTable) {
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
Assert.assertEquals("datacompute", statement.tableId.schemaName)
Assert.assertEquals("users_quan", statement.tableId.tableName)
val action = statement.firstAction() as AlterColumnAction
Assert.assertEquals(AlterActionType.ADD_COLUMN, action.alterType)
Assert.assertEquals("age", action.columName)
Assert.assertFalse(action.nullable)
Assert.assertEquals("18", action.defaultExpression)
Assert.assertEquals("年龄", action.comment)
} else {
Assert.fail()
}
}
@Test
fun addColumnTest1() {
val sql =
"""
ALTER TABLE `mxy`.`cyj`
ADD COLUMN new_column1 VARCHAR(255) default null,
ADD COLUMN new_column2 INT not null default 0,
ADD COLUMN new_column3 TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is AlterTable) {
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
Assert.assertEquals("mxy", statement.tableId.schemaName)
Assert.assertEquals("cyj", statement.tableId.tableName)
Assert.assertEquals(3, statement.actions.size)
} else {
Assert.fail()
}
}
@Test
fun dropColumnTest() {
val sql = "ALTER TABLE `datacompute`.`users_quan` DROP COLUMN `age`;"
val statement = MySqlHelper.parseStatement(sql)
if (statement is AlterTable) {
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
Assert.assertEquals("datacompute", statement.tableId.schemaName)
Assert.assertEquals("users_quan", statement.tableId.tableName)
val action = statement.firstAction() as DropColumnAction
Assert.assertEquals(AlterActionType.DROP_COLUMN, action.alterType)
Assert.assertEquals("age", action.columNames.get(0))
} else {
Assert.fail()
}
}
@Test
fun addUNIQUETest() {
val sql =
"ALTER TABLE `datacompute`.`dc_project_member`\n" +
" ADD UNIQUE INDEX `uk_prj_user` (`project_code` ASC, `user_id` ASC);"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
}
@Test
fun addUNIQUETest1() {
val sql = "ALTER TABLE amount_all ADD UNIQUE uk_type_time(etype, time)"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
}
@Test
fun addIndexTest() {
val sql = "ALTER TABLE sj_resource_charges add index index_test (name);"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
if (statement is AlterTable) {
val createIndex = statement.firstAction() as CreateIndex
Assert.assertEquals("index_test", createIndex.indexName)
}
}
@Test
fun addIndexTest1() {
val sql = "ALTER TABLE tablename ADD INDEX INDEX_NAME (school_id, settlement_time)"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
}
@Test
fun dropIndexTest1() {
val sql = "ALTER TABLE table_name DROP INDEX index_name"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals("ALTER TABLE table_name DROP INDEX index_name", sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
}
@Test
fun useTest() {
var sql = "use bigdata"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.USE, statement.statementType)
if (statement is UseDatabase) {
Assert.assertEquals("bigdata", statement.databaseName)
} else {
Assert.fail()
}
}
@Test
fun createIndexTest() {
val sql = "CREATE INDEX test_index ON demo.orders (column_name)"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
if (statement is AlterTable) {
Assert.assertEquals(TableId("demo", "orders"), statement.tableId)
val createIndex = statement.firstAction() as CreateIndex
Assert.assertEquals("test_index", createIndex.indexName)
}
}
@Test
fun dropIndexTest() {
val sql = "DROP INDEX test_index ON demo.orders"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
if (statement is AlterTable) {
Assert.assertEquals(TableId("demo", "orders"), statement.tableId)
val dropIndex = statement.firstAction() as DropIndex
Assert.assertEquals(AlterActionType.DROP_INDEX, dropIndex.alterType)
Assert.assertEquals("test_index", dropIndex.indexName)
}
}
@Test
fun truncatePartitionTest() {
val sql = "ALTER TABLE demo.orders TRUNCATE PARTITION p1998\n"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
if (statement is AlterTable) {
Assert.assertEquals(AlterActionType.TRUNCATE_PARTITION, statement.firstAction().alterType)
Assert.assertEquals(TableId("demo", "orders"), statement.tableId)
}
}
@Test
fun dropPrimarykeyTest() {
val sql = "alter table rd_orders drop primary key"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
if (statement is AlterTable) {
Assert.assertEquals(AlterActionType.DROP_PRIMARY_KEY, statement.firstAction().alterType)
Assert.assertEquals(TableId("rd_orders"), statement.tableId)
}
}
@Test
fun addPrimarykeyTest() {
val sql = "alter table rd_orders add primary key (name)"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
if (statement is AlterTable) {
Assert.assertEquals(AlterActionType.ADD_PRIMARY_KEY, statement.firstAction().alterType)
Assert.assertEquals(TableId("rd_orders"), statement.tableId)
}
}
}
================================================
FILE: superior-mysql-parser/src/test/kotlin/io/github/melin/superior/parser/mysql/MySqlParserDmlTest.kt
================================================
package io.github.melin.superior.parser.mysql
import com.github.melin.superior.sql.parser.mysql.MySqlHelper
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.create.CreateTableAsSelect
import io.github.melin.superior.common.relational.dml.DeleteTable
import io.github.melin.superior.common.relational.dml.InsertTable
import io.github.melin.superior.common.relational.dml.QueryStmt
import io.github.melin.superior.common.relational.dml.UpdateTable
import org.junit.Assert
import org.junit.Test
/** Created by libinsong on 2018/1/10. */
class MySqlParserDmlTest {
@Test
fun selectTest0() {
val sql = "select * from users limit 5, 10"
val statement = MySqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(1, statement.inputTables.size)
Assert.assertEquals(5, statement.offset)
Assert.assertEquals(10, statement.limit)
} else {
Assert.fail()
}
}
@Test
fun selectTest1() {
val sql = "select * from users a left outer join address b on a.address_id = b.id limit 10 offset 100"
val statement = MySqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(2, statement.inputTables.size)
Assert.assertEquals(10, statement.limit)
Assert.assertEquals(100, statement.offset)
} else {
Assert.fail()
}
}
@Test
fun deleteTest0() {
val sql =
"""
DELETE FROM films
WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is DeleteTable) {
Assert.assertEquals(StatementType.DELETE, statement.statementType)
Assert.assertEquals("films", statement.tableId?.tableName)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun deleteTest1() {
val sql =
"""
DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3
WHERE t1.id=t2.id AND t2.id=t3.id;
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is DeleteTable) {
Assert.assertEquals(StatementType.DELETE, statement.statementType)
Assert.assertEquals("t1", statement.tableId.tableName)
Assert.assertEquals(2, statement.outputTables.size)
Assert.assertEquals(3, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun deleteTest2() {
val sql =
"""
DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3
WHERE t1.id=t2.id AND t2.id=t3.id;
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is DeleteTable) {
Assert.assertEquals(StatementType.DELETE, statement.statementType)
Assert.assertEquals("t1", statement.tableId.tableName)
Assert.assertEquals(2, statement.outputTables.size)
Assert.assertEquals(3, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun deleteTest3() {
val sql =
"""
DELETE FROM users
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is DeleteTable) {
Assert.assertEquals(StatementType.DELETE, statement.statementType)
Assert.assertEquals("users", statement.tableId.tableName)
} else {
Assert.fail()
}
}
@Test
fun updateTest0() {
val sql =
"""
UPDATE employees SET sales_count = sales_count + 1 WHERE id =
(SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is UpdateTable) {
Assert.assertEquals(StatementType.UPDATE, statement.statementType)
Assert.assertEquals("employees", statement.tableId?.tableName)
Assert.assertEquals(2, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun updateTest1() {
val sql =
"""
UPDATE product p LEFT JOIN product_price pp ON p.productid= pp.productid
SET p.isdelete = 1 WHERE pp.productid IS NULL;
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is UpdateTable) {
Assert.assertEquals(StatementType.UPDATE, statement.statementType)
Assert.assertEquals("product", statement.tableId.tableName)
Assert.assertEquals(2, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun updateTest2() {
val sql =
"""
update resource_screen_node b join (
select
concat(region_name,'区域测点') name
,sum(access_station_num) as snum
,sum(access_point_num) as pnum
from ads_dmap_datasource_indicator
group by region_name
) as a on a.name=b.name
set b.access_station=a.snum,b.access_point=pnum;
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is UpdateTable) {
Assert.assertEquals(StatementType.UPDATE, statement.statementType)
Assert.assertEquals("resource_screen_node", statement.tableId.tableName)
Assert.assertEquals(2, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun updateTest3() {
val sql =
"""
UPDATE items,month SET items.price=month.price
WHERE items.id=month.id;
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is UpdateTable) {
Assert.assertEquals(StatementType.UPDATE, statement.statementType)
Assert.assertEquals("items", statement.tableId.tableName)
Assert.assertEquals(2, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertValuesTest() {
val sql =
"""
insert into bigdata."user" select * from users a left outer join address b on a.address_id = b.id
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("bigdata", statement.tableId?.schemaName)
Assert.assertEquals("user", statement.tableId?.tableName)
Assert.assertEquals(2, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun replaceValuesTest() {
// val sql = "insert into user values('name')"
val sql = "REPLACE into bigdata.user select * from users a left outer join address b on a.address_id = b.id"
val statement = MySqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("bigdata", statement.tableId?.schemaName)
Assert.assertEquals("user", statement.tableId?.tableName)
Assert.assertTrue(statement.mysqlReplace)
Assert.assertEquals(2, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun countCondTest() {
val sql = "select count(type='mac' or null) From test_table where a=2 limit 50"
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.SELECT, statement.statementType)
if (statement is QueryStmt) {
Assert.assertEquals("test_table", statement.inputTables.get(0).tableName)
} else {
Assert.fail()
}
}
@Test
fun cteTest0() {
val sql =
"""
WITH
CTE1 AS (SELECT A, B FROM TABLE1),
CTE2 AS (SELECT C, D FROM TABLE2)
SELECT B, D FROM CTE1 JOIN CTE2
WHERE CTE1.A = CTE2.C;
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.SELECT, statement.statementType)
if (statement is QueryStmt) {
Assert.assertEquals("TABLE1", statement.inputTables.get(0).tableName)
Assert.assertEquals(2, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun cteTest1() {
val sql =
"""
INSERT INTO DATES (DATE)
SELECT DATE
FROM (
WITH RECURSIVE DATE_RANGE AS (
SELECT DATE('2023-01-01') AS DATE
UNION ALL
SELECT DATE + INTERVAL 1 DAY
FROM DATE_RANGE
WHERE DATE < '2024-12-31'
),
DATE_RANGE2 AS (
SELECT DATE('2025-01-01') AS DATE
UNION ALL
SELECT DATE + INTERVAL 1 DAY
FROM DATE_RANGE2
WHERE DATE < '2025-12-31'
)
SELECT DATE
FROM DATE_RANGE
UNION ALL
SELECT DATE
FROM DATE_RANGE2
) AS DERIVED_TABLE
ON DUPLICATE KEY UPDATE DATE = VALUES(DATE);
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.INSERT, statement.statementType)
if (statement is InsertTable) {
Assert.assertEquals(2, statement.queryStmt.inputTables.size)
Assert.assertEquals(TableId("DATES"), statement.tableId)
} else {
Assert.fail()
}
}
@Test
fun cteTest2() {
val sql =
"""
WITH cte1 AS (SELECT 1)
SELECT * FROM (WITH cte2 AS (SELECT 2) SELECT * FROM cte2 JOIN cte1) AS dt;
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.SELECT, statement.statementType)
if (statement is QueryStmt) {
Assert.assertEquals(0, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun ctasTest0() {
val sql = "create table demo1 as select * from demo"
val statement = MySqlHelper.parseStatement(sql)
if (statement is CreateTableAsSelect) {
Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)
Assert.assertEquals("demo1", statement.tableId.tableName)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-mysql-parser/src/test/kotlin/io/github/melin/superior/parser/mysql/MySqlProcedureParserTest.kt
================================================
package io.github.melin.superior.parser.mysql
import com.github.melin.superior.sql.parser.mysql.MySqlHelper
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.create.CreateProcedure
import org.junit.Assert
import org.junit.Test
class MySqlProcedureParserTest {
@Test
fun procedureTest0() {
val sql =
"""
CREATE PROCEDURE UpdateEmployeeSalary(IN employeeId INT, IN newSalary DECIMAL(10, 2))
BEGIN
-- Update the salary of an employee with the given ID
UPDATE employees
SET salary = newSalary
WHERE id = employeeId;
select * from demos;
END;
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is CreateProcedure) {
Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)
Assert.assertEquals("UpdateEmployeeSalary", statement.procedureId?.procedureName)
Assert.assertEquals(2, statement.childStatements.size)
} else {
Assert.fail()
}
}
@Test
fun procedureTest1() {
val sql =
"""
create procedure my_procedure()
begin
declare my_id varchar(32);
declare my_name varchar(50);
DECLARE done INT DEFAULT FALSE;
DECLARE My_Cursor CURSOR FOR ( SELECT id, name FROM t_people );
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN My_Cursor;
myLoop: LOOP
FETCH My_Cursor into my_id, my_name;
IF done THEN
LEAVE myLoop;
END IF;
UPDATE t_user SET c_name = my_name WHERE id = my_id and rtrim(ltrim(c_name)) = '';
COMMIT;
END LOOP myLoop;
CLOSE My_Cursor;
END;
"""
.trimIndent()
val statement = MySqlHelper.parseStatement(sql)
if (statement is CreateProcedure) {
Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)
Assert.assertEquals("my_procedure", statement.procedureId?.procedureName)
Assert.assertEquals(2, statement.childStatements.size)
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-mysql-parser/src/test/resources/log4j2.xml
================================================
================================================
FILE: superior-oracle-parser/pom.xml
================================================
4.0.0
io.github.melin.superior
superior-sql-parser
4.0.23
superior-oracle-parser
superior-oracle-parser
io.github.melin.superior
superior-common-parser
${project.version}
================================================
FILE: superior-oracle-parser/src/main/antlr4/io/github/melin/superior/parser/oracle/antlr4/OracleLexer.g4
================================================
/**
* Oracle(c) PL/SQL 11g Parser
*
* Copyright (c) 2009-2011 Alexandre Porcelli
* Copyright (c) 2015-2019 Ivan Kochurkin (KvanTTT, kvanttt@gmail.com, Positive Technologies).
* Copyright (c) 2017 Mark Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
lexer grammar OracleLexer;
options {
superClass=OracleLexerBase;
}
ABORT : 'ABORT';
ABS : 'ABS';
ABSENT : 'ABSENT';
ACCESS : 'ACCESS';
ACCESSED : 'ACCESSED';
ACCESSIBLE : 'ACCESSIBLE';
ACCOUNT : 'ACCOUNT';
ACL : 'ACL';
ACOS : 'ACOS';
ACROSS : 'ACROSS';
ACTION : 'ACTION';
ACTIONS : 'ACTIONS';
ACTIVATE : 'ACTIVATE';
ACTIVE : 'ACTIVE';
ACTIVE_COMPONENT : 'ACTIVE_COMPONENT';
ACTIVE_DATA : 'ACTIVE_DATA';
ACTIVE_FUNCTION : 'ACTIVE_FUNCTION';
ACTIVE_TAG : 'ACTIVE_TAG';
ACTIVITY : 'ACTIVITY';
ADAPTIVE_PLAN : 'ADAPTIVE_PLAN';
ADD : 'ADD';
ADD_COLUMN : 'ADD_COLUMN';
ADD_GROUP : 'ADD_GROUP';
ADD_MONTHS : 'ADD_MONTHS';
ADJ_DATE : 'ADJ_DATE';
ADMIN : 'ADMIN';
ADMINISTER : 'ADMINISTER';
ADMINISTRATOR : 'ADMINISTRATOR';
ADVANCED : 'ADVANCED';
ADVISE : 'ADVISE';
ADVISOR : 'ADVISOR';
AFD_DISKSTRING : 'AFD_DISKSTRING';
AFTER : 'AFTER';
AGENT : 'AGENT';
AGGREGATE : 'AGGREGATE';
A_LETTER : 'A';
ALIAS : 'ALIAS';
ALL : 'ALL';
ALLOCATE : 'ALLOCATE';
ALLOW : 'ALLOW';
ALL_ROWS : 'ALL_ROWS';
ALTER : 'ALTER';
ALTERNATE : 'ALTERNATE';
ALWAYS : 'ALWAYS';
ANALYTIC : 'ANALYTIC';
ANALYZE : 'ANALYZE';
ANCESTOR : 'ANCESTOR';
ANCILLARY : 'ANCILLARY';
AND : 'AND';
AND_EQUAL : 'AND_EQUAL';
ANNOTATIONS : 'ANNOTATIONS';
ANOMALY : 'ANOMALY';
ANSI_REARCH : 'ANSI_REARCH';
ANTIJOIN : 'ANTIJOIN';
ANY : 'ANY';
ANYSCHEMA : 'ANYSCHEMA';
APPEND : 'APPEND';
APPENDCHILDXML : 'APPENDCHILDXML';
APPEND_VALUES : 'APPEND_VALUES';
APPLICATION : 'APPLICATION';
APPLY : 'APPLY';
APPROX_COUNT_DISTINCT : 'APPROX_COUNT_DISTINCT';
ARCHIVAL : 'ARCHIVAL';
ARCHIVE : 'ARCHIVE';
ARCHIVED : 'ARCHIVED';
ARCHIVELOG : 'ARCHIVELOG';
ARE : 'ARE';
ARRAY : 'ARRAY';
AS : 'AS';
ASC : 'ASC';
ASCII : 'ASCII';
ASCIISTR : 'ASCIISTR';
ASIN : 'ASIN';
ASIS : 'ASIS';
ASSEMBLY : 'ASSEMBLY';
ASSIGN : 'ASSIGN';
ASSOCIATE : 'ASSOCIATE';
ASYNC : 'ASYNC';
ASYNCHRONOUS : 'ASYNCHRONOUS';
ATAN2 : 'ATAN2';
ATAN : 'ATAN';
AT : 'AT';
ATTRIBUTE : 'ATTRIBUTE';
ATTRIBUTES : 'ATTRIBUTES';
AUDIT : 'AUDIT';
AUTHENTICATED : 'AUTHENTICATED';
AUTHENTICATION : 'AUTHENTICATION';
AUTHID : 'AUTHID';
AUTHORIZATION : 'AUTHORIZATION';
AUTOALLOCATE : 'AUTOALLOCATE';
AUTO : 'AUTO';
AUTOBACKUP : 'AUTOBACKUP';
AUTOEXTEND : 'AUTOEXTEND';
AUTO_LOGIN : 'AUTO_LOGIN';
AUTOMATIC : 'AUTOMATIC';
AUTONOMOUS_TRANSACTION : 'AUTONOMOUS_TRANSACTION';
AUTO_REOPTIMIZE : 'AUTO_REOPTIMIZE';
AVAILABILITY : 'AVAILABILITY';
AVRO : 'AVRO';
BACKGROUND : 'BACKGROUND';
BACKINGFILE : 'BACKINGFILE';
BACKUP : 'BACKUP';
BACKUPS : 'BACKUPS';
BACKUPSET : 'BACKUPSET';
BADFILE : 'BADFILE';
BASIC : 'BASIC';
BASICFILE : 'BASICFILE';
BATCH : 'BATCH';
BATCHSIZE : 'BATCHSIZE';
BATCH_TABLE_ACCESS_BY_ROWID : 'BATCH_TABLE_ACCESS_BY_ROWID';
BECOME : 'BECOME';
BEFORE : 'BEFORE';
BEGIN : 'BEGIN';
BEGINNING : 'BEGINNING';
BEGIN_OUTLINE_DATA : 'BEGIN_OUTLINE_DATA';
BEHALF : 'BEHALF';
BEQUEATH : 'BEQUEATH';
BETWEEN : 'BETWEEN';
BFILE : 'BFILE';
BFILENAME : 'BFILENAME';
BIG : 'BIG';
BIGFILE : 'BIGFILE';
BIGINT : 'BIGINT';
BINARY : 'BINARY';
BINARY_DOUBLE : 'BINARY_DOUBLE';
BINARY_DOUBLE_INFINITY : 'BINARY_DOUBLE_INFINITY';
BINARY_DOUBLE_NAN : 'BINARY_DOUBLE_NAN';
BINARY_FLOAT : 'BINARY_FLOAT';
BINARY_FLOAT_INFINITY : 'BINARY_FLOAT_INFINITY';
BINARY_FLOAT_NAN : 'BINARY_FLOAT_NAN';
BINARY_INTEGER : 'BINARY_INTEGER';
BIND_AWARE : 'BIND_AWARE';
BINDING : 'BINDING';
BIN_TO_NUM : 'BIN_TO_NUM';
BITAND : 'BITAND';
BITMAP_AND : 'BITMAP_AND';
BITMAP : 'BITMAP';
BITMAPS : 'BITMAPS';
BITMAP_TREE : 'BITMAP_TREE';
BITS : 'BITS';
BLANKS : 'BLANKS';
BLOB : 'BLOB';
BLOCK : 'BLOCK';
BLOCK_RANGE : 'BLOCK_RANGE';
BLOCKS : 'BLOCKS';
BLOCKSIZE : 'BLOCKSIZE';
BODY : 'BODY';
BOOLEAN : 'BOOLEAN';
BOTH : 'BOTH';
BOUND : 'BOUND';
BRANCH : 'BRANCH';
BREADTH : 'BREADTH';
BROADCAST : 'BROADCAST';
BSON : 'BSON';
BUFFER : 'BUFFER';
BUFFER_CACHE : 'BUFFER_CACHE';
BUFFER_POOL : 'BUFFER_POOL';
BUILD : 'BUILD';
BULK : 'BULK';
BY : 'BY';
BYPASS_RECURSIVE_CHECK : 'BYPASS_RECURSIVE_CHECK';
BYPASS_UJVC : 'BYPASS_UJVC';
BYTE : 'BYTE';
BYTES : 'BYTES';
BYTEORDERMARK : 'BYTEORDERMARK';
CACHE : 'CACHE';
CACHE_CB : 'CACHE_CB';
CACHE_INSTANCES : 'CACHE_INSTANCES';
CACHE_TEMP_TABLE : 'CACHE_TEMP_TABLE';
CACHING : 'CACHING';
CALCULATED : 'CALCULATED';
CALLBACK : 'CALLBACK';
CALL : 'CALL';
CANCEL : 'CANCEL';
CANONICAL : 'CANONICAL';
CAPACITY : 'CAPACITY';
CAPTION : 'CAPTION';
CARDINALITY : 'CARDINALITY';
CASCADE : 'CASCADE';
CASE : 'CASE';
CAST : 'CAST';
CASESENSITIVE : 'CASE-SENSITIVE';
CATEGORY : 'CATEGORY';
CDBDEFAULT : 'CDB$DEFAULT';
CEIL : 'CEIL';
CELL_FLASH_CACHE : 'CELL_FLASH_CACHE';
CERTIFICATE : 'CERTIFICATE';
CFILE : 'CFILE';
CHAINED : 'CHAINED';
CHANGE : 'CHANGE';
CHANGETRACKING : 'CHANGETRACKING';
CHANGE_DUPKEY_ERROR_INDEX : 'CHANGE_DUPKEY_ERROR_INDEX';
CHARACTER : 'CHARACTER';
CHARACTERS : 'CHARACTERS';
CHARACTERSET : 'CHARACTERSET';
CHAR : 'CHAR';
CHAR_CS : 'CHAR_CS';
CHARTOROWID : 'CHARTOROWID';
CHECK_ACL_REWRITE : 'CHECK_ACL_REWRITE';
CHECK : 'CHECK';
CHECKPOINT : 'CHECKPOINT';
CHILD : 'CHILD';
CHOOSE : 'CHOOSE';
CHR : 'CHR';
CHUNK : 'CHUNK';
CLASS : 'CLASS';
CLASSIFICATION : 'CLASSIFICATION';
CLASSIFIER : 'CLASSIFIER';
CLAUSE : 'CLAUSE';
CLEAN : 'CLEAN';
CLEANUP : 'CLEANUP';
CLEAR : 'CLEAR';
C_LETTER : 'C';
CLIENT : 'CLIENT';
CLOB : 'CLOB';
CLONE : 'CLONE';
CLOSE_CACHED_OPEN_CURSORS : 'CLOSE_CACHED_OPEN_CURSORS';
CLOSE : 'CLOSE';
CLUSTER_BY_ROWID : 'CLUSTER_BY_ROWID';
CLUSTER : 'CLUSTER';
CLUSTER_DETAILS : 'CLUSTER_DETAILS';
CLUSTER_DISTANCE : 'CLUSTER_DISTANCE';
CLUSTER_ID : 'CLUSTER_ID';
CLUSTERING : 'CLUSTERING';
CLUSTERING_FACTOR : 'CLUSTERING_FACTOR';
CLUSTER_PROBABILITY : 'CLUSTER_PROBABILITY';
CLUSTER_SET : 'CLUSTER_SET';
COALESCE : 'COALESCE';
COALESCE_SQ : 'COALESCE_SQ';
COARSE : 'COARSE';
CO_AUTH_IND : 'CO_AUTH_IND';
COLD : 'COLD';
COLLECT : 'COLLECT';
COLLECTION : 'COLLECTION';
COLUMNAR : 'COLUMNAR';
COLUMN_AUTH_INDICATOR : 'COLUMN_AUTH_INDICATOR';
COLUMN : 'COLUMN';
COLUMNS : 'COLUMNS';
COLUMN_STATS : 'COLUMN_STATS';
COLUMN_VALUE : 'COLUMN_VALUE';
COMMENT : 'COMMENT';
COMMIT : 'COMMIT';
COMMITTED : 'COMMITTED';
COMMON : 'COMMON';
COMMON_DATA : 'COMMON_DATA';
COMPACT : 'COMPACT';
COMPATIBLE : 'COMPATIBLE';
COMPATIBILITY : 'COMPATIBILITY';
COMPILE : 'COMPILE';
COMPLETE : 'COMPLETE';
COMPLIANCE : 'COMPLIANCE';
COMPONENT : 'COMPONENT';
COMPONENTS : 'COMPONENTS';
COMPOSE : 'COMPOSE';
COMPOSITE : 'COMPOSITE';
COMPOSITE_LIMIT : 'COMPOSITE_LIMIT';
COMPOUND : 'COMPOUND';
COMPRESS : 'COMPRESS';
COMPRESSION : 'COMPRESSION';
COMPUTE : 'COMPUTE';
CONCAT : 'CONCAT';
CON_DBID_TO_ID : 'CON_DBID_TO_ID';
CONDITIONAL : 'CONDITIONAL';
CONDITION : 'CONDITION';
CONFIRM : 'CONFIRM';
CONFORMING : 'CONFORMING';
CON_GUID_TO_ID : 'CON_GUID_TO_ID';
CON_ID : 'CON_ID';
CON_NAME_TO_ID : 'CON_NAME_TO_ID';
CONNECT_BY_CB_WHR_ONLY : 'CONNECT_BY_CB_WHR_ONLY';
CONNECT_BY_COMBINE_SW : 'CONNECT_BY_COMBINE_SW';
CONNECT_BY_COST_BASED : 'CONNECT_BY_COST_BASED';
CONNECT_BY_ELIM_DUPS : 'CONNECT_BY_ELIM_DUPS';
CONNECT_BY_FILTERING : 'CONNECT_BY_FILTERING';
CONNECT_BY_ISCYCLE : 'CONNECT_BY_ISCYCLE';
CONNECT_BY_ISLEAF : 'CONNECT_BY_ISLEAF';
CONNECT_BY_ROOT : 'CONNECT_BY_ROOT';
CONNECT : 'CONNECT';
CONNECT_TIME : 'CONNECT_TIME';
CONSIDER : 'CONSIDER';
CONSISTENT : 'CONSISTENT';
CONSTANT : 'CONSTANT';
CONST : 'CONST';
CONSTRAINT : 'CONSTRAINT';
CONSTRAINTS : 'CONSTRAINTS';
CONSTRUCTOR : 'CONSTRUCTOR';
CONTAINER : 'CONTAINER';
CONTAINERS : 'CONTAINERS';
CONTAINERS_DEFAULT : 'CONTAINERS_DEFAULT';
CONTAINER_DATA : 'CONTAINER_DATA';
CONTAINER_MAP : 'CONTAINER_MAP';
CONTENT : 'CONTENT';
CONTENTS : 'CONTENTS';
CONTEXT : 'CONTEXT';
CONTINUE : 'CONTINUE';
CONTROLFILE : 'CONTROLFILE';
CON_UID_TO_ID : 'CON_UID_TO_ID';
CONVERT : 'CONVERT';
CONVERSION : 'CONVERSION';
COOKIE : 'COOKIE';
COPY : 'COPY';
CORR_K : 'CORR_K';
CORR_S : 'CORR_S';
CORRUPTION : 'CORRUPTION';
CORRUPT_XID_ALL : 'CORRUPT_XID_ALL';
CORRUPT_XID : 'CORRUPT_XID';
COS : 'COS';
COSH : 'COSH';
COST : 'COST';
COST_XML_QUERY_REWRITE : 'COST_XML_QUERY_REWRITE';
COUNT : 'COUNT';
COUNTED : 'COUNTED';
COVAR_POP : 'COVAR_POP';
COVAR_SAMP : 'COVAR_SAMP';
CPU_COSTING : 'CPU_COSTING';
CPU_PER_CALL : 'CPU_PER_CALL';
CPU_PER_SESSION : 'CPU_PER_SESSION';
CRASH : 'CRASH';
CREATE : 'CREATE';
CREATE_FILE_DEST : 'CREATE_FILE_DEST';
CREATE_STORED_OUTLINES : 'CREATE_STORED_OUTLINES';
CREATION : 'CREATION';
CREDENTIAL : 'CREDENTIAL';
CRITICAL : 'CRITICAL';
CROSS : 'CROSS';
CROSSEDITION : 'CROSSEDITION';
CSCONVERT : 'CSCONVERT';
CSV : 'CSV';
CUBE_AJ : 'CUBE_AJ';
CUBE : 'CUBE';
CUBE_GB : 'CUBE_GB';
CUBE_SJ : 'CUBE_SJ';
CUME_DISTM : 'CUME_DISTM';
CURRENT : 'CURRENT';
CURRENT_DATE : 'CURRENT_DATE';
CURRENT_SCHEMA : 'CURRENT_SCHEMA';
CURRENT_TIME : 'CURRENT_TIME';
CURRENT_TIMESTAMP : 'CURRENT_TIMESTAMP';
CURRENT_USER : 'CURRENT_USER';
CURRENTV : 'CURRENTV';
CURSOR : 'CURSOR';
CURSOR_SHARING_EXACT : 'CURSOR_SHARING_EXACT';
CURSOR_SPECIFIC_SEGMENT : 'CURSOR_SPECIFIC_SEGMENT';
CUSTOMDATUM : 'CUSTOMDATUM';
CV : 'CV';
CYCLE : 'CYCLE';
DANGLING : 'DANGLING';
DATABASE : 'DATABASE';
DATA : 'DATA';
DATAFILE : 'DATAFILE';
DATAFILES : 'DATAFILES';
DATAGUARDCONFIG : 'DATAGUARDCONFIG';
DATAMOVEMENT : 'DATAMOVEMENT';
DATAOBJNO : 'DATAOBJNO';
DATAOBJ_TO_MAT_PARTITION : 'DATAOBJ_TO_MAT_PARTITION';
DATAOBJ_TO_PARTITION : 'DATAOBJ_TO_PARTITION';
DATAPUMP : 'DATAPUMP';
DATA_SECURITY_REWRITE_LIMIT : 'DATA_SECURITY_REWRITE_LIMIT';
DATE : 'DATE';
DATE_CACHE : 'DATE_CACHE';
DATE_FORMAT : 'DATE_FORMAT';
DATE_MODE : 'DATE_MODE';
DAY : 'DAY';
DAYS : 'DAYS';
DAY_TO_SECOND : 'DAY_TO_SECOND';
DBA : 'DBA';
DBA_RECYCLEBIN : 'DBA_RECYCLEBIN';
DBLINK : 'DBLINK';
DBMS_STATS : 'DBMS_STATS';
DB_ROLE_CHANGE : 'DB_ROLE_CHANGE';
DBTIMEZONE : 'DBTIMEZONE';
DB_UNIQUE_NAME : 'DB_UNIQUE_NAME';
DB_VERSION : 'DB_VERSION';
DDL : 'DDL';
DEALLOCATE : 'DEALLOCATE';
DEBUG : 'DEBUG';
DEBUGGER : 'DEBUGGER';
DEC : 'DEC';
DECIMAL : 'DECIMAL';
DECLARE : 'DECLARE';
DECOMPOSE : 'DECOMPOSE';
DECORRELATE : 'DECORRELATE';
DECR : 'DECR';
DECREMENT : 'DECREMENT';
DECRYPT : 'DECRYPT';
DEDUPLICATE : 'DEDUPLICATE';
DEFAULT : 'DEFAULT';
DEFAULTIF : 'DEFAULTIF';
DEFAULTS : 'DEFAULTS';
DEFAULT_COLLATION : 'DEFAULT_COLLATION';
DEFAULT_CREDENTIAL : 'DEFAULT_CREDENTIAL';
DEFERRABLE : 'DEFERRABLE';
DEFERRED : 'DEFERRED';
DEFINED : 'DEFINED';
DEFINE : 'DEFINE';
DEFINER : 'DEFINER';
DEGREE : 'DEGREE';
DELAY : 'DELAY';
DELEGATE : 'DELEGATE';
DELETE_ALL : 'DELETE_ALL';
DELETE : 'DELETE';
DELETEXML : 'DELETEXML';
DELIMITED : 'DELIMITED';
DEMAND : 'DEMAND';
DENSE_RANKM : 'DENSE_RANKM';
DEPENDENT : 'DEPENDENT';
DEPRECATE : 'DEPRECATE';
DEPTH : 'DEPTH';
DEQUEUE : 'DEQUEUE';
DEREF : 'DEREF';
DEREF_NO_REWRITE : 'DEREF_NO_REWRITE';
DESC : 'DESC';
DESCRIPTION : 'DESCRIPTION';
DESTROY : 'DESTROY';
DETACHED : 'DETACHED';
DETECTED : 'DETECTED';
DETERMINES : 'DETERMINES';
DETERMINISTIC : 'DETERMINISTIC';
DICTIONARY : 'DICTIONARY';
DIMENSION : 'DIMENSION';
DIMENSIONS : 'DIMENSIONS';
DIRECTIO : 'DIRECTIO';
DIRECT_LOAD : 'DIRECT_LOAD';
DIRECTORY : 'DIRECTORY';
DIRECT_PATH : 'DIRECT_PATH';
DISABLE_ALL : 'DISABLE_ALL';
DISABLE : 'DISABLE';
DISABLED : 'DISABLED';
DISABLE_DIRECTORY_LINK_CHECK : 'DISABLE_DIRECTORY_LINK_CHECK';
DISABLE_PARALLEL_DML : 'DISABLE_PARALLEL_DML';
DISABLE_PRESET : 'DISABLE_PRESET';
DISABLE_RPKE : 'DISABLE_RPKE';
DISALLOW : 'DISALLOW';
DISASSOCIATE : 'DISASSOCIATE';
DISCARD : 'DISCARD';
DISCARDFILE : 'DISCARDFILE';
DISCONNECT : 'DISCONNECT';
DISK : 'DISK';
DISKGROUP : 'DISKGROUP';
DISKGROUP_PLUS : '\'+ DISKGROUP';
DISKS : 'DISKS';
DISMOUNT : 'DISMOUNT';
DISTINCT : 'DISTINCT';
DISTINGUISHED : 'DISTINGUISHED';
DISTRIBUTED : 'DISTRIBUTED';
DISTRIBUTE : 'DISTRIBUTE';
DML : 'DML';
DML_UPDATE : 'DML_UPDATE';
DNFS_DISABLE : 'DNFS_DISABLE';
DNFS_ENABLE : 'DNFS_ENABLE';
DNFS_READBUFFERS : 'DNFS_READBUFFERS';
DOCFIDELITY : 'DOCFIDELITY';
DOCUMENT : 'DOCUMENT';
DOLLAR_ELSE : '$ELSE';
DOLLAR_ELSIF : '$ELSIF';
DOLLAR_END : '$END';
DOLLAR_ERROR : '$ERROR';
DOLLAR_IF : '$IF';
DOLLAR_THEN : '$THEN';
DOMAIN_INDEX_FILTER : 'DOMAIN_INDEX_FILTER';
DOMAIN_INDEX_NO_SORT : 'DOMAIN_INDEX_NO_SORT';
DOMAIN_INDEX_SORT : 'DOMAIN_INDEX_SORT';
DOUBLE : 'DOUBLE';
DOWNGRADE : 'DOWNGRADE';
DRIVING_SITE : 'DRIVING_SITE';
DROP_COLUMN : 'DROP_COLUMN';
DROP : 'DROP';
DROP_GROUP : 'DROP_GROUP';
DSINTERVAL_UNCONSTRAINED : 'DSINTERVAL_UNCONSTRAINED';
DST_UPGRADE_INSERT_CONV : 'DST_UPGRADE_INSERT_CONV';
DUMP : 'DUMP';
DUMPSET : 'DUMPSET';
DUPLICATE : 'DUPLICATE';
DV : 'DV';
DYNAMIC : 'DYNAMIC';
DYNAMIC_SAMPLING : 'DYNAMIC_SAMPLING';
DYNAMIC_SAMPLING_EST_CDN : 'DYNAMIC_SAMPLING_EST_CDN';
E_LETTER : 'E';
EACH : 'EACH';
EDITIONABLE : 'EDITIONABLE';
EDITION : 'EDITION';
EDITIONING : 'EDITIONING';
EDITIONS : 'EDITIONS';
ELEMENT : 'ELEMENT';
ELIM_GROUPBY : 'ELIM_GROUPBY';
ELIMINATE_JOIN : 'ELIMINATE_JOIN';
ELIMINATE_OBY : 'ELIMINATE_OBY';
ELIMINATE_OUTER_JOIN : 'ELIMINATE_OUTER_JOIN';
ELSE : 'ELSE';
ELSIF : 'ELSIF';
EM : 'EM';
EMBEDDED : 'EMBEDDED';
EMPTY_BLOB : 'EMPTY_BLOB';
EMPTY_CLOB : 'EMPTY_CLOB';
EMPTY_ : 'EMPTY';
ENABLE_ALL : 'ENABLE_ALL';
ENABLE : 'ENABLE';
ENABLED : 'ENABLED';
ENABLE_PARALLEL_DML : 'ENABLE_PARALLEL_DML';
ENABLE_PRESET : 'ENABLE_PRESET';
ENCLOSED : 'ENCLOSED';
ENCODING : 'ENCODING';
ENCRYPT : 'ENCRYPT';
ENCRYPTION : 'ENCRYPTION';
ENCRYPTPASSWORDISNULL : 'ENCRYPTPASSWORDISNULL';
END : 'END';
END_OUTLINE_DATA : 'END_OUTLINE_DATA';
ENDIAN : 'ENDIAN';
ENFORCED : 'ENFORCED';
ENFORCE : 'ENFORCE';
ENQUEUE : 'ENQUEUE';
ENTERPRISE : 'ENTERPRISE';
ENTITYESCAPING : 'ENTITYESCAPING';
ENTRY : 'ENTRY';
EQUIPART : 'EQUIPART';
ERR : 'ERR';
ERROR_ARGUMENT : 'ERROR_ARGUMENT';
ERROR : 'ERROR';
ERROR_ON_OVERLAP_TIME : 'ERROR_ON_OVERLAP_TIME';
ERRORS : 'ERRORS';
ERROR_INDEX : 'ERROR_INDEX';
ERROR_CODE : 'ERROR_CODE';
ESCAPE : 'ESCAPE';
ESCAPED : 'ESCAPED';
ESTIMATE : 'ESTIMATE';
EVAL : 'EVAL';
EVALNAME : 'EVALNAME';
EVALUATE : 'EVALUATE';
EVALUATION : 'EVALUATION';
EVENTS : 'EVENTS';
EVERY : 'EVERY';
EXCEPT : 'EXCEPT';
EXCEPTION : 'EXCEPTION';
EXCEPTION_INIT : 'EXCEPTION_INIT';
EXCEPTIONS : 'EXCEPTIONS';
EXCHANGE : 'EXCHANGE';
EXCLUDE : 'EXCLUDE';
EXCLUDING : 'EXCLUDING';
EXCLUSIVE : 'EXCLUSIVE';
EXECUTE : 'EXECUTE';
EXEMPT : 'EXEMPT';
EXISTING : 'EXISTING';
EXISTS : 'EXISTS';
EXISTSNODE : 'EXISTSNODE';
EXIT : 'EXIT';
EXPAND_GSET_TO_UNION : 'EXPAND_GSET_TO_UNION';
EXPAND_TABLE : 'EXPAND_TABLE';
EXP : 'EXP';
EXPIRE : 'EXPIRE';
EXPLAIN : 'EXPLAIN';
EXPLOSION : 'EXPLOSION';
EXPORT : 'EXPORT';
EXPR_CORR_CHECK : 'EXPR_CORR_CHECK';
EXPRESS : 'EXPRESS';
EXTENDS : 'EXTENDS';
EXTENT : 'EXTENT';
EXTENTS : 'EXTENTS';
EXTERNAL : 'EXTERNAL';
EXTERNALLY : 'EXTERNALLY';
EXTRACTCLOBXML : 'EXTRACTCLOBXML';
EXTRACT : 'EXTRACT';
EXTRACTVALUE : 'EXTRACTVALUE';
EXTRA : 'EXTRA';
FACILITY : 'FACILITY';
FACT : 'FACT';
FACTOR : 'FACTOR';
FACTORIZE_JOIN : 'FACTORIZE_JOIN';
FAILED : 'FAILED';
FAILED_LOGIN_ATTEMPTS : 'FAILED_LOGIN_ATTEMPTS';
FAILGROUP : 'FAILGROUP';
FAILOVER : 'FAILOVER';
FAILURE : 'FAILURE';
FALSE : 'FALSE';
FAMILY : 'FAMILY';
FAR : 'FAR';
FAST : 'FAST';
FASTSTART : 'FASTSTART';
FBTSCAN : 'FBTSCAN';
FEATURE : 'FEATURE';
FEATURE_DETAILS : 'FEATURE_DETAILS';
FEATURE_ID : 'FEATURE_ID';
FEATURE_SET : 'FEATURE_SET';
FEATURE_VALUE : 'FEATURE_VALUE';
FETCH : 'FETCH';
FIELD : 'FIELD';
FIELDS : 'FIELDS';
FILE : 'FILE';
FILE_NAME_CONVERT : 'FILE_NAME_CONVERT';
FILEGROUP : 'FILEGROUP';
FILESTORE : 'FILESTORE';
FILESYSTEM_LIKE_LOGGING : 'FILESYSTEM_LIKE_LOGGING';
FILTER : 'FILTER';
FINAL : 'FINAL';
FINE : 'FINE';
FINISH : 'FINISH';
FIRST : 'FIRST';
FIRSTM : 'FIRSTM';
FIRST_ROWS : 'FIRST_ROWS';
FIRST_VALUE : 'FIRST_VALUE';
FIXED : 'FIXED';
FIXED_VIEW_DATA : 'FIXED_VIEW_DATA';
FLAGGER : 'FLAGGER';
FLASHBACK : 'FLASHBACK';
FLASH_CACHE : 'FLASH_CACHE';
FLOAT : 'FLOAT';
FLOB : 'FLOB';
FLEX : 'FLEX';
FLOOR : 'FLOOR';
FLUSH : 'FLUSH';
FOLDER : 'FOLDER';
FOLLOWING : 'FOLLOWING';
FOLLOWS : 'FOLLOWS';
FORALL : 'FORALL';
FORCE : 'FORCE';
FORCE_XML_QUERY_REWRITE : 'FORCE_XML_QUERY_REWRITE';
FOREIGN : 'FOREIGN';
FOREVER : 'FOREVER';
FOR : 'FOR';
FORMAT : 'FORMAT';
FORWARD : 'FORWARD';
FRAGMENT_NUMBER : 'FRAGMENT_NUMBER';
FREELIST : 'FREELIST';
FREELISTS : 'FREELISTS';
FREEPOOLS : 'FREEPOOLS';
FRESH : 'FRESH';
FROM : 'FROM';
FROM_TZ : 'FROM_TZ';
FULL : 'FULL';
FULL_OUTER_JOIN_TO_OUTER : 'FULL_OUTER_JOIN_TO_OUTER';
FUNCTION : 'FUNCTION';
FUNCTIONS : 'FUNCTIONS';
FTP : 'FTP';
G_LETTER : 'G';
GATHER_OPTIMIZER_STATISTICS : 'GATHER_OPTIMIZER_STATISTICS';
GATHER_PLAN_STATISTICS : 'GATHER_PLAN_STATISTICS';
GBY_CONC_ROLLUP : 'GBY_CONC_ROLLUP';
GBY_PUSHDOWN : 'GBY_PUSHDOWN';
GENERATED : 'GENERATED';
GET : 'GET';
GLOBAL : 'GLOBAL';
GLOBALLY : 'GLOBALLY';
GLOBAL_NAME : 'GLOBAL_NAME';
GLOBAL_TOPIC_ENABLED : 'GLOBAL_TOPIC_ENABLED';
GOTO : 'GOTO';
GRANT : 'GRANT';
GROUP_BY : 'GROUP_BY';
GROUP : 'GROUP';
GROUP_ID : 'GROUP_ID';
GROUPING : 'GROUPING';
GROUPING_ID : 'GROUPING_ID';
GROUPS : 'GROUPS';
GUARANTEED : 'GUARANTEED';
GUARANTEE : 'GUARANTEE';
GUARD : 'GUARD';
HADOOP_TRAILERS : 'HADOOP_TRAILERS';
HALF_YEARS : 'HALF_YEARS';
HASH_AJ : 'HASH_AJ';
HASH : 'HASH';
HASHKEYS : 'HASHKEYS';
HASH_SJ : 'HASH_SJ';
HAVING : 'HAVING';
HEADER : 'HEADER';
HEAP : 'HEAP';
HELP : 'HELP';
HEXTORAW : 'HEXTORAW';
HEXTOREF : 'HEXTOREF';
HIDDEN_KEYWORD : 'HIDDEN';
HIDE : 'HIDE';
HIER_ORDER : 'HIER_ORDER';
HIERARCHICAL : 'HIERARCHICAL';
HIERARCHIES : 'HIERARCHIES';
HIERARCHY : 'HIERARCHY';
HIGH : 'HIGH';
HINTSET_BEGIN : 'HINTSET_BEGIN';
HINTSET_END : 'HINTSET_END';
HOT : 'HOT';
HOUR : 'HOUR';
HOURS : 'HOURS';
HTTP : 'HTTP';
HWM_BROKERED : 'HWM_BROKERED';
HYBRID : 'HYBRID';
H_LETTER : 'H';
IDENTIFIED : 'IDENTIFIED';
IDENTIFIER : 'IDENTIFIER';
IDENTITY : 'IDENTITY';
IDGENERATORS : 'IDGENERATORS';
ID : 'ID';
IDLE_TIME : 'IDLE_TIME';
IF : 'IF';
IGNORE : 'IGNORE';
IGNORE_CHARS_AFTER_EOR : 'IGNORE_CHARS_AFTER_EOR';
IGNORE_OPTIM_EMBEDDED_HINTS : 'IGNORE_OPTIM_EMBEDDED_HINTS';
IGNORE_ROW_ON_DUPKEY_INDEX : 'IGNORE_ROW_ON_DUPKEY_INDEX';
IGNORE_WHERE_CLAUSE : 'IGNORE_WHERE_CLAUSE';
ILM : 'ILM';
IMMEDIATE : 'IMMEDIATE';
IMPACT : 'IMPACT';
IMPORT : 'IMPORT';
INACTIVE : 'INACTIVE';
INACTIVE_ACCOUNT_TIME : 'INACTIVE_ACCOUNT_TIME';
INCLUDE : 'INCLUDE';
INCLUDE_VERSION : 'INCLUDE_VERSION';
INCLUDING : 'INCLUDING';
INCREMENTAL : 'INCREMENTAL';
INCREMENT : 'INCREMENT';
INCR : 'INCR';
INDENT : 'INDENT';
INDEX_ASC : 'INDEX_ASC';
INDEX_COMBINE : 'INDEX_COMBINE';
INDEX_DESC : 'INDEX_DESC';
INDEXED : 'INDEXED';
INDEXES : 'INDEXES';
INDEX_FFS : 'INDEX_FFS';
INDEX_FILTER : 'INDEX_FILTER';
INDEX : 'INDEX';
INDEXING : 'INDEXING';
INDEX_JOIN : 'INDEX_JOIN';
INDEX_ROWS : 'INDEX_ROWS';
INDEX_RRS : 'INDEX_RRS';
INDEX_RS_ASC : 'INDEX_RS_ASC';
INDEX_RS_DESC : 'INDEX_RS_DESC';
INDEX_RS : 'INDEX_RS';
INDEX_SCAN : 'INDEX_SCAN';
INDEX_SKIP_SCAN : 'INDEX_SKIP_SCAN';
INDEX_SS_ASC : 'INDEX_SS_ASC';
INDEX_SS_DESC : 'INDEX_SS_DESC';
INDEX_SS : 'INDEX_SS';
INDEX_STATS : 'INDEX_STATS';
INDEXTYPE : 'INDEXTYPE';
INDEXTYPES : 'INDEXTYPES';
INDICATOR : 'INDICATOR';
INDICES : 'INDICES';
INFINITE : 'INFINITE';
INFORMATIONAL : 'INFORMATIONAL';
INHERIT : 'INHERIT';
IN : 'IN';
INITCAP : 'INITCAP';
INITIAL : 'INITIAL';
INITIALIZED : 'INITIALIZED';
INITIALLY : 'INITIALLY';
INITRANS : 'INITRANS';
INLINE : 'INLINE';
INLINE_XMLTYPE_NT : 'INLINE_XMLTYPE_NT';
INMEMORY : 'INMEMORY';
IN_MEMORY_METADATA : 'IN_MEMORY_METADATA';
INMEMORY_PRUNING : 'INMEMORY_PRUNING';
INNER : 'INNER';
INOUT : 'INOUT';
INPLACE : 'INPLACE';
INPUTFORMAT : 'INPUTFORMAT';
INSERTCHILDXMLAFTER : 'INSERTCHILDXMLAFTER';
INSERTCHILDXMLBEFORE : 'INSERTCHILDXMLBEFORE';
INSERTCHILDXML : 'INSERTCHILDXML';
INSERT : 'INSERT';
INSERTXMLAFTER : 'INSERTXMLAFTER';
INSERTXMLBEFORE : 'INSERTXMLBEFORE';
INSTANCE : 'INSTANCE';
INSTANCES : 'INSTANCES';
INSTANTIABLE : 'INSTANTIABLE';
INSTANTLY : 'INSTANTLY';
INSTEAD : 'INSTEAD';
INSTR2 : 'INSTR2';
INSTR4 : 'INSTR4';
INSTRB : 'INSTRB';
INSTRC : 'INSTRC';
INSTR : 'INSTR';
INTEGER : 'INTEGER';
INTERLEAVED : 'INTERLEAVED';
INTERMEDIATE : 'INTERMEDIATE';
INTERNAL_CONVERT : 'INTERNAL_CONVERT';
INTERNAL_USE : 'INTERNAL_USE';
INTERPRETED : 'INTERPRETED';
INTERSECT : 'INTERSECT';
INTERVAL : 'INTERVAL';
INT : 'INT';
INTERNAL : 'INTERNAL';
INTO : 'INTO';
INVALIDATE : 'INVALIDATE';
INVALIDATION : 'INVALIDATION';
INVISIBLE : 'INVISIBLE';
IN_XQUERY : 'IN_XQUERY';
IO_OPTIONS : 'IO_OPTIONS';
IS : 'IS';
IS_LEAF : 'IS_LEAF';
ISOLATION : 'ISOLATION';
ISOLATION_LEVEL : 'ISOLATION_LEVEL';
ITEMS : 'ITEMS';
ITERATE : 'ITERATE';
ITERATION_NUMBER : 'ITERATION_NUMBER';
JAVA : 'JAVA';
JOB : 'JOB';
JOIN : 'JOIN';
JSON_ARRAYAGG : 'JSON_ARRAYAGG';
JSON_ARRAY : 'JSON_ARRAY';
JSON_EQUAL : 'JSON_EQUAL';
JSON_EXISTS2 : 'JSON_EXISTS2';
JSON_EXISTS : 'JSON_EXISTS';
JSONGET : 'JSONGET';
JSON : 'JSON';
JSON_OBJECTAGG : 'JSON_OBJECTAGG';
JSON_OBJECT : 'JSON_OBJECT';
JSONPARSE : 'JSONPARSE';
JSON_QUERY : 'JSON_QUERY';
JSON_SERIALIZE : 'JSON_SERIALIZE';
JSON_TABLE : 'JSON_TABLE';
JSON_TEXTCONTAINS2 : 'JSON_TEXTCONTAINS2';
JSON_TEXTCONTAINS : 'JSON_TEXTCONTAINS';
JSON_TRANSFORM : 'JSON_TRANSFORM';
JSON_VALUE : 'JSON_VALUE';
K_LETTER : 'K';
KEEP_DUPLICATES : 'KEEP_DUPLICATES';
KEEP : 'KEEP';
KERBEROS : 'KERBEROS';
KEY : 'KEY';
KEY_LENGTH : 'KEY_LENGTH';
KEYSIZE : 'KEYSIZE';
KEYS : 'KEYS';
KEYSTORE : 'KEYSTORE';
KILL : 'KILL';
LABEL : 'LABEL';
LANGUAGE : 'LANGUAGE';
LAST_DAY : 'LAST_DAY';
LAST : 'LAST';
LAST_VALUE : 'LAST_VALUE';
LATERAL : 'LATERAL';
LATEST : 'LATEST';
LAX : 'LAX';
LAYER : 'LAYER';
LDAP_REGISTRATION_ENABLED : 'LDAP_REGISTRATION_ENABLED';
LDAP_REGISTRATION : 'LDAP_REGISTRATION';
LDAP_REG_SYNC_INTERVAL : 'LDAP_REG_SYNC_INTERVAL';
LDRTRIM : 'LDRTRIM';
LEAF : 'LEAF';
LEAD_CDB : 'LEAD_CDB';
LEAD_CDB_URI : 'LEAD_CDB_URI';
LEADING : 'LEADING';
LEFT : 'LEFT';
LENGTH2 : 'LENGTH2';
LENGTH4 : 'LENGTH4';
LENGTHB : 'LENGTHB';
LENGTHC : 'LENGTHC';
LENGTH : 'LENGTH';
LESS : 'LESS';
LEVEL : 'LEVEL';
LEVEL_NAME : 'LEVEL_NAME';
LEVELS : 'LEVELS';
LIBRARY : 'LIBRARY';
LIFECYCLE : 'LIFECYCLE';
LIFE : 'LIFE';
LIFETIME : 'LIFETIME';
LIKE2 : 'LIKE2';
LIKE4 : 'LIKE4';
LIKEC : 'LIKEC';
LIKE_EXPAND : 'LIKE_EXPAND';
LIKE : 'LIKE';
LIMIT : 'LIMIT';
LINEAR : 'LINEAR';
LINES : 'LINES';
LINK : 'LINK';
LIST : 'LIST';
LITTLE : 'LITTLE';
LLS : 'LLS';
LN : 'LN';
LNNVL : 'LNNVL';
LOAD : 'LOAD';
LOB : 'LOB';
LOBFILE : 'LOBFILE';
LOBNVL : 'LOBNVL';
LOBS : 'LOBS';
LOCAL_INDEXES : 'LOCAL_INDEXES';
LOCAL : 'LOCAL';
LOCALTIME : 'LOCALTIME';
LOCALTIMESTAMP : 'LOCALTIMESTAMP';
LOCATION : 'LOCATION';
LOCATOR : 'LOCATOR';
LOCKDOWN : 'LOCKDOWN';
LOCKED : 'LOCKED';
LOCKING : 'LOCKING';
LOCK : 'LOCK';
LOGFILE : 'LOGFILE';
LOGFILES : 'LOGFILES';
LOGGING : 'LOGGING';
LOGICAL : 'LOGICAL';
LOGICAL_READS_PER_CALL : 'LOGICAL_READS_PER_CALL';
LOGICAL_READS_PER_SESSION : 'LOGICAL_READS_PER_SESSION';
LOG : 'LOG';
LOGMINING : 'LOGMINING';
LOGOFF : 'LOGOFF';
LOGON : 'LOGON';
LOG_READ_ONLY_VIOLATIONS : 'LOG_READ_ONLY_VIOLATIONS';
LONG : 'LONG';
LOOP : 'LOOP';
LOST : 'LOST';
LOWER : 'LOWER';
LOW : 'LOW';
LPAD : 'LPAD';
LRTRIM : 'LRTRIM';
LTRIM : 'LTRIM';
M_LETTER : 'M';
MAIN : 'MAIN';
MAKE_REF : 'MAKE_REF';
MANAGED : 'MANAGED';
MANAGE : 'MANAGE';
MANAGEMENT : 'MANAGEMENT';
MANAGER : 'MANAGER';
MANDATORY : 'MANDATORY';
MANUAL : 'MANUAL';
MAP : 'MAP';
MAPPING : 'MAPPING';
MASK : 'MASK';
MASTER : 'MASTER';
MATCHED : 'MATCHED';
MATCHES : 'MATCHES';
MATCH : 'MATCH';
MATCH_NUMBER : 'MATCH_NUMBER';
MATCH_RECOGNIZE : 'MATCH_RECOGNIZE';
MATERIALIZED : 'MATERIALIZED';
MATERIALIZE : 'MATERIALIZE';
MAXARCHLOGS : 'MAXARCHLOGS';
MAXDATAFILES : 'MAXDATAFILES';
MAXEXTENTS : 'MAXEXTENTS';
MAXIMIZE : 'MAXIMIZE';
MAXINSTANCES : 'MAXINSTANCES';
MAXLOGFILES : 'MAXLOGFILES';
MAXLOGHISTORY : 'MAXLOGHISTORY';
MAXLOGMEMBERS : 'MAXLOGMEMBERS';
MAX_SHARED_TEMP_SIZE : 'MAX_SHARED_TEMP_SIZE';
MAXSIZE : 'MAXSIZE';
MAXTRANS : 'MAXTRANS';
MAXVALUE : 'MAXVALUE';
MEASURE : 'MEASURE';
MEASURES : 'MEASURES';
MEDIUM : 'MEDIUM';
MEMBER : 'MEMBER';
MEMBER_CAPTION : 'MEMBER_CAPTION';
MEMBER_DESCRIPTION : 'MEMBER_DESCRIPTION';
MEMBER_NAME : 'MEMBER_NAME';
MEMBER_UNIQUE_NAME : 'MEMBER_UNIQUE_NAME';
MEMCOMPRESS : 'MEMCOMPRESS';
MEMORY : 'MEMORY';
MERGEACTIONS : 'MERGE$ACTIONS';
MERGE_AJ : 'MERGE_AJ';
MERGE_CONST_ON : 'MERGE_CONST_ON';
MERGE : 'MERGE';
MERGE_SJ : 'MERGE_SJ';
METADATA : 'METADATA';
METHOD : 'METHOD';
MIGRATE : 'MIGRATE';
MIGRATION : 'MIGRATION';
MINEXTENTS : 'MINEXTENTS';
MINIMIZE : 'MINIMIZE';
MINIMUM : 'MINIMUM';
MINING : 'MINING';
MINUS : 'MINUS';
MINUS_NULL : 'MINUS_NULL';
MINUTE : 'MINUTE';
MINUTES : 'MINUTES';
MINVALUE : 'MINVALUE';
MIRRORCOLD : 'MIRRORCOLD';
MIRRORHOT : 'MIRRORHOT';
MIRROR : 'MIRROR';
MISSING : 'MISSING';
MISMATCH : 'MISMATCH';
MLSLABEL : 'MLSLABEL';
MODEL_COMPILE_SUBQUERY : 'MODEL_COMPILE_SUBQUERY';
MODEL_DONTVERIFY_UNIQUENESS : 'MODEL_DONTVERIFY_UNIQUENESS';
MODEL_DYNAMIC_SUBQUERY : 'MODEL_DYNAMIC_SUBQUERY';
MODEL_MIN_ANALYSIS : 'MODEL_MIN_ANALYSIS';
MODEL : 'MODEL';
MODEL_NB : 'MODEL_NB';
MODEL_NO_ANALYSIS : 'MODEL_NO_ANALYSIS';
MODEL_PBY : 'MODEL_PBY';
MODEL_PUSH_REF : 'MODEL_PUSH_REF';
MODEL_SV : 'MODEL_SV';
MODE : 'MODE';
MODIFICATION : 'MODIFICATION';
MODIFY_COLUMN_TYPE : 'MODIFY_COLUMN_TYPE';
MODIFY : 'MODIFY';
MOD : 'MOD';
MODULE : 'MODULE';
MONITORING : 'MONITORING';
MONITOR : 'MONITOR';
MONTH : 'MONTH';
MONTHS_BETWEEN : 'MONTHS_BETWEEN';
MONTHS : 'MONTHS';
MOUNT : 'MOUNT';
MOUNTPATH : 'MOUNTPATH';
MOUNTPOINT : 'MOUNTPOINT';
MOVEMENT : 'MOVEMENT';
MOVE : 'MOVE';
MULTIDIMENSIONAL : 'MULTIDIMENSIONAL';
MULTISET : 'MULTISET';
MV_MERGE : 'MV_MERGE';
NAMED : 'NAMED';
NAME : 'NAME';
NAMESPACE : 'NAMESPACE';
NAN_ : 'NAN';
NANVL : 'NANVL';
NATIONAL : 'NATIONAL';
NATIVE_FULL_OUTER_JOIN : 'NATIVE_FULL_OUTER_JOIN';
NATIVE : 'NATIVE';
NATURAL : 'NATURAL';
NATURALN : 'NATURALN';
NAV : 'NAV';
NCHAR_CS : 'NCHAR_CS';
NCHAR : 'NCHAR';
NCHR : 'NCHR';
NCLOB : 'NCLOB';
NEEDED : 'NEEDED';
NEG : 'NEG';
NESTED : 'NESTED';
NESTED_TABLE_FAST_INSERT : 'NESTED_TABLE_FAST_INSERT';
NESTED_TABLE_GET_REFS : 'NESTED_TABLE_GET_REFS';
NESTED_TABLE_ID : 'NESTED_TABLE_ID';
NESTED_TABLE_SET_REFS : 'NESTED_TABLE_SET_REFS';
NESTED_TABLE_SET_SETID : 'NESTED_TABLE_SET_SETID';
NETWORK : 'NETWORK';
NEVER : 'NEVER';
NEW : 'NEW';
NEWLINE_ : 'NEWLINE';
NEW_TIME : 'NEW_TIME';
NEXT_DAY : 'NEXT_DAY';
NEXT : 'NEXT';
NL_AJ : 'NL_AJ';
NLJ_BATCHING : 'NLJ_BATCHING';
NLJ_INDEX_FILTER : 'NLJ_INDEX_FILTER';
NLJ_INDEX_SCAN : 'NLJ_INDEX_SCAN';
NLJ_PREFETCH : 'NLJ_PREFETCH';
NLS_CALENDAR : 'NLS_CALENDAR';
NLS_CHARACTERSET : 'NLS_CHARACTERSET';
NLS_CHARSET_DECL_LEN : 'NLS_CHARSET_DECL_LEN';
NLS_CHARSET_ID : 'NLS_CHARSET_ID';
NLS_CHARSET_NAME : 'NLS_CHARSET_NAME';
NLS_COMP : 'NLS_COMP';
NLS_CURRENCY : 'NLS_CURRENCY';
NLS_DATE_FORMAT : 'NLS_DATE_FORMAT';
NLS_DATE_LANGUAGE : 'NLS_DATE_LANGUAGE';
NLS_INITCAP : 'NLS_INITCAP';
NLS_ISO_CURRENCY : 'NLS_ISO_CURRENCY';
NL_SJ : 'NL_SJ';
NLS_LANG : 'NLS_LANG';
NLS_LANGUAGE : 'NLS_LANGUAGE';
NLS_LENGTH_SEMANTICS : 'NLS_LENGTH_SEMANTICS';
NLS_LOWER : 'NLS_LOWER';
NLS_NCHAR_CONV_EXCP : 'NLS_NCHAR_CONV_EXCP';
NLS_NUMERIC_CHARACTERS : 'NLS_NUMERIC_CHARACTERS';
NLS_SORT : 'NLS_SORT';
NLSSORT : 'NLSSORT';
NLS_SPECIAL_CHARS : 'NLS_SPECIAL_CHARS';
NLS_TERRITORY : 'NLS_TERRITORY';
NLS_UPPER : 'NLS_UPPER';
NO_ACCESS : 'NO_ACCESS';
NO_ADAPTIVE_PLAN : 'NO_ADAPTIVE_PLAN';
NO_ANSI_REARCH : 'NO_ANSI_REARCH';
NOAPPEND : 'NOAPPEND';
NOARCHIVELOG : 'NOARCHIVELOG';
NOAUDIT : 'NOAUDIT';
NOBADFILE : 'NOBADFILE';
NO_AUTO_REOPTIMIZE : 'NO_AUTO_REOPTIMIZE';
NO_BASETABLE_MULTIMV_REWRITE : 'NO_BASETABLE_MULTIMV_REWRITE';
NO_BATCH_TABLE_ACCESS_BY_ROWID : 'NO_BATCH_TABLE_ACCESS_BY_ROWID';
NO_BIND_AWARE : 'NO_BIND_AWARE';
NO_BUFFER : 'NO_BUFFER';
NOCACHE : 'NOCACHE';
NOCHECK : 'NOCHECK';
NO_CARTESIAN : 'NO_CARTESIAN';
NO_CHECK_ACL_REWRITE : 'NO_CHECK_ACL_REWRITE';
NO_CLUSTER_BY_ROWID : 'NO_CLUSTER_BY_ROWID';
NO_CLUSTERING : 'NO_CLUSTERING';
NO_COALESCE_SQ : 'NO_COALESCE_SQ';
NO_COMMON_DATA : 'NO_COMMON_DATA';
NOCOMPRESS : 'NOCOMPRESS';
NO_CONNECT_BY_CB_WHR_ONLY : 'NO_CONNECT_BY_CB_WHR_ONLY';
NO_CONNECT_BY_COMBINE_SW : 'NO_CONNECT_BY_COMBINE_SW';
NO_CONNECT_BY_COST_BASED : 'NO_CONNECT_BY_COST_BASED';
NO_CONNECT_BY_ELIM_DUPS : 'NO_CONNECT_BY_ELIM_DUPS';
NO_CONNECT_BY_FILTERING : 'NO_CONNECT_BY_FILTERING';
NOCOPY : 'NOCOPY';
NO_COST_XML_QUERY_REWRITE : 'NO_COST_XML_QUERY_REWRITE';
NO_CPU_COSTING : 'NO_CPU_COSTING';
NOCPU_COSTING : 'NOCPU_COSTING';
NOCYCLE : 'NOCYCLE';
NO_DATA_SECURITY_REWRITE : 'NO_DATA_SECURITY_REWRITE';
NO_DECORRELATE : 'NO_DECORRELATE';
NODELAY : 'NODELAY';
NODIRECTIO : 'NODIRECTIO';
NODISCARDFILE : 'NODISCARDFILE';
NO_DOMAIN_INDEX_FILTER : 'NO_DOMAIN_INDEX_FILTER';
NO_DST_UPGRADE_INSERT_CONV : 'NO_DST_UPGRADE_INSERT_CONV';
NO_ELIM_GROUPBY : 'NO_ELIM_GROUPBY';
NO_ELIMINATE_JOIN : 'NO_ELIMINATE_JOIN';
NO_ELIMINATE_OBY : 'NO_ELIMINATE_OBY';
NO_ELIMINATE_OUTER_JOIN : 'NO_ELIMINATE_OUTER_JOIN';
NOENTITYESCAPING : 'NOENTITYESCAPING';
NO_EXPAND_GSET_TO_UNION : 'NO_EXPAND_GSET_TO_UNION';
NO_EXPAND : 'NO_EXPAND';
NO_EXPAND_TABLE : 'NO_EXPAND_TABLE';
NOEXTEND : 'NOEXTEND';
NO_FACT : 'NO_FACT';
NO_FACTORIZE_JOIN : 'NO_FACTORIZE_JOIN';
NO_FILTERING : 'NO_FILTERING';
NOFORCE : 'NOFORCE';
NO_FULL_OUTER_JOIN_TO_OUTER : 'NO_FULL_OUTER_JOIN_TO_OUTER';
NO_GATHER_OPTIMIZER_STATISTICS : 'NO_GATHER_OPTIMIZER_STATISTICS';
NO_GBY_PUSHDOWN : 'NO_GBY_PUSHDOWN';
NOGUARANTEE : 'NOGUARANTEE';
NO_INDEX_FFS : 'NO_INDEX_FFS';
NO_INDEX : 'NO_INDEX';
NO_INDEX_SS : 'NO_INDEX_SS';
NO_INMEMORY : 'NO_INMEMORY';
NO_INMEMORY_PRUNING : 'NO_INMEMORY_PRUNING';
NOKEEP : 'NOKEEP';
NO_LOAD : 'NO_LOAD';
NOLOCAL : 'NOLOCAL';
NOLOG : 'NOLOG';
NOLOGFILE : 'NOLOGFILE';
NOLOGGING : 'NOLOGGING';
NOMAPPING : 'NOMAPPING';
NOMAXVALUE : 'NOMAXVALUE';
NO_MERGE : 'NO_MERGE';
NOMINIMIZE : 'NOMINIMIZE';
NOMINVALUE : 'NOMINVALUE';
NO_MODEL_PUSH_REF : 'NO_MODEL_PUSH_REF';
NO_MONITORING : 'NO_MONITORING';
NOMONITORING : 'NOMONITORING';
NO_MONITOR : 'NO_MONITOR';
NO_MULTIMV_REWRITE : 'NO_MULTIMV_REWRITE';
NO_NATIVE_FULL_OUTER_JOIN : 'NO_NATIVE_FULL_OUTER_JOIN';
NONBLOCKING : 'NONBLOCKING';
NONEDITIONABLE : 'NONEDITIONABLE';
NONE : 'NONE';
NONULLIF : 'NONULLIF';
NO_NLJ_BATCHING : 'NO_NLJ_BATCHING';
NO_NLJ_PREFETCH : 'NO_NLJ_PREFETCH';
NO : 'NO';
NONSCHEMA : 'NONSCHEMA';
NO_OBJECT_LINK : 'NO_OBJECT_LINK';
NOORDER : 'NOORDER';
NO_ORDER_ROLLUPS : 'NO_ORDER_ROLLUPS';
NO_OUTER_JOIN_TO_ANTI : 'NO_OUTER_JOIN_TO_ANTI';
NO_OUTER_JOIN_TO_INNER : 'NO_OUTER_JOIN_TO_INNER';
NOOVERRIDE : 'NOOVERRIDE';
NO_PARALLEL_INDEX : 'NO_PARALLEL_INDEX';
NOPARALLEL_INDEX : 'NOPARALLEL_INDEX';
NO_PARALLEL : 'NO_PARALLEL';
NOPARALLEL : 'NOPARALLEL';
NO_PARTIAL_COMMIT : 'NO_PARTIAL_COMMIT';
NO_PARTIAL_JOIN : 'NO_PARTIAL_JOIN';
NO_PARTIAL_ROLLUP_PUSHDOWN : 'NO_PARTIAL_ROLLUP_PUSHDOWN';
NOPARTITION : 'NOPARTITION';
NO_PLACE_DISTINCT : 'NO_PLACE_DISTINCT';
NO_PLACE_GROUP_BY : 'NO_PLACE_GROUP_BY';
NO_PQ_CONCURRENT_UNION : 'NO_PQ_CONCURRENT_UNION';
NO_PQ_MAP : 'NO_PQ_MAP';
NOPROMPT : 'NOPROMPT';
NO_PQ_REPLICATE : 'NO_PQ_REPLICATE';
NO_PQ_SKEW : 'NO_PQ_SKEW';
NO_PRUNE_GSETS : 'NO_PRUNE_GSETS';
NO_PULL_PRED : 'NO_PULL_PRED';
NO_PUSH_PRED : 'NO_PUSH_PRED';
NO_PUSH_SUBQ : 'NO_PUSH_SUBQ';
NO_PX_FAULT_TOLERANCE : 'NO_PX_FAULT_TOLERANCE';
NO_PX_JOIN_FILTER : 'NO_PX_JOIN_FILTER';
NO_QKN_BUFF : 'NO_QKN_BUFF';
NO_QUERY_TRANSFORMATION : 'NO_QUERY_TRANSFORMATION';
NO_REF_CASCADE : 'NO_REF_CASCADE';
NORELOCATE : 'NORELOCATE';
NORELY : 'NORELY';
NOREPAIR : 'NOREPAIR';
NOREPLAY : 'NOREPLAY';
NORESETLOGS : 'NORESETLOGS';
NO_RESULT_CACHE : 'NO_RESULT_CACHE';
NOREVERSE : 'NOREVERSE';
NO_REWRITE : 'NO_REWRITE';
NOREWRITE : 'NOREWRITE';
NORMAL : 'NORMAL';
NO_ROOT_SW_FOR_LOCAL : 'NO_ROOT_SW_FOR_LOCAL';
NOROWDEPENDENCIES : 'NOROWDEPENDENCIES';
NOSCALE : 'NOSCALE';
NOSCHEMACHECK : 'NOSCHEMACHECK';
NOSEGMENT : 'NOSEGMENT';
NO_SEMIJOIN : 'NO_SEMIJOIN';
NO_SEMI_TO_INNER : 'NO_SEMI_TO_INNER';
NO_SET_TO_JOIN : 'NO_SET_TO_JOIN';
NOSHARD : 'NOSHARD';
NOSORT : 'NOSORT';
NO_SQL_TRANSLATION : 'NO_SQL_TRANSLATION';
NO_SQL_TUNE : 'NO_SQL_TUNE';
NO_STAR_TRANSFORMATION : 'NO_STAR_TRANSFORMATION';
NO_STATEMENT_QUEUING : 'NO_STATEMENT_QUEUING';
NO_STATS_GSETS : 'NO_STATS_GSETS';
NOSTRICT : 'NOSTRICT';
NO_SUBQUERY_PRUNING : 'NO_SUBQUERY_PRUNING';
NO_SUBSTRB_PAD : 'NO_SUBSTRB_PAD';
NO_SWAP_JOIN_INPUTS : 'NO_SWAP_JOIN_INPUTS';
NOSWITCH : 'NOSWITCH';
NO_TABLE_LOOKUP_BY_NL : 'NO_TABLE_LOOKUP_BY_NL';
NO_TEMP_TABLE : 'NO_TEMP_TABLE';
NOTHING : 'NOTHING';
NOTIFICATION : 'NOTIFICATION';
NOTRIM : 'NOTRIM';
NOT : 'NOT';
NO_TRANSFORM_DISTINCT_AGG : 'NO_TRANSFORM_DISTINCT_AGG';
NO_UNNEST : 'NO_UNNEST';
NO_USE_CUBE : 'NO_USE_CUBE';
NO_USE_HASH_AGGREGATION : 'NO_USE_HASH_AGGREGATION';
NO_USE_HASH_GBY_FOR_PUSHDOWN : 'NO_USE_HASH_GBY_FOR_PUSHDOWN';
NO_USE_HASH : 'NO_USE_HASH';
NO_USE_INVISIBLE_INDEXES : 'NO_USE_INVISIBLE_INDEXES';
NO_USE_MERGE : 'NO_USE_MERGE';
NO_USE_NL : 'NO_USE_NL';
NO_USE_VECTOR_AGGREGATION : 'NO_USE_VECTOR_AGGREGATION';
NOVALIDATE : 'NOVALIDATE';
NO_VECTOR_TRANSFORM_DIMS : 'NO_VECTOR_TRANSFORM_DIMS';
NO_VECTOR_TRANSFORM_FACT : 'NO_VECTOR_TRANSFORM_FACT';
NO_VECTOR_TRANSFORM : 'NO_VECTOR_TRANSFORM';
NOWAIT : 'NOWAIT';
NO_XDB_FASTPATH_INSERT : 'NO_XDB_FASTPATH_INSERT';
NO_XML_DML_REWRITE : 'NO_XML_DML_REWRITE';
NO_XMLINDEX_REWRITE_IN_SELECT : 'NO_XMLINDEX_REWRITE_IN_SELECT';
NO_XMLINDEX_REWRITE : 'NO_XMLINDEX_REWRITE';
NO_XML_QUERY_REWRITE : 'NO_XML_QUERY_REWRITE';
NO_ZONEMAP : 'NO_ZONEMAP';
NTH_VALUE : 'NTH_VALUE';
NULLIF : 'NULLIF';
NULL_ : 'NULL';
NULLS : 'NULLS';
NUMBER : 'NUMBER';
NUMERIC : 'NUMERIC';
NUM_INDEX_KEYS : 'NUM_INDEX_KEYS';
NUMTODSINTERVAL : 'NUMTODSINTERVAL';
NUMTOYMINTERVAL : 'NUMTOYMINTERVAL';
NVARCHAR2 : 'NVARCHAR2';
NVL2 : 'NVL2';
OBJECT2XML : 'OBJECT2XML';
OBJECT : 'OBJECT';
OBJ_ID : 'OBJ_ID';
OBJNO : 'OBJNO';
OBJNO_REUSE : 'OBJNO_REUSE';
OCCURENCES : 'OCCURENCES';
OFFLINE : 'OFFLINE';
OFF : 'OFF';
OFFSET : 'OFFSET';
OF : 'OF';
OIDINDEX : 'OIDINDEX';
OID : 'OID';
OLAP : 'OLAP';
OLD : 'OLD';
OLD_PUSH_PRED : 'OLD_PUSH_PRED';
OLS : 'OLS';
OLTP : 'OLTP';
OMIT : 'OMIT';
ONE : 'ONE';
ONLINE : 'ONLINE';
ONLINELOG : 'ONLINELOG';
ONLY : 'ONLY';
ON : 'ON';
OPAQUE : 'OPAQUE';
OPAQUE_TRANSFORM : 'OPAQUE_TRANSFORM';
OPAQUE_XCANONICAL : 'OPAQUE_XCANONICAL';
OPCODE : 'OPCODE';
OPEN : 'OPEN';
OPERATIONS : 'OPERATIONS';
OPERATOR : 'OPERATOR';
OPT_ESTIMATE : 'OPT_ESTIMATE';
OPTIMAL : 'OPTIMAL';
OPTIMIZE : 'OPTIMIZE';
OPTIMIZER_FEATURES_ENABLE : 'OPTIMIZER_FEATURES_ENABLE';
OPTIMIZER_GOAL : 'OPTIMIZER_GOAL';
OPTION : 'OPTION';
OPTIONALLY : 'OPTIONALLY';
OPT_PARAM : 'OPT_PARAM';
ORA_BRANCH : 'ORA_BRANCH';
ORA_CHECK_ACL : 'ORA_CHECK_ACL';
ORA_CHECK_PRIVILEGE : 'ORA_CHECK_PRIVILEGE';
ORA_CLUSTERING : 'ORA_CLUSTERING';
ORADATA : 'ORADATA';
ORC : 'ORC';
ORACLE_DATE : 'ORACLE_DATE';
ORACLE_NUMBER : 'ORACLE_NUMBER';
ORADEBUG : 'ORADEBUG';
ORA_DST_AFFECTED : 'ORA_DST_AFFECTED';
ORA_DST_CONVERT : 'ORA_DST_CONVERT';
ORA_DST_ERROR : 'ORA_DST_ERROR';
ORA_GET_ACLIDS : 'ORA_GET_ACLIDS';
ORA_GET_PRIVILEGES : 'ORA_GET_PRIVILEGES';
ORA_HASH : 'ORA_HASH';
ORA_INVOKING_USERID : 'ORA_INVOKING_USERID';
ORA_INVOKING_USER : 'ORA_INVOKING_USER';
ORA_INVOKING_XS_USER_GUID : 'ORA_INVOKING_XS_USER_GUID';
ORA_INVOKING_XS_USER : 'ORA_INVOKING_XS_USER';
ORA_RAWCOMPARE : 'ORA_RAWCOMPARE';
ORA_RAWCONCAT : 'ORA_RAWCONCAT';
ORA_ROWSCN : 'ORA_ROWSCN';
ORA_ROWSCN_RAW : 'ORA_ROWSCN_RAW';
ORA_ROWVERSION : 'ORA_ROWVERSION';
ORA_TABVERSION : 'ORA_TABVERSION';
ORA_WRITE_TIME : 'ORA_WRITE_TIME';
ORDERED : 'ORDERED';
ORDERED_PREDICATES : 'ORDERED_PREDICATES';
ORDER : 'ORDER';
ORDINALITY : 'ORDINALITY';
OR_EXPAND : 'OR_EXPAND';
ORGANIZATION : 'ORGANIZATION';
OR : 'OR';
OR_PREDICATES : 'OR_PREDICATES';
OSERROR : 'OSERROR';
OTHER : 'OTHER';
OUTER_JOIN_TO_ANTI : 'OUTER_JOIN_TO_ANTI';
OUTER_JOIN_TO_INNER : 'OUTER_JOIN_TO_INNER';
OUTER : 'OUTER';
OUTLINE_LEAF : 'OUTLINE_LEAF';
OUTLINE : 'OUTLINE';
OUTPUTFORMAT : 'OUTPUTFORMAT';
OUT_OF_LINE : 'OUT_OF_LINE';
OUT : 'OUT';
OVERFLOW_NOMOVE : 'OVERFLOW_NOMOVE';
OVERFLOW_ : 'OVERFLOW';
OVERLAPS : 'OVERLAPS';
OVER : 'OVER';
OVERRIDE : 'OVERRIDE';
OVERRIDING : 'OVERRIDING';
OWNER : 'OWNER';
OWNERSHIP : 'OWNERSHIP';
OWN : 'OWN';
P_LETTER : 'P';
PACKAGE : 'PACKAGE';
PACKAGES : 'PACKAGES';
PARALLEL_ENABLE : 'PARALLEL_ENABLE';
PARALLEL_INDEX : 'PARALLEL_INDEX';
PARALLEL : 'PARALLEL';
PARAMETERFILE : 'PARAMETERFILE';
PARAMETERS : 'PARAMETERS';
PARAM : 'PARAM';
PARENT : 'PARENT';
PARENT_LEVEL_NAME : 'PARENT_LEVEL_NAME';
PARENT_UNIQUE_NAME : 'PARENT_UNIQUE_NAME';
PARITY : 'PARITY';
PARQUET : 'PARQUET';
PARTIAL_JOIN : 'PARTIAL_JOIN';
PARTIALLY : 'PARTIALLY';
PARTIAL : 'PARTIAL';
PARTIAL_ROLLUP_PUSHDOWN : 'PARTIAL_ROLLUP_PUSHDOWN';
PARTITION_HASH : 'PARTITION_HASH';
PARTITION_LIST : 'PARTITION_LIST';
PARTITION : 'PARTITION';
PARTITION_RANGE : 'PARTITION_RANGE';
PARTITIONS : 'PARTITIONS';
PARTNUMINST : 'PART$NUM$INST';
PASSING : 'PASSING';
PASSWORD_GRACE_TIME : 'PASSWORD_GRACE_TIME';
PASSWORD_LIFE_TIME : 'PASSWORD_LIFE_TIME';
PASSWORD_LOCK_TIME : 'PASSWORD_LOCK_TIME';
PASSWORD : 'PASSWORD';
PASSWORD_REUSE_MAX : 'PASSWORD_REUSE_MAX';
PASSWORD_REUSE_TIME : 'PASSWORD_REUSE_TIME';
PASSWORD_ROLLOVER_TIME : 'PASSWORD_ROLLOVER_TIME';
PASSWORD_VERIFY_FUNCTION : 'PASSWORD_VERIFY_FUNCTION';
PAST : 'PAST';
PATCH : 'PATCH';
PATH : 'PATH';
PATH_PREFIX : 'PATH_PREFIX';
PATHS : 'PATHS';
PATTERN : 'PATTERN';
PBL_HS_BEGIN : 'PBL_HS_BEGIN';
PBL_HS_END : 'PBL_HS_END';
PCTFREE : 'PCTFREE';
PCTINCREASE : 'PCTINCREASE';
PCTTHRESHOLD : 'PCTTHRESHOLD';
PCTUSED : 'PCTUSED';
PCTVERSION : 'PCTVERSION';
PENDING : 'PENDING';
PERCENT_FOUND : '%' SPACE* 'FOUND';
PERCENT_ISOPEN : '%' SPACE* 'ISOPEN';
PERCENT_NOTFOUND : '%' SPACE* 'NOTFOUND';
PERCENT_KEYWORD : 'PERCENT';
PERCENT_RANKM : 'PERCENT_RANKM';
PERCENT_ROWCOUNT : '%' SPACE* 'ROWCOUNT';
PERCENT_ROWTYPE : '%' SPACE* 'ROWTYPE';
PERCENT_TYPE : '%' SPACE* 'TYPE';
PERCENT_BULK_EXCEPTIONS : '%' SPACE* 'BULK_EXCEPTIONS';
PERCENT_BULK_ROWCOUNT : '%' SPACE* 'BULK_ROWCOUNT';
PERFORMANCE : 'PERFORMANCE';
PERIOD_KEYWORD : 'PERIOD';
PERMANENT : 'PERMANENT';
PERMISSION : 'PERMISSION';
PERMUTE : 'PERMUTE';
PER : 'PER';
PFILE : 'PFILE';
PHYSICAL : 'PHYSICAL';
PIKEY : 'PIKEY';
PIPELINED : 'PIPELINED';
PIPE : 'PIPE';
PIV_GB : 'PIV_GB';
PIVOT : 'PIVOT';
PIV_SSF : 'PIV_SSF';
PLACE_DISTINCT : 'PLACE_DISTINCT';
PLACE_GROUP_BY : 'PLACE_GROUP_BY';
PLAN : 'PLAN';
PLSCOPE_SETTINGS : 'PLSCOPE_SETTINGS';
PLS_INTEGER : 'PLS_INTEGER';
PLSQL_CCFLAGS : 'PLSQL_CCFLAGS';
PLSQL_CODE_TYPE : 'PLSQL_CODE_TYPE';
PLSQL_DEBUG : 'PLSQL_DEBUG';
PLSQL_OPTIMIZE_LEVEL : 'PLSQL_OPTIMIZE_LEVEL';
PLSQL_WARNINGS : 'PLSQL_WARNINGS';
PLUGGABLE : 'PLUGGABLE';
PMEM : 'PMEM';
POINT : 'POINT';
POLICY : 'POLICY';
POOL_16K : 'POOL_16K';
POOL_2K : 'POOL_2K';
POOL_32K : 'POOL_32K';
POOL_4K : 'POOL_4K';
POOL_8K : 'POOL_8K';
POSITION : 'POSITION';
POSITIVEN : 'POSITIVEN';
POSITIVE : 'POSITIVE';
POST_TRANSACTION : 'POST_TRANSACTION';
POWERMULTISET_BY_CARDINALITY : 'POWERMULTISET_BY_CARDINALITY';
POWERMULTISET : 'POWERMULTISET';
POWER : 'POWER';
PQ_CONCURRENT_UNION : 'PQ_CONCURRENT_UNION';
PQ_DISTRIBUTE : 'PQ_DISTRIBUTE';
PQ_DISTRIBUTE_WINDOW : 'PQ_DISTRIBUTE_WINDOW';
PQ_FILTER : 'PQ_FILTER';
PQ_MAP : 'PQ_MAP';
PQ_NOMAP : 'PQ_NOMAP';
PQ_REPLICATE : 'PQ_REPLICATE';
PQ_SKEW : 'PQ_SKEW';
PRAGMA : 'PRAGMA';
PREBUILT : 'PREBUILT';
PRECEDES : 'PRECEDES';
PRECEDING : 'PRECEDING';
PRECISION : 'PRECISION';
PRECOMPUTE_SUBQUERY : 'PRECOMPUTE_SUBQUERY';
PREDICATE_REORDERS : 'PREDICATE_REORDERS';
PRELOAD : 'PRELOAD';
PREPARE : 'PREPARE';
PREPROCESSOR : 'PREPROCESSOR';
PRESENTNNV : 'PRESENTNNV';
PRESENT : 'PRESENT';
PRESENTV : 'PRESENTV';
PRESERVE_OID : 'PRESERVE_OID';
PRESERVE : 'PRESERVE';
PRETTY : 'PRETTY';
PREVIOUS : 'PREVIOUS';
PREV : 'PREV';
PRIMARY : 'PRIMARY';
PRINTBLOBTOCLOB : 'PRINTBLOBTOCLOB';
PRIORITY : 'PRIORITY';
PRIOR : 'PRIOR';
PRIVATE : 'PRIVATE';
PRIVATE_SGA : 'PRIVATE_SGA';
PRIVILEGED : 'PRIVILEGED';
PRIVILEGE : 'PRIVILEGE';
PRIVILEGES : 'PRIVILEGES';
PROCEDURAL : 'PROCEDURAL';
PROCEDURE : 'PROCEDURE';
PROCESS : 'PROCESS';
PROFILE : 'PROFILE';
PROGRAM : 'PROGRAM';
PROJECT : 'PROJECT';
PROPAGATE : 'PROPAGATE';
PROPERTY : 'PROPERTY';
PROTECTED : 'PROTECTED';
PROTECTION : 'PROTECTION';
PROTOCOL : 'PROTOCOL';
PROXY : 'PROXY';
PRUNING : 'PRUNING';
PUBLIC : 'PUBLIC';
PULL_PRED : 'PULL_PRED';
PURGE : 'PURGE';
PUSH_PRED : 'PUSH_PRED';
PUSH_SUBQ : 'PUSH_SUBQ';
PX_FAULT_TOLERANCE : 'PX_FAULT_TOLERANCE';
PX_GRANULE : 'PX_GRANULE';
PX_JOIN_FILTER : 'PX_JOIN_FILTER';
QB_NAME : 'QB_NAME';
QUARTERS : 'QUARTERS';
QUERY_BLOCK : 'QUERY_BLOCK';
QUERY : 'QUERY';
QUEUE_CURR : 'QUEUE_CURR';
QUEUE : 'QUEUE';
QUEUE_ROWP : 'QUEUE_ROWP';
QUIESCE : 'QUIESCE';
QUORUM : 'QUORUM';
QUOTA : 'QUOTA';
QUOTAGROUP : 'QUOTAGROUP';
RAISE : 'RAISE';
RANDOM_LOCAL : 'RANDOM_LOCAL';
RANDOM : 'RANDOM';
RANGE : 'RANGE';
RANKM : 'RANKM';
RAPIDLY : 'RAPIDLY';
RAW : 'RAW';
RAWTOHEX : 'RAWTOHEX';
RAWTONHEX : 'RAWTONHEX';
RBA : 'RBA';
RBO_OUTLINE : 'RBO_OUTLINE';
RCFILE : 'RCFILE';
RDBA : 'RDBA';
READ : 'READ';
READS : 'READS';
READSIZE : 'READSIZE';
REALM : 'REALM';
REAL : 'REAL';
REBALANCE : 'REBALANCE';
REBUILD : 'REBUILD';
RECORD : 'RECORD';
RECORDS : 'RECORDS';
RECORDS_PER_BLOCK : 'RECORDS_PER_BLOCK';
RECOVERABLE : 'RECOVERABLE';
RECOVER : 'RECOVER';
RECOVERY : 'RECOVERY';
RECYCLEBIN : 'RECYCLEBIN';
RECYCLE : 'RECYCLE';
REDACTION : 'REDACTION';
REDEFINE : 'REDEFINE';
REDO : 'REDO';
REDUCED : 'REDUCED';
REDUNDANCY : 'REDUNDANCY';
REF_CASCADE_CURSOR : 'REF_CASCADE_CURSOR';
REFERENCED : 'REFERENCED';
REFERENCE : 'REFERENCE';
REFERENCES : 'REFERENCES';
REFERENCING : 'REFERENCING';
REF : 'REF';
REFRESH : 'REFRESH';
REFTOHEX : 'REFTOHEX';
REGEXP_COUNT : 'REGEXP_COUNT';
REGEXP_INSTR : 'REGEXP_INSTR';
REGEXP_LIKE : 'REGEXP_LIKE';
REGEXP_REPLACE : 'REGEXP_REPLACE';
REGEXP_SUBSTR : 'REGEXP_SUBSTR';
REGISTER : 'REGISTER';
REGR_AVGX : 'REGR_AVGX';
REGR_AVGY : 'REGR_AVGY';
REGR_COUNT : 'REGR_COUNT';
REGR_INTERCEPT : 'REGR_INTERCEPT';
REGR_R2 : 'REGR_R2';
REGR_SLOPE : 'REGR_SLOPE';
REGR_SXX : 'REGR_SXX';
REGR_SXY : 'REGR_SXY';
REGR_SYY : 'REGR_SYY';
REGULAR : 'REGULAR';
REJECT : 'REJECT';
REKEY : 'REKEY';
RELATIONAL : 'RELATIONAL';
RELIES_ON : 'RELIES_ON';
RELOCATE : 'RELOCATE';
RELY : 'RELY';
REMAINDER : 'REMAINDER';
REMOTE : 'REMOTE';
REMOTE_MAPPED : 'REMOTE_MAPPED';
REMOVE : 'REMOVE';
RENAME : 'RENAME';
REPAIR : 'REPAIR';
REPEAT : 'REPEAT';
REPLACE : 'REPLACE';
REPLICATION : 'REPLICATION';
REQUIRED : 'REQUIRED';
RESETLOGS : 'RESETLOGS';
RESET : 'RESET';
RESIZE : 'RESIZE';
RESOLVE : 'RESOLVE';
RESOLVER : 'RESOLVER';
RESOURCE : 'RESOURCE';
RESPECT : 'RESPECT';
RESTART : 'RESTART';
RESTORE_AS_INTERVALS : 'RESTORE_AS_INTERVALS';
RESTORE : 'RESTORE';
RESTRICT_ALL_REF_CONS : 'RESTRICT_ALL_REF_CONS';
RESTRICTED : 'RESTRICTED';
RESTRICT_REFERENCES : 'RESTRICT_REFERENCES';
RESTRICT : 'RESTRICT';
RESULT_CACHE : 'RESULT_CACHE';
RESULT : 'RESULT';
RESUMABLE : 'RESUMABLE';
RESUME : 'RESUME';
RETENTION : 'RETENTION';
RETRY_ON_ROW_CHANGE : 'RETRY_ON_ROW_CHANGE';
RETURNING : 'RETURNING';
RETURN : 'RETURN';
REUSE : 'REUSE';
REVERSE : 'REVERSE';
REVOKE : 'REVOKE';
REWRITE_OR_ERROR : 'REWRITE_OR_ERROR';
REWRITE : 'REWRITE';
RIGHT : 'RIGHT';
ROLE : 'ROLE';
ROLESET : 'ROLESET';
ROLES : 'ROLES';
ROLLBACK : 'ROLLBACK';
ROLLING : 'ROLLING';
ROLLUP : 'ROLLUP';
ROWDEPENDENCIES : 'ROWDEPENDENCIES';
ROWID_MAPPING_TABLE : 'ROWID_MAPPING_TABLE';
ROWID : 'ROWID';
ROWIDTOCHAR : 'ROWIDTOCHAR';
ROWIDTONCHAR : 'ROWIDTONCHAR';
ROW_LENGTH : 'ROW_LENGTH';
ROWNUM : 'ROWNUM';
ROW : 'ROW';
ROWS : 'ROWS';
RPAD : 'RPAD';
RTRIM : 'RTRIM';
RULE : 'RULE';
RULES : 'RULES';
RUNNING : 'RUNNING';
SALT : 'SALT';
SAMPLE : 'SAMPLE';
SAVE_AS_INTERVALS : 'SAVE_AS_INTERVALS';
SAVEPOINT : 'SAVEPOINT';
SAVE : 'SAVE';
SB4 : 'SB4';
SCALE_ROWS : 'SCALE_ROWS';
SCALE : 'SCALE';
SCAN_INSTANCES : 'SCAN_INSTANCES';
SCAN : 'SCAN';
SCHEDULER : 'SCHEDULER';
SCHEMACHECK : 'SCHEMACHECK';
SCHEMA : 'SCHEMA';
SCN_ASCENDING : 'SCN_ASCENDING';
SCN : 'SCN';
SCOPE : 'SCOPE';
SCRUB : 'SCRUB';
SD_ALL : 'SD_ALL';
SD_INHIBIT : 'SD_INHIBIT';
SDO_GEOM_MBR : 'SDO_GEOM_MBR';
SDO_GEOMETRY : 'SDO_GEOMETRY';
SD_SHOW : 'SD_SHOW';
SEARCH : 'SEARCH';
SECOND : 'SECOND';
SECONDS : 'SECONDS';
SECRET : 'SECRET';
SECUREFILE_DBA : 'SECUREFILE_DBA';
SECUREFILE : 'SECUREFILE';
SECURITY : 'SECURITY';
SEED : 'SEED';
SEG_BLOCK : 'SEG_BLOCK';
SEG_FILE : 'SEG_FILE';
SEGMENT : 'SEGMENT';
SELECTIVITY : 'SELECTIVITY';
SELECT : 'SELECT';
SELF : 'SELF';
SEMIJOIN_DRIVER : 'SEMIJOIN_DRIVER';
SEMIJOIN : 'SEMIJOIN';
SEMI_TO_INNER : 'SEMI_TO_INNER';
SEQUENCED : 'SEQUENCED';
SEQUENCE : 'SEQUENCE';
SEQUENCEFILE : 'SEQUENCEFILE';
SEQUENTIAL : 'SEQUENTIAL';
SEQ : 'SEQ';
SERDE : 'SERDE';
SERDEPROPERTIES : 'SERDEPROPERTIES';
SERIALIZABLE : 'SERIALIZABLE';
SERIALLY_REUSABLE : 'SERIALLY_REUSABLE';
SERIAL : 'SERIAL';
SERVERERROR : 'SERVERERROR';
SERVICE_NAME_CONVERT : 'SERVICE_NAME_CONVERT';
SERVICE : 'SERVICE';
SERVICES : 'SERVICES';
SESSION_CACHED_CURSORS : 'SESSION_CACHED_CURSORS';
SESSION : 'SESSION';
SESSIONS_PER_USER : 'SESSIONS_PER_USER';
SESSIONTIMEZONE : 'SESSIONTIMEZONE';
SESSIONTZNAME : 'SESSIONTZNAME';
SET : 'SET';
SETS : 'SETS';
SETTINGS : 'SETTINGS';
SET_TO_JOIN : 'SET_TO_JOIN';
SEVERE : 'SEVERE';
SHARD : 'SHARD';
SHARDSPACE : 'SHARDSPACE';
SHARED_POOL : 'SHARED_POOL';
SHARED : 'SHARED';
SHARE : 'SHARE';
SHARING : 'SHARING';
SHELFLIFE : 'SHELFLIFE';
SHOW : 'SHOW';
SHRINK : 'SHRINK';
SHUTDOWN : 'SHUTDOWN';
SIBLINGS : 'SIBLINGS';
SID : 'SID';
SITE : 'SITE';
SIGNAL_COMPONENT : 'SIGNAL_COMPONENT';
SIGNAL_FUNCTION : 'SIGNAL_FUNCTION';
SIGN : 'SIGN';
SIGNTYPE : 'SIGNTYPE';
SIMPLE_INTEGER : 'SIMPLE_INTEGER';
SIMPLE : 'SIMPLE';
SINGLE : 'SINGLE';
SINGLETASK : 'SINGLETASK';
SINH : 'SINH';
SIN : 'SIN';
SIZE : 'SIZE';
SIZES : 'SIZES';
SKIP_EXT_OPTIMIZER : 'SKIP_EXT_OPTIMIZER';
SKIP_ : 'SKIP';
SKIP_UNQ_UNUSABLE_IDX : 'SKIP_UNQ_UNUSABLE_IDX';
SKIP_UNUSABLE_INDEXES : 'SKIP_UNUSABLE_INDEXES';
SMALLFILE : 'SMALLFILE';
SMALLINT : 'SMALLINT';
SNAPSHOT : 'SNAPSHOT';
SOME : 'SOME';
SORT : 'SORT';
SOUNDEX : 'SOUNDEX';
SOURCE_FILE_DIRECTORY : 'SOURCE_FILE_DIRECTORY';
SOURCE_FILE_NAME_CONVERT : 'SOURCE_FILE_NAME_CONVERT';
SOURCE : 'SOURCE';
SPACE_KEYWORD : 'SPACE';
SPECIFICATION : 'SPECIFICATION';
SPFILE : 'SPFILE';
SPLIT : 'SPLIT';
SPREADSHEET : 'SPREADSHEET';
SQLDATA : 'SQLDATA';
SQLERROR : 'SQLERROR';
SQLLDR : 'SQLLDR';
SQL : 'SQL';
FILE_EXT : 'PKB' | 'PKS';
SQL_MACRO : 'SQL_MACRO';
SQL_TRACE : 'SQL_TRACE';
SQL_TRANSLATION_PROFILE : 'SQL_TRANSLATION_PROFILE';
SQRT : 'SQRT';
STALE : 'STALE';
STANDALONE : 'STANDALONE';
STANDARD : 'STANDARD';
STANDARD_HASH : 'STANDARD_HASH';
STANDBY_MAX_DATA_DELAY : 'STANDBY_MAX_DATA_DELAY';
STANDBYS : 'STANDBYS';
STANDBY : 'STANDBY';
STAR : 'STAR';
STAR_TRANSFORMATION : 'STAR_TRANSFORMATION';
START : 'START';
STARTOF : 'STARTOF';
STARTUP : 'STARTUP';
STATEMENT_ID : 'STATEMENT_ID';
STATEMENT_QUEUING : 'STATEMENT_QUEUING';
STATEMENTS : 'STATEMENTS';
STATEMENT : 'STATEMENT';
STATE : 'STATE';
STATIC : 'STATIC';
STATISTICS : 'STATISTICS';
STATS_BINOMIAL_TEST : 'STATS_BINOMIAL_TEST';
STATS_CROSSTAB : 'STATS_CROSSTAB';
STATS_F_TEST : 'STATS_F_TEST';
STATS_KS_TEST : 'STATS_KS_TEST';
STATS_MODE : 'STATS_MODE';
STATS_MW_TEST : 'STATS_MW_TEST';
STATS_ONE_WAY_ANOVA : 'STATS_ONE_WAY_ANOVA';
STATS_T_TEST_INDEP : 'STATS_T_TEST_INDEP';
STATS_T_TEST_INDEPU : 'STATS_T_TEST_INDEPU';
STATS_T_TEST_ONE : 'STATS_T_TEST_ONE';
STATS_T_TEST_PAIRED : 'STATS_T_TEST_PAIRED';
STATS_WSR_TEST : 'STATS_WSR_TEST';
STDDEV_POP : 'STDDEV_POP';
STDDEV_SAMP : 'STDDEV_SAMP';
STOP : 'STOP';
STORAGE : 'STORAGE';
STORE : 'STORE';
STREAMS : 'STREAMS';
STREAM : 'STREAM';
STRICT : 'STRICT';
STRING : 'STRING';
STRIPE_COLUMNS : 'STRIPE_COLUMNS';
STRIPE_WIDTH : 'STRIPE_WIDTH';
STRIP : 'STRIP';
STRUCTURE : 'STRUCTURE';
SUBMULTISET : 'SUBMULTISET';
SUBPARTITION_REL : 'SUBPARTITION_REL';
SUBPARTITIONS : 'SUBPARTITIONS';
SUBPARTITION : 'SUBPARTITION';
SUBQUERIES : 'SUBQUERIES';
SUBQUERY_PRUNING : 'SUBQUERY_PRUNING';
SUBSCRIBE : 'SUBSCRIBE';
SUBSET : 'SUBSET';
SUBSTITUTABLE : 'SUBSTITUTABLE';
SUBSTR2 : 'SUBSTR2';
SUBSTR4 : 'SUBSTR4';
SUBSTRB : 'SUBSTRB';
SUBSTRC : 'SUBSTRC';
SUBTYPE : 'SUBTYPE';
SUCCESSFUL : 'SUCCESSFUL';
SUCCESS : 'SUCCESS';
SUMMARY : 'SUMMARY';
SUPPLEMENTAL : 'SUPPLEMENTAL';
SUSPEND : 'SUSPEND';
SWAP_JOIN_INPUTS : 'SWAP_JOIN_INPUTS';
SWITCHOVER : 'SWITCHOVER';
SWITCH : 'SWITCH';
SYNCHRONOUS : 'SYNCHRONOUS';
SYNC : 'SYNC';
SYNONYM : 'SYNONYM';
SYS : 'SYS';
SYSASM : 'SYSASM';
SYS_AUDIT : 'SYS_AUDIT';
SYSAUX : 'SYSAUX';
SYSBACKUP : 'SYSBACKUP';
SYS_CHECKACL : 'SYS_CHECKACL';
SYS_CHECK_PRIVILEGE : 'SYS_CHECK_PRIVILEGE';
SYS_CONNECT_BY_PATH : 'SYS_CONNECT_BY_PATH';
SYS_CONTEXT : 'SYS_CONTEXT';
SYSDATE : 'SYSDATE';
SYSDBA : 'SYSDBA';
SYS_DBURIGEN : 'SYS_DBURIGEN';
SYSDG : 'SYSDG';
SYS_DL_CURSOR : 'SYS_DL_CURSOR';
SYS_DM_RXFORM_CHR : 'SYS_DM_RXFORM_CHR';
SYS_DM_RXFORM_NUM : 'SYS_DM_RXFORM_NUM';
SYS_DOM_COMPARE : 'SYS_DOM_COMPARE';
SYS_DST_PRIM2SEC : 'SYS_DST_PRIM2SEC';
SYS_DST_SEC2PRIM : 'SYS_DST_SEC2PRIM';
SYS_ET_BFILE_TO_RAW : 'SYS_ET_BFILE_TO_RAW';
SYS_ET_BLOB_TO_IMAGE : 'SYS_ET_BLOB_TO_IMAGE';
SYS_ET_IMAGE_TO_BLOB : 'SYS_ET_IMAGE_TO_BLOB';
SYS_ET_RAW_TO_BFILE : 'SYS_ET_RAW_TO_BFILE';
SYS_EXTPDTXT : 'SYS_EXTPDTXT';
SYS_EXTRACT_UTC : 'SYS_EXTRACT_UTC';
SYS_FBT_INSDEL : 'SYS_FBT_INSDEL';
SYS_FILTER_ACLS : 'SYS_FILTER_ACLS';
SYS_FNMATCHES : 'SYS_FNMATCHES';
SYS_FNREPLACE : 'SYS_FNREPLACE';
SYS_GET_ACLIDS : 'SYS_GET_ACLIDS';
SYS_GET_COL_ACLIDS : 'SYS_GET_COL_ACLIDS';
SYS_GET_PRIVILEGES : 'SYS_GET_PRIVILEGES';
SYS_GETTOKENID : 'SYS_GETTOKENID';
SYS_GETXTIVAL : 'SYS_GETXTIVAL';
SYS_GUID : 'SYS_GUID';
SYSGUID : 'SYSGUID';
SYSKM : 'SYSKM';
SYS_MAKE_XMLNODEID : 'SYS_MAKE_XMLNODEID';
SYS_MAKEXML : 'SYS_MAKEXML';
SYS_MKXMLATTR : 'SYS_MKXMLATTR';
SYS_MKXTI : 'SYS_MKXTI';
SYSOBJ : 'SYSOBJ';
SYS_OP_ADT2BIN : 'SYS_OP_ADT2BIN';
SYS_OP_ADTCONS : 'SYS_OP_ADTCONS';
SYS_OP_ALSCRVAL : 'SYS_OP_ALSCRVAL';
SYS_OP_ATG : 'SYS_OP_ATG';
SYS_OP_BIN2ADT : 'SYS_OP_BIN2ADT';
SYS_OP_BITVEC : 'SYS_OP_BITVEC';
SYS_OP_BL2R : 'SYS_OP_BL2R';
SYS_OP_BLOOM_FILTER_LIST : 'SYS_OP_BLOOM_FILTER_LIST';
SYS_OP_BLOOM_FILTER : 'SYS_OP_BLOOM_FILTER';
SYS_OP_C2C : 'SYS_OP_C2C';
SYS_OP_CAST : 'SYS_OP_CAST';
SYS_OP_CEG : 'SYS_OP_CEG';
SYS_OP_CL2C : 'SYS_OP_CL2C';
SYS_OP_COMBINED_HASH : 'SYS_OP_COMBINED_HASH';
SYS_OP_COMP : 'SYS_OP_COMP';
SYS_OP_CONVERT : 'SYS_OP_CONVERT';
SYS_OP_COUNTCHG : 'SYS_OP_COUNTCHG';
SYS_OP_CSCONV : 'SYS_OP_CSCONV';
SYS_OP_CSCONVTEST : 'SYS_OP_CSCONVTEST';
SYS_OP_CSR : 'SYS_OP_CSR';
SYS_OP_CSX_PATCH : 'SYS_OP_CSX_PATCH';
SYS_OP_CYCLED_SEQ : 'SYS_OP_CYCLED_SEQ';
SYS_OP_DECOMP : 'SYS_OP_DECOMP';
SYS_OP_DESCEND : 'SYS_OP_DESCEND';
SYS_OP_DISTINCT : 'SYS_OP_DISTINCT';
SYS_OP_DRA : 'SYS_OP_DRA';
SYS_OP_DUMP : 'SYS_OP_DUMP';
SYS_OP_DV_CHECK : 'SYS_OP_DV_CHECK';
SYS_OP_ENFORCE_NOT_NULL : 'SYS_OP_ENFORCE_NOT_NULL$';
SYSOPER : 'SYSOPER';
SYS_OP_EXTRACT : 'SYS_OP_EXTRACT';
SYS_OP_GROUPING : 'SYS_OP_GROUPING';
SYS_OP_GUID : 'SYS_OP_GUID';
SYS_OP_HASH : 'SYS_OP_HASH';
SYS_OP_IIX : 'SYS_OP_IIX';
SYS_OP_ITR : 'SYS_OP_ITR';
SYS_OP_KEY_VECTOR_CREATE : 'SYS_OP_KEY_VECTOR_CREATE';
SYS_OP_KEY_VECTOR_FILTER_LIST : 'SYS_OP_KEY_VECTOR_FILTER_LIST';
SYS_OP_KEY_VECTOR_FILTER : 'SYS_OP_KEY_VECTOR_FILTER';
SYS_OP_KEY_VECTOR_SUCCEEDED : 'SYS_OP_KEY_VECTOR_SUCCEEDED';
SYS_OP_KEY_VECTOR_USE : 'SYS_OP_KEY_VECTOR_USE';
SYS_OP_LBID : 'SYS_OP_LBID';
SYS_OP_LOBLOC2BLOB : 'SYS_OP_LOBLOC2BLOB';
SYS_OP_LOBLOC2CLOB : 'SYS_OP_LOBLOC2CLOB';
SYS_OP_LOBLOC2ID : 'SYS_OP_LOBLOC2ID';
SYS_OP_LOBLOC2NCLOB : 'SYS_OP_LOBLOC2NCLOB';
SYS_OP_LOBLOC2TYP : 'SYS_OP_LOBLOC2TYP';
SYS_OP_LSVI : 'SYS_OP_LSVI';
SYS_OP_LVL : 'SYS_OP_LVL';
SYS_OP_MAKEOID : 'SYS_OP_MAKEOID';
SYS_OP_MAP_NONNULL : 'SYS_OP_MAP_NONNULL';
SYS_OP_MSR : 'SYS_OP_MSR';
SYS_OP_NICOMBINE : 'SYS_OP_NICOMBINE';
SYS_OP_NIEXTRACT : 'SYS_OP_NIEXTRACT';
SYS_OP_NII : 'SYS_OP_NII';
SYS_OP_NIX : 'SYS_OP_NIX';
SYS_OP_NOEXPAND : 'SYS_OP_NOEXPAND';
SYS_OP_NTCIMG : 'SYS_OP_NTCIMG$';
SYS_OP_NUMTORAW : 'SYS_OP_NUMTORAW';
SYS_OP_OIDVALUE : 'SYS_OP_OIDVALUE';
SYS_OP_OPNSIZE : 'SYS_OP_OPNSIZE';
SYS_OP_PAR_1 : 'SYS_OP_PAR_1';
SYS_OP_PARGID_1 : 'SYS_OP_PARGID_1';
SYS_OP_PARGID : 'SYS_OP_PARGID';
SYS_OP_PAR : 'SYS_OP_PAR';
SYS_OP_PART_ID : 'SYS_OP_PART_ID';
SYS_OP_PIVOT : 'SYS_OP_PIVOT';
SYS_OP_R2O : 'SYS_OP_R2O';
SYS_OP_RAWTONUM : 'SYS_OP_RAWTONUM';
SYS_OP_RDTM : 'SYS_OP_RDTM';
SYS_OP_REF : 'SYS_OP_REF';
SYS_OP_RMTD : 'SYS_OP_RMTD';
SYS_OP_ROWIDTOOBJ : 'SYS_OP_ROWIDTOOBJ';
SYS_OP_RPB : 'SYS_OP_RPB';
SYS_OPTLOBPRBSC : 'SYS_OPTLOBPRBSC';
SYS_OP_TOSETID : 'SYS_OP_TOSETID';
SYS_OP_TPR : 'SYS_OP_TPR';
SYS_OP_TRTB : 'SYS_OP_TRTB';
SYS_OPTXICMP : 'SYS_OPTXICMP';
SYS_OPTXQCASTASNQ : 'SYS_OPTXQCASTASNQ';
SYS_OP_UNDESCEND : 'SYS_OP_UNDESCEND';
SYS_OP_VECAND : 'SYS_OP_VECAND';
SYS_OP_VECBIT : 'SYS_OP_VECBIT';
SYS_OP_VECOR : 'SYS_OP_VECOR';
SYS_OP_VECXOR : 'SYS_OP_VECXOR';
SYS_OP_VERSION : 'SYS_OP_VERSION';
SYS_OP_VREF : 'SYS_OP_VREF';
SYS_OP_VVD : 'SYS_OP_VVD';
SYS_OP_XMLCONS_FOR_CSX : 'SYS_OP_XMLCONS_FOR_CSX';
SYS_OP_XPTHATG : 'SYS_OP_XPTHATG';
SYS_OP_XPTHIDX : 'SYS_OP_XPTHIDX';
SYS_OP_XPTHOP : 'SYS_OP_XPTHOP';
SYS_OP_XTXT2SQLT : 'SYS_OP_XTXT2SQLT';
SYS_OP_ZONE_ID : 'SYS_OP_ZONE_ID';
SYS_ORDERKEY_DEPTH : 'SYS_ORDERKEY_DEPTH';
SYS_ORDERKEY_MAXCHILD : 'SYS_ORDERKEY_MAXCHILD';
SYS_ORDERKEY_PARENT : 'SYS_ORDERKEY_PARENT';
SYS_PARALLEL_TXN : 'SYS_PARALLEL_TXN';
SYS_PATHID_IS_ATTR : 'SYS_PATHID_IS_ATTR';
SYS_PATHID_IS_NMSPC : 'SYS_PATHID_IS_NMSPC';
SYS_PATHID_LASTNAME : 'SYS_PATHID_LASTNAME';
SYS_PATHID_LASTNMSPC : 'SYS_PATHID_LASTNMSPC';
SYS_PATH_REVERSE : 'SYS_PATH_REVERSE';
SYS_PXQEXTRACT : 'SYS_PXQEXTRACT';
SYS_RAW_TO_XSID : 'SYS_RAW_TO_XSID';
SYS_RID_ORDER : 'SYS_RID_ORDER';
SYS_ROW_DELTA : 'SYS_ROW_DELTA';
SYS_SC_2_XMLT : 'SYS_SC_2_XMLT';
SYS_SYNRCIREDO : 'SYS_SYNRCIREDO';
SYSTEM_DEFINED : 'SYSTEM_DEFINED';
SYSTEM : 'SYSTEM';
SYSTIMESTAMP : 'SYSTIMESTAMP';
SYS_TYPEID : 'SYS_TYPEID';
SYS_UMAKEXML : 'SYS_UMAKEXML';
SYS_XMLANALYZE : 'SYS_XMLANALYZE';
SYS_XMLCONTAINS : 'SYS_XMLCONTAINS';
SYS_XMLCONV : 'SYS_XMLCONV';
SYS_XMLEXNSURI : 'SYS_XMLEXNSURI';
SYS_XMLGEN : 'SYS_XMLGEN';
SYS_XMLI_LOC_ISNODE : 'SYS_XMLI_LOC_ISNODE';
SYS_XMLI_LOC_ISTEXT : 'SYS_XMLI_LOC_ISTEXT';
SYS_XMLINSTR : 'SYS_XMLINSTR';
SYS_XMLLOCATOR_GETSVAL : 'SYS_XMLLOCATOR_GETSVAL';
SYS_XMLNODEID_GETCID : 'SYS_XMLNODEID_GETCID';
SYS_XMLNODEID_GETLOCATOR : 'SYS_XMLNODEID_GETLOCATOR';
SYS_XMLNODEID_GETOKEY : 'SYS_XMLNODEID_GETOKEY';
SYS_XMLNODEID_GETPATHID : 'SYS_XMLNODEID_GETPATHID';
SYS_XMLNODEID_GETPTRID : 'SYS_XMLNODEID_GETPTRID';
SYS_XMLNODEID_GETRID : 'SYS_XMLNODEID_GETRID';
SYS_XMLNODEID_GETSVAL : 'SYS_XMLNODEID_GETSVAL';
SYS_XMLNODEID_GETTID : 'SYS_XMLNODEID_GETTID';
SYS_XMLNODEID : 'SYS_XMLNODEID';
SYS_XMLT_2_SC : 'SYS_XMLT_2_SC';
SYS_XMLTRANSLATE : 'SYS_XMLTRANSLATE';
SYS_XMLTYPE2SQL : 'SYS_XMLTYPE2SQL';
SYS_XQ_ASQLCNV : 'SYS_XQ_ASQLCNV';
SYS_XQ_ATOMCNVCHK : 'SYS_XQ_ATOMCNVCHK';
SYS_XQBASEURI : 'SYS_XQBASEURI';
SYS_XQCASTABLEERRH : 'SYS_XQCASTABLEERRH';
SYS_XQCODEP2STR : 'SYS_XQCODEP2STR';
SYS_XQCODEPEQ : 'SYS_XQCODEPEQ';
SYS_XQCON2SEQ : 'SYS_XQCON2SEQ';
SYS_XQCONCAT : 'SYS_XQCONCAT';
SYS_XQDELETE : 'SYS_XQDELETE';
SYS_XQDFLTCOLATION : 'SYS_XQDFLTCOLATION';
SYS_XQDOC : 'SYS_XQDOC';
SYS_XQDOCURI : 'SYS_XQDOCURI';
SYS_XQDURDIV : 'SYS_XQDURDIV';
SYS_XQED4URI : 'SYS_XQED4URI';
SYS_XQENDSWITH : 'SYS_XQENDSWITH';
SYS_XQERRH : 'SYS_XQERRH';
SYS_XQERR : 'SYS_XQERR';
SYS_XQESHTMLURI : 'SYS_XQESHTMLURI';
SYS_XQEXLOBVAL : 'SYS_XQEXLOBVAL';
SYS_XQEXSTWRP : 'SYS_XQEXSTWRP';
SYS_XQEXTRACT : 'SYS_XQEXTRACT';
SYS_XQEXTRREF : 'SYS_XQEXTRREF';
SYS_XQEXVAL : 'SYS_XQEXVAL';
SYS_XQFB2STR : 'SYS_XQFB2STR';
SYS_XQFNBOOL : 'SYS_XQFNBOOL';
SYS_XQFNCMP : 'SYS_XQFNCMP';
SYS_XQFNDATIM : 'SYS_XQFNDATIM';
SYS_XQFNLNAME : 'SYS_XQFNLNAME';
SYS_XQFNNM : 'SYS_XQFNNM';
SYS_XQFNNSURI : 'SYS_XQFNNSURI';
SYS_XQFNPREDTRUTH : 'SYS_XQFNPREDTRUTH';
SYS_XQFNQNM : 'SYS_XQFNQNM';
SYS_XQFNROOT : 'SYS_XQFNROOT';
SYS_XQFORMATNUM : 'SYS_XQFORMATNUM';
SYS_XQFTCONTAIN : 'SYS_XQFTCONTAIN';
SYS_XQFUNCR : 'SYS_XQFUNCR';
SYS_XQGETCONTENT : 'SYS_XQGETCONTENT';
SYS_XQINDXOF : 'SYS_XQINDXOF';
SYS_XQINSERT : 'SYS_XQINSERT';
SYS_XQINSPFX : 'SYS_XQINSPFX';
SYS_XQIRI2URI : 'SYS_XQIRI2URI';
SYS_XQLANG : 'SYS_XQLANG';
SYS_XQLLNMFRMQNM : 'SYS_XQLLNMFRMQNM';
SYS_XQMKNODEREF : 'SYS_XQMKNODEREF';
SYS_XQNILLED : 'SYS_XQNILLED';
SYS_XQNODENAME : 'SYS_XQNODENAME';
SYS_XQNORMSPACE : 'SYS_XQNORMSPACE';
SYS_XQNORMUCODE : 'SYS_XQNORMUCODE';
SYS_XQ_NRNG : 'SYS_XQ_NRNG';
SYS_XQNSP4PFX : 'SYS_XQNSP4PFX';
SYS_XQNSPFRMQNM : 'SYS_XQNSPFRMQNM';
SYS_XQPFXFRMQNM : 'SYS_XQPFXFRMQNM';
SYS_XQ_PKSQL2XML : 'SYS_XQ_PKSQL2XML';
SYS_XQPOLYABS : 'SYS_XQPOLYABS';
SYS_XQPOLYADD : 'SYS_XQPOLYADD';
SYS_XQPOLYCEL : 'SYS_XQPOLYCEL';
SYS_XQPOLYCSTBL : 'SYS_XQPOLYCSTBL';
SYS_XQPOLYCST : 'SYS_XQPOLYCST';
SYS_XQPOLYDIV : 'SYS_XQPOLYDIV';
SYS_XQPOLYFLR : 'SYS_XQPOLYFLR';
SYS_XQPOLYMOD : 'SYS_XQPOLYMOD';
SYS_XQPOLYMUL : 'SYS_XQPOLYMUL';
SYS_XQPOLYRND : 'SYS_XQPOLYRND';
SYS_XQPOLYSQRT : 'SYS_XQPOLYSQRT';
SYS_XQPOLYSUB : 'SYS_XQPOLYSUB';
SYS_XQPOLYUMUS : 'SYS_XQPOLYUMUS';
SYS_XQPOLYUPLS : 'SYS_XQPOLYUPLS';
SYS_XQPOLYVEQ : 'SYS_XQPOLYVEQ';
SYS_XQPOLYVGE : 'SYS_XQPOLYVGE';
SYS_XQPOLYVGT : 'SYS_XQPOLYVGT';
SYS_XQPOLYVLE : 'SYS_XQPOLYVLE';
SYS_XQPOLYVLT : 'SYS_XQPOLYVLT';
SYS_XQPOLYVNE : 'SYS_XQPOLYVNE';
SYS_XQREF2VAL : 'SYS_XQREF2VAL';
SYS_XQRENAME : 'SYS_XQRENAME';
SYS_XQREPLACE : 'SYS_XQREPLACE';
SYS_XQRESVURI : 'SYS_XQRESVURI';
SYS_XQRNDHALF2EVN : 'SYS_XQRNDHALF2EVN';
SYS_XQRSLVQNM : 'SYS_XQRSLVQNM';
SYS_XQRYENVPGET : 'SYS_XQRYENVPGET';
SYS_XQRYVARGET : 'SYS_XQRYVARGET';
SYS_XQRYWRP : 'SYS_XQRYWRP';
SYS_XQSEQ2CON4XC : 'SYS_XQSEQ2CON4XC';
SYS_XQSEQ2CON : 'SYS_XQSEQ2CON';
SYS_XQSEQDEEPEQ : 'SYS_XQSEQDEEPEQ';
SYS_XQSEQINSB : 'SYS_XQSEQINSB';
SYS_XQSEQRM : 'SYS_XQSEQRM';
SYS_XQSEQRVS : 'SYS_XQSEQRVS';
SYS_XQSEQSUB : 'SYS_XQSEQSUB';
SYS_XQSEQTYPMATCH : 'SYS_XQSEQTYPMATCH';
SYS_XQSTARTSWITH : 'SYS_XQSTARTSWITH';
SYS_XQSTATBURI : 'SYS_XQSTATBURI';
SYS_XQSTR2CODEP : 'SYS_XQSTR2CODEP';
SYS_XQSTRJOIN : 'SYS_XQSTRJOIN';
SYS_XQSUBSTRAFT : 'SYS_XQSUBSTRAFT';
SYS_XQSUBSTRBEF : 'SYS_XQSUBSTRBEF';
SYS_XQTOKENIZE : 'SYS_XQTOKENIZE';
SYS_XQTREATAS : 'SYS_XQTREATAS';
SYS_XQ_UPKXML2SQL : 'SYS_XQ_UPKXML2SQL';
SYS_XQXFORM : 'SYS_XQXFORM';
SYS_XSID_TO_RAW : 'SYS_XSID_TO_RAW';
SYS_ZMAP_FILTER : 'SYS_ZMAP_FILTER';
SYS_ZMAP_REFRESH : 'SYS_ZMAP_REFRESH';
T_LETTER : 'T';
TABLE_LOOKUP_BY_NL : 'TABLE_LOOKUP_BY_NL';
TABLESPACE_NO : 'TABLESPACE_NO';
TABLESPACE : 'TABLESPACE';
TABLES : 'TABLES';
TABLE_STATS : 'TABLE_STATS';
TABLE : 'TABLE';
TABNO : 'TABNO';
TAG : 'TAG';
TANH : 'TANH';
TAN : 'TAN';
TBLORIDXPARTNUM : 'TBL$OR$IDX$PART$NUM';
TEMPFILE : 'TEMPFILE';
TEMPLATE : 'TEMPLATE';
TEMPLATE_TABLE : 'TEMPLATE_TABLE';
TEMPORARY : 'TEMPORARY';
TEMP_TABLE : 'TEMP_TABLE';
TERMINATED : 'TERMINATED';
TEST : 'TEST';
TEXT : 'TEXT';
TEXTFILE : 'TEXTFILE';
THAN : 'THAN';
THEN : 'THEN';
THE : 'THE';
THESE : 'THESE';
THREAD : 'THREAD';
THROUGH : 'THROUGH';
TIER : 'TIER';
TIES : 'TIES';
TIMEOUT : 'TIMEOUT';
TIMESTAMP_LTZ_UNCONSTRAINED : 'TIMESTAMP_LTZ_UNCONSTRAINED';
TIMESTAMP : 'TIMESTAMP';
TIMESTAMP_TZ_UNCONSTRAINED : 'TIMESTAMP_TZ_UNCONSTRAINED';
TIMESTAMP_UNCONSTRAINED : 'TIMESTAMP_UNCONSTRAINED';
TIMES : 'TIMES';
TIME : 'TIME';
TIMEZONE : 'TIMEZONE';
TIMEZONE_ABBR : 'TIMEZONE_ABBR';
TIMEZONE_HOUR : 'TIMEZONE_HOUR';
TIMEZONE_MINUTE : 'TIMEZONE_MINUTE';
TIMEZONE_OFFSET : 'TIMEZONE_OFFSET';
TIMEZONE_REGION : 'TIMEZONE_REGION';
TIME_ZONE : 'TIME_ZONE';
TIMING : 'TIMING';
TINYINT : 'TINYINT';
TIV_GB : 'TIV_GB';
TIV_SSF : 'TIV_SSF';
TO_ACLID : 'TO_ACLID';
TO_BINARY_DOUBLE : 'TO_BINARY_DOUBLE';
TO_BINARY_FLOAT : 'TO_BINARY_FLOAT';
TO_BLOB : 'TO_BLOB';
TO_CLOB : 'TO_CLOB';
TO_DSINTERVAL : 'TO_DSINTERVAL';
TO_LOB : 'TO_LOB';
TO_MULTI_BYTE : 'TO_MULTI_BYTE';
TO_NCHAR : 'TO_NCHAR';
TO_NCLOB : 'TO_NCLOB';
TO_NUMBER : 'TO_NUMBER';
TOPLEVEL : 'TOPLEVEL';
TO_SINGLE_BYTE : 'TO_SINGLE_BYTE';
TO_TIMESTAMP : 'TO_TIMESTAMP';
TO_TIMESTAMP_TZ : 'TO_TIMESTAMP_TZ';
TO_TIME : 'TO_TIME';
TO_TIME_TZ : 'TO_TIME_TZ';
TO : 'TO';
TO_YMINTERVAL : 'TO_YMINTERVAL';
TRACE : 'TRACE';
TRACING : 'TRACING';
TRACKING : 'TRACKING';
TRAILING : 'TRAILING';
TRANSACTION : 'TRANSACTION';
TRANSFORM : 'TRANSFORM';
TRANSFORMS : 'TRANSFORMS';
TRANSFORM_DISTINCT_AGG : 'TRANSFORM_DISTINCT_AGG';
TRANSITIONAL : 'TRANSITIONAL';
TRANSITION : 'TRANSITION';
TRANSLATE : 'TRANSLATE';
TRANSLATION : 'TRANSLATION';
TREAT : 'TREAT';
TRIGGERS : 'TRIGGERS';
TRIGGER : 'TRIGGER';
TRUE : 'TRUE';
TRUNCATE : 'TRUNCATE';
TRUNC : 'TRUNC';
TRUSTED : 'TRUSTED';
TRUST : 'TRUST';
TUNING : 'TUNING';
TX : 'TX';
TYPES : 'TYPES';
TYPE : 'TYPE';
TZ_OFFSET : 'TZ_OFFSET';
UB2 : 'UB2';
UBA : 'UBA';
UCS2 : 'UCS2';
UDF : 'UDF';
UID : 'UID';
UNARCHIVED : 'UNARCHIVED';
UNBOUNDED : 'UNBOUNDED';
UNBOUND : 'UNBOUND';
UNCONDITIONAL : 'UNCONDITIONAL';
UNDER : 'UNDER';
UNDO : 'UNDO';
UNDROP : 'UNDROP';
UNIFORM : 'UNIFORM';
UNION : 'UNION';
UNIONTYPE : 'UNIONTYPE';
UNIQUE : 'UNIQUE';
UNISTR : 'UNISTR';
UNLIMITED : 'UNLIMITED';
UNLOAD : 'UNLOAD';
UNLOCK : 'UNLOCK';
UNMATCHED : 'UNMATCHED';
UNNEST_INNERJ_DISTINCT_VIEW : 'UNNEST_INNERJ_DISTINCT_VIEW';
UNNEST_NOSEMIJ_NODISTINCTVIEW : 'UNNEST_NOSEMIJ_NODISTINCTVIEW';
UNNEST_SEMIJ_VIEW : 'UNNEST_SEMIJ_VIEW';
UNNEST : 'UNNEST';
UNPACKED : 'UNPACKED';
UNPIVOT : 'UNPIVOT';
UNPLUG : 'UNPLUG';
UNPROTECTED : 'UNPROTECTED';
UNQUIESCE : 'UNQUIESCE';
UNRECOVERABLE : 'UNRECOVERABLE';
UNRESTRICTED : 'UNRESTRICTED';
UNSIGNED : 'UNSIGNED';
UNSUBSCRIBE : 'UNSUBSCRIBE';
UNTIL : 'UNTIL';
UNUSABLE : 'UNUSABLE';
UNUSED : 'UNUSED';
UPDATABLE : 'UPDATABLE';
UPDATED : 'UPDATED';
UPDATE : 'UPDATE';
UPDATEXML : 'UPDATEXML';
UPD_INDEXES : 'UPD_INDEXES';
UPD_JOININDEX : 'UPD_JOININDEX';
UPGRADE : 'UPGRADE';
UPPER : 'UPPER';
UPSERT : 'UPSERT';
UROWID : 'UROWID';
USABLE : 'USABLE';
USAGE : 'USAGE';
USE_ANTI : 'USE_ANTI';
USE_CONCAT : 'USE_CONCAT';
USE_CUBE : 'USE_CUBE';
USE_HASH_AGGREGATION : 'USE_HASH_AGGREGATION';
USE_HASH_GBY_FOR_PUSHDOWN : 'USE_HASH_GBY_FOR_PUSHDOWN';
USE_HASH : 'USE_HASH';
USE_HIDDEN_PARTITIONS : 'USE_HIDDEN_PARTITIONS';
USE_INVISIBLE_INDEXES : 'USE_INVISIBLE_INDEXES';
USE_MERGE_CARTESIAN : 'USE_MERGE_CARTESIAN';
USE_MERGE : 'USE_MERGE';
USE_NL : 'USE_NL';
USE_NL_WITH_INDEX : 'USE_NL_WITH_INDEX';
USE_PRIVATE_OUTLINES : 'USE_PRIVATE_OUTLINES';
USER_DATA : 'USER_DATA';
USER_DEFINED : 'USER_DEFINED';
USERENV : 'USERENV';
USERGROUP : 'USERGROUP';
USER_RECYCLEBIN : 'USER_RECYCLEBIN';
USERS : 'USERS';
USER_TABLESPACES : 'USER_TABLESPACES';
USER : 'USER';
USE_SEMI : 'USE_SEMI';
USE_STORED_OUTLINES : 'USE_STORED_OUTLINES';
USE_TTT_FOR_GSETS : 'USE_TTT_FOR_GSETS';
USE : 'USE';
USE_VECTOR_AGGREGATION : 'USE_VECTOR_AGGREGATION';
USE_WEAK_NAME_RESL : 'USE_WEAK_NAME_RESL';
USING_NO_EXPAND : 'USING_NO_EXPAND';
USING_NLS_COMP : 'USING_NLS_COMP';
USING : 'USING';
UTF16BE : 'UTF16BE';
UTF16LE : 'UTF16LE';
UTF32 : 'UTF32';
UTF8 : 'UTF8';
V1 : 'V1';
V2 : 'V2';
VALIDATE : 'VALIDATE';
VALIDATE_CONVERSION : 'VALIDATE_CONVERSION';
VALIDATION : 'VALIDATION';
VALID_TIME_END : 'VALID_TIME_END';
VALUES : 'VALUES';
VALUE : 'VALUE';
VARCHAR2 : 'VARCHAR2';
VARCHAR : 'VARCHAR';
VARCHARC : 'VARCHARC';
VARIABLE : 'VARIABLE';
VARRAW : 'VARRAW';
VARRAWC : 'VARRAWC';
VAR_POP : 'VAR_POP';
VARRAYS : 'VARRAYS';
VARRAY : 'VARRAY';
VAR_SAMP : 'VAR_SAMP';
VARYING : 'VARYING';
VECTOR_READ_TRACE : 'VECTOR_READ_TRACE';
VECTOR_READ : 'VECTOR_READ';
VECTOR_TRANSFORM_DIMS : 'VECTOR_TRANSFORM_DIMS';
VECTOR_TRANSFORM_FACT : 'VECTOR_TRANSFORM_FACT';
VECTOR_TRANSFORM : 'VECTOR_TRANSFORM';
VERIFIER : 'VERIFIER';
VERIFY : 'VERIFY';
VERSIONING : 'VERSIONING';
VERSIONS_ENDSCN : 'VERSIONS_ENDSCN';
VERSIONS_ENDTIME : 'VERSIONS_ENDTIME';
VERSIONS_OPERATION : 'VERSIONS_OPERATION';
VERSIONS_STARTSCN : 'VERSIONS_STARTSCN';
VERSIONS_STARTTIME : 'VERSIONS_STARTTIME';
VERSIONS : 'VERSIONS';
VERSIONS_XID : 'VERSIONS_XID';
VERSION : 'VERSION';
VIEW : 'VIEW';
VIOLATION : 'VIOLATION';
VIRTUAL : 'VIRTUAL';
VISIBILITY : 'VISIBILITY';
VISIBLE : 'VISIBLE';
VOLUME : 'VOLUME';
VSIZE : 'VSIZE';
WAIT : 'WAIT';
WALLET : 'WALLET';
WARNING : 'WARNING';
WEEKS : 'WEEKS';
WEEK : 'WEEK';
WELLFORMED : 'WELLFORMED';
WHENEVER : 'WHENEVER';
WHEN : 'WHEN';
WHERE : 'WHERE';
WHILE : 'WHILE';
WHITESPACE : 'WHITESPACE';
WIDTH_BUCKET : 'WIDTH_BUCKET';
WITHIN : 'WITHIN';
WITHOUT : 'WITHOUT';
WITH_PLSQL : 'WITH_PLSQL';
WITH : 'WITH';
WORK : 'WORK';
WORKERID : 'WORKERID';
WRAPPED : 'WRAPPED';
WRAPPER : 'WRAPPER';
WRITE : 'WRITE';
XDB_FASTPATH_INSERT : 'XDB_FASTPATH_INSERT';
XDB : 'XDB';
X_DYN_PRUNE : 'X_DYN_PRUNE';
XID : 'XID';
XML2OBJECT : 'XML2OBJECT';
XMLAGG : 'XMLAGG';
XMLATTRIBUTES : 'XMLATTRIBUTES';
XMLCAST : 'XMLCAST';
XMLCDATA : 'XMLCDATA';
XMLCOLATTVAL : 'XMLCOLATTVAL';
XMLCOMMENT : 'XMLCOMMENT';
XMLCONCAT : 'XMLCONCAT';
XMLDIFF : 'XMLDIFF';
XML_DML_RWT_STMT : 'XML_DML_RWT_STMT';
XMLELEMENT : 'XMLELEMENT';
XMLEXISTS2 : 'XMLEXISTS2';
XMLEXISTS : 'XMLEXISTS';
XMLFOREST : 'XMLFOREST';
XMLINDEX : 'XMLINDEX';
XMLINDEX_REWRITE_IN_SELECT : 'XMLINDEX_REWRITE_IN_SELECT';
XMLINDEX_REWRITE : 'XMLINDEX_REWRITE';
XMLINDEX_SEL_IDX_TBL : 'XMLINDEX_SEL_IDX_TBL';
XMLISNODE : 'XMLISNODE';
XMLISVALID : 'XMLISVALID';
XMLNAMESPACES : 'XMLNAMESPACES';
XMLPARSE : 'XMLPARSE';
XMLPATCH : 'XMLPATCH';
XMLPI : 'XMLPI';
XMLQUERYVAL : 'XMLQUERYVAL';
XMLQUERY : 'XMLQUERY';
XMLROOT : 'XMLROOT';
XMLSCHEMA : 'XMLSCHEMA';
XMLSERIALIZE : 'XMLSERIALIZE';
XMLTABLE : 'XMLTABLE';
XMLTAG : 'XMLTAG';
XMLTRANSFORMBLOB : 'XMLTRANSFORMBLOB';
XMLTRANSFORM : 'XMLTRANSFORM';
XMLTYPE : 'XMLTYPE';
XML : 'XML';
XPATHTABLE : 'XPATHTABLE';
XS_SYS_CONTEXT : 'XS_SYS_CONTEXT';
XS : 'XS';
XTRANSPORT : 'XTRANSPORT';
YEARS : 'YEARS';
YEAR : 'YEAR';
YEAR_TO_MONTH : 'YEAR_TO_MONTH';
YES : 'YES';
YMINTERVAL_UNCONSTRAINED : 'YMINTERVAL_UNCONSTRAINED';
ZONEMAP : 'ZONEMAP';
ZONE : 'ZONE';
ZONED : 'ZONED';
PREDICTION : 'PREDICTION';
PREDICTION_BOUNDS : 'PREDICTION_BOUNDS';
PREDICTION_COST : 'PREDICTION_COST';
PREDICTION_DETAILS : 'PREDICTION_DETAILS';
PREDICTION_PROBABILITY : 'PREDICTION_PROBABILITY';
PREDICTION_SET : 'PREDICTION_SET';
BLOCKCHAIN : 'BLOCKCHAIN';
COLLATE : 'COLLATE';
COLLATION : 'COLLATION';
DEFINITION : 'DEFINITION';
DUPLICATED : 'DUPLICATED';
EXTENDED : 'EXTENDED';
HASHING : 'HASHING';
IDLE : 'IDLE';
IMMUTABLE : 'IMMUTABLE';
ORACLE_DATAPUMP : 'ORACLE_DATAPUMP';
ORACLE_HDFS : 'ORACLE_HDFS';
ORACLE_HIVE : 'ORACLE_HIVE';
ORACLE_LOADER : 'ORACLE_LOADER';
SHA2_512_Q : '"SHA2_512"';
SHARDED : 'SHARDED';
V1_Q : '"V1"';
ISOLATE : 'ISOLATE';
ROOT : 'ROOT';
UNITE : 'UNITE';
ALGORITHM : 'ALGORITHM';
CUME_DIST : 'CUME_DIST';
DENSE_RANK : 'DENSE_RANK';
LISTAGG : 'LISTAGG';
PERCENT_RANK : 'PERCENT_RANK';
PERCENTILE_CONT : 'PERCENTILE_CONT';
PERCENTILE_DISC : 'PERCENTILE_DISC';
RANK : 'RANK';
AVG : 'AVG';
CORR : 'CORR';
COVAR_ : 'COVAR_';
DECODE : 'DECODE';
LAG : 'LAG';
LAG_DIFF : 'LAG_DIFF';
LAG_DIFF_PERCENT : 'LAG_DIFF_PERCENT';
LEAD : 'LEAD';
MAX : 'MAX';
MEDIAN : 'MEDIAN';
MEMOPTIMIZE : 'MEMOPTIMIZE';
MIN : 'MIN';
NTILE : 'NTILE';
NVL : 'NVL';
RATIO_TO_REPORT : 'RATIO_TO_REPORT';
REGR_ : 'REGR_';
ROUND : 'ROUND';
ROW_NUMBER : 'ROW_NUMBER';
SUBSTR : 'SUBSTR';
TO_CHAR : 'TO_CHAR';
TRIM : 'TRIM';
SUM : 'SUM';
STDDEV : 'STDDEV';
VAR_ : 'VAR_';
VARIANCE : 'VARIANCE';
LEAST : 'LEAST';
GREATEST : 'GREATEST';
TO_DATE : 'TO_DATE';
CHARSETID : 'CHARSETID';
CHARSETFORM : 'CHARSETFORM';
DURATION : 'DURATION';
EXTEND : 'EXTEND';
MAXLEN : 'MAXLEN';
PERSISTABLE : 'PERSISTABLE';
POLYMORPHIC : 'POLYMORPHIC';
STRUCT : 'STRUCT';
TDO : 'TDO';
WM_CONCAT : 'WM_CONCAT';
// Rule #358 - subtoken typecast in , it also incorporates
// Lowercase 'n' is a usual addition to the standard
NATIONAL_CHAR_STRING_LIT: 'N' '\'' (~('\'' | '\r' | '\n') | '\'' '\'' | NEWLINE)* '\'';
// Rule #040 - subtoken typecast in
// Lowercase 'b' is a usual addition to the standard
BIT_STRING_LIT: 'B' ('\'' [01]* '\'')+;
// Rule #284 - subtoken typecast in
// Lowercase 'x' is a usual addition to the standard
// The '0X' is used in external_table_clause sub-rules
HEX_STRING_LIT : ('X' | '0X') ('\'' [A-F0-9]* '\'')+;
DOUBLE_PERIOD : '..';
PERIOD : '.';
//{ Rule #238
// This rule is a bit tricky - it resolves the ambiguity with
// It also incorporates and for the
// Rule #501 was incorporated directly in the token
// See also the rule #617
/*
: (
UNSIGNED_INTEGER
( '.' UNSIGNED_INTEGER
| {$type = UNSIGNED_INTEGER;}
) ( E ('+' | '-')? UNSIGNED_INTEGER {$type = APPROXIMATE_NUM_LIT;} )?
| '.' UNSIGNED_INTEGER ( E ('+' | '-')? UNSIGNED_INTEGER {$type = APPROXIMATE_NUM_LIT;} )?
)
(D | F)?
;*/
UNSIGNED_INTEGER : [0-9]+;
APPROXIMATE_NUM_LIT : FLOAT_FRAGMENT ('E' ('+' | '-')? (FLOAT_FRAGMENT | [0-9]+))? ('D' | 'F')?;
// Rule #--- is a base for Rule #065 , it incorporates
// and a superfluous subtoken typecasting of the "QUOTE"
CHAR_STRING: '\'' (~('\'' | '\r' | '\n') | '\'' '\'' | NEWLINE)* '\'';
// See https://livesql.oracle.com/apex/livesql/file/content_CIREYU9EA54EOKQ7LAMZKRF6P.html
// TODO: context sensitive string quotes (any characted after quote)
CHAR_STRING_PERL:
'Q' '\'' (
QS_ANGLE
| QS_BRACE
| QS_BRACK
| QS_PAREN
| QS_EXCLAM
| QS_SHARP
| QS_QUOTE
| QS_DQUOTE
| QS_TILDA
| QS_SOLIDUS
| QS_RSOLIDUS
) '\'' -> type(CHAR_STRING)
;
fragment QS_ANGLE : '<' .*? '>';
fragment QS_BRACE : '{' .*? '}';
fragment QS_BRACK : '[' .*? ']';
fragment QS_PAREN : '(' .*? ')';
fragment QS_EXCLAM : '!' .*? '!';
fragment QS_SHARP : '#' .*? '#';
fragment QS_QUOTE : '\'' .*? '\'';
fragment QS_DQUOTE : '"' .*? '"';
fragment QS_TILDA : '~' .*? '~';
fragment QS_SOLIDUS : '/' .*? '/';
fragment QS_RSOLIDUS : '\\' .*? '\\';
DELIMITED_ID: '"' (~ [\u0000"] | '"' '"')+ '"';
PERCENT : '%';
AMPERSAND : '&';
LEFT_PAREN : '(';
RIGHT_PAREN : ')';
DOUBLE_ASTERISK : '**';
ASTERISK : '*';
PLUS_SIGN : '+';
MINUS_SIGN : '-';
COMMA : ',';
SOLIDUS : '/';
AT_SIGN : '@';
ASSIGN_OP : ':=';
HASH_OP : '#';
LEFT_CURLY_PAREN : '{';
RIGHT_CURLY_PAREN : '}';
SQ: '\'';
BINDVAR:
':' SIMPLE_LETTER (SIMPLE_LETTER | [0-9] | '_')*
| ':' DELIMITED_ID // not used in SQL but spotted in v$sqltext when using cursor_sharing
| ':' UNSIGNED_INTEGER
| QUESTION_MARK // not in SQL, not in Oracle, not in OCI, use this for JDBC
;
NOT_EQUAL_OP : '!=' | '<>' | '^=' | '~=';
CARRET_OPERATOR_PART : '^';
TILDE_OPERATOR_PART : '~';
EXCLAMATION_OPERATOR_PART : '!';
GREATER_THAN_OP : '>';
LESS_THAN_OP : '<';
COLON : ':';
SEMICOLON : ';';
BAR : '|';
EQUALS_OP : '=';
LEFT_BRACKET : '[';
RIGHT_BRACKET : ']';
INTRODUCER: '_';
// Comments https://docs.oracle.com/cd/E11882_01/server.112/e41084/sql_elements006.htm
SINGLE_LINE_COMMENT : '--' ~('\r' | '\n')* NEWLINE_EOF -> channel(HIDDEN);
MULTI_LINE_COMMENT : '/*' .*? '*/' -> channel(HIDDEN);
// https://docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve034.htm#SQPUG054
REMARK_COMMENT:
'REM' {this.IsNewlineAtPos(-4)}? 'ARK'? (' ' ~('\r' | '\n')*)? NEWLINE_EOF -> channel(HIDDEN)
;
// https://docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve032.htm#SQPUG052
PROMPT_MESSAGE: 'PRO' {this.IsNewlineAtPos(-4)}? 'MPT'? (' ' ~('\r' | '\n')*)? NEWLINE_EOF;
// TODO: should starts with newline
START_CMD: // https://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12002.htm
'@' '@'?
; // https://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12003.htm
REGULAR_ID: SIMPLE_LETTER (SIMPLE_LETTER | '$' | '_' | '#' | [0-9])*;
INQUIRY_DIRECTIVE: '$$' (SIMPLE_LETTER | '_')+;
SPACES: [ \t\r\n]+ -> channel(HIDDEN);
// Fragment rules
fragment NEWLINE_EOF : NEWLINE | EOF;
fragment QUESTION_MARK : '?';
fragment SIMPLE_LETTER : [\p{Letter}];
fragment FLOAT_FRAGMENT : UNSIGNED_INTEGER* '.'? UNSIGNED_INTEGER+;
fragment NEWLINE : '\r'? '\n';
fragment SPACE : [ \t];
================================================
FILE: superior-oracle-parser/src/main/antlr4/io/github/melin/superior/parser/oracle/antlr4/OracleParser.g4
================================================
/**
* Oracle(c) PL/SQL 11g Parser
*
* Copyright (c) 2009-2011 Alexandre Porcelli
* Copyright (c) 2015-2019 Ivan Kochurkin (KvanTTT, kvanttt@gmail.com, Positive Technologies).
* Copyright (c) 2017-2018 Mark Adams
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
parser grammar OracleParser;
options {
tokenVocab=OracleLexer;
superClass=OracleParserBase;
}
sql_script
: (sql_plus_command SEMICOLON?)* (
(sql_plus_command | unit_statement) (SEMICOLON '/'? (sql_plus_command | unit_statement))* SEMICOLON? '/'?
) EOF
;
unit_statement
: alter_analytic_view
| alter_attribute_dimension
| alter_audit_policy
| alter_cluster
| alter_database
| alter_database_link
| alter_dimension
| alter_diskgroup
| alter_flashback_archive
| alter_function
| alter_hierarchy
| alter_index
| alter_inmemory_join_group
| alter_java
| alter_library
| alter_lockdown_profile
| alter_materialized_view
| alter_materialized_view_log
| alter_materialized_zonemap
| alter_operator
| alter_outline
| alter_package
| alter_pmem_filestore
| alter_procedure
| alter_resource_cost
| alter_role
| alter_rollback_segment
| alter_sequence
| alter_session
| alter_synonym
| alter_table
| alter_tablespace
| alter_tablespace_set
| alter_trigger
| alter_type
| alter_user
| alter_view
| anonymous_block
| call_statement
| create_analytic_view
| create_attribute_dimension
| create_audit_policy
| create_cluster
| create_context
| create_controlfile
| create_schema
| create_database
| create_database_link
| create_dimension
| create_directory
| create_diskgroup
| create_edition
| create_flashback_archive
| create_function_body
| create_hierarchy
| create_index
| create_inmemory_join_group
| create_java
| create_library
| create_lockdown_profile
| create_materialized_view
| create_materialized_view_log
| create_materialized_zonemap
| create_operator
| create_outline
| create_package
| create_package_body
| create_pmem_filestore
| create_procedure_body
| create_profile
| create_restore_point
| create_role
| create_rollback_segment
| create_sequence
| create_spfile
| create_synonym
| create_table
| create_tablespace
| create_tablespace_set
| create_trigger
| create_type
| create_user
| create_view
| drop_analytic_view
| drop_attribute_dimension
| drop_audit_policy
| drop_cluster
| drop_context
| drop_database
| drop_database_link
| drop_directory
| drop_diskgroup
| drop_edition
| drop_flashback_archive
| drop_function
| drop_hierarchy
| drop_index
| drop_indextype
| drop_inmemory_join_group
| drop_java
| drop_library
| drop_lockdown_profile
| drop_materialized_view
| drop_materialized_view_log
| drop_materialized_zonemap
| drop_operator
| drop_outline
| drop_package
| drop_pmem_filestore
| drop_procedure
| drop_restore_point
| drop_role
| drop_rollback_segment
| drop_sequence
| drop_synonym
| drop_table
| drop_tablespace
| drop_tablespace_set
| drop_trigger
| drop_type
| drop_user
| drop_view
| administer_key_management
| analyze
| associate_statistics
| audit_traditional
| comment_on_column
| comment_on_materialized
| comment_on_table
| data_manipulation_language_statements
| disassociate_statistics
| flashback_table
| grant_statement
| noaudit_statement
| purge_statement
| rename_object
| revoke_statement
| transaction_control_statements
| truncate_cluster
| truncate_table
| unified_auditing
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-DISKGROUP.html
alter_diskgroup
: ALTER DISKGROUP (
id_expression (
((add_disk_clause | drop_disk_clause)+ | resize_disk_clause) rebalance_diskgroup_clause?
| (
replace_disk_clause
| rename_disk_clause
| disk_online_clause
| disk_offline_clause
| rebalance_diskgroup_clause
| check_diskgroup_clause
| diskgroup_template_clauses
| diskgroup_directory_clauses
| diskgroup_alias_clauses
| diskgroup_volume_clauses
| diskgroup_attributes
| drop_diskgroup_file_clause
| convert_redundancy_clause
| usergroup_clauses
| user_clauses
| file_permissions_clause
| file_owner_clause
| scrub_clause
| quotagroup_clauses
| filegroup_clauses
)
)
| (id_expression (',' id_expression)* | ALL) (
undrop_disk_clause
| diskgroup_availability
| enable_disable_volume
)
)
;
add_disk_clause
: ADD (
(SITE sn = id_expression)? quorum_regular? (FAILGROUP fgn = id_expression)? DISK qualified_disk_clause (
',' qualified_disk_clause
)*
)+
;
drop_disk_clause
: DROP (
quorum_regular? DISK id_expression force_noforce? (',' id_expression force_noforce?)*
| DISKS IN quorum_regular? FAILGROUP id_expression force_noforce? (
',' id_expression force_noforce?
)*
)
;
resize_disk_clause
: RESIZE ALL (SIZE size_clause)?
;
replace_disk_clause
: REPLACE DISK id_expression WITH CHAR_STRING force_noforce? (
',' id_expression WITH CHAR_STRING force_noforce?
)* (POWER numeric)? wait_nowait?
;
wait_nowait
: WAIT
| NOWAIT
;
rename_disk_clause
: RENAME (
DISK id_expression TO id_expression (',' id_expression TO id_expression)*
| DISKS ALL
)
;
disk_online_clause
: ONLINE (
(
quorum_regular? DISK id_expression (',' id_expression)*
| DISKS IN quorum_regular? FAILGROUP id_expression (',' id_expression)*
)+
| ALL
) (POWER numeric)? wait_nowait?
;
disk_offline_clause
: OFFLINE (
quorum_regular? DISK id_expression (',' id_expression)*
| DISKS IN quorum_regular? FAILGROUP id_expression (',' id_expression)*
) timeout_clause?
;
timeout_clause
: DROP AFTER numeric (M_LETTER | H_LETTER)
;
rebalance_diskgroup_clause
: REBALANCE (
((WITH | WITHOUT) phase+)? (POWER numeric) (WAIT | NOWAIT)?
| MODIFY POWER numeric?
)
;
phase
: id_expression //TODO
;
check_diskgroup_clause
: CHECK ALL? (REPAIR | NOREPAIR)? //inconsistent documentation
;
diskgroup_template_clauses
: (ADD | MODIFY) TEMPLATE id_expression qualified_template_clause (
',' id_expression qualified_template_clause
)*
| DROP TEMPLATE id_expression (',' id_expression)*
;
qualified_template_clause
: ATTRIBUTES '(' redundancy_clause? striping_clause? ')' //inconsistent documentation
;
redundancy_clause
: MIRROR
| HIGH
| UNPROTECTED
| PARITY
| DOUBLE
;
striping_clause
: FINE
| COARSE
;
force_noforce
: FORCE
| NOFORCE
;
diskgroup_directory_clauses
: ADD DIRECTORY filename (',' filename)*
| DROP DIRECTORY filename force_noforce? (',' filename force_noforce?)*
| RENAME DIRECTORY dir_name TO dir_name (',' dir_name TO dir_name)*
;
dir_name
: CHAR_STRING
;
diskgroup_alias_clauses
: ADD ALIAS CHAR_STRING FOR CHAR_STRING (',' CHAR_STRING FOR CHAR_STRING)*
| DROP ALIAS CHAR_STRING (',' CHAR_STRING)*
| RENAME ALIAS CHAR_STRING TO CHAR_STRING (',' CHAR_STRING TO CHAR_STRING)*
;
diskgroup_volume_clauses
: add_volume_clause
| modify_volume_clause
| RESIZE VOLUME id_expression SIZE size_clause
| DROP VOLUME id_expression
;
add_volume_clause
: ADD VOLUME id_expression SIZE size_clause redundancy_clause? (
STRIPE_WIDTH numeric (K_LETTER | M_LETTER)
)? (STRIPE_COLUMNS numeric)?
;
modify_volume_clause
: MODIFY VOLUME id_expression (MOUNTPATH CHAR_STRING)? (USAGE CHAR_STRING)?
;
diskgroup_attributes
: SET ATTRIBUTE CHAR_STRING '=' CHAR_STRING
;
drop_diskgroup_file_clause
: DROP FILE filename (',' filename)*
;
convert_redundancy_clause
: CONVERT REDUNDANCY TO FLEX
;
usergroup_clauses
: ADD USERGROUP CHAR_STRING WITH MEMBER CHAR_STRING (',' CHAR_STRING)*
| MODIFY USERGROUP CHAR_STRING (ADD | DROP) MEMBER CHAR_STRING (',' CHAR_STRING)*
| DROP USERGROUP CHAR_STRING
;
user_clauses
: ADD USER CHAR_STRING (',' CHAR_STRING)*
| DROP USER CHAR_STRING (',' CHAR_STRING)* CASCADE?
| REPLACE USER CHAR_STRING WITH CHAR_STRING (',' CHAR_STRING WITH CHAR_STRING)*
;
file_permissions_clause
: SET PERMISSION (OWNER | GROUP | OTHER) '=' (NONE | READ (ONLY | WRITE)) (
',' (OWNER | GROUP | OTHER) '=' (NONE | READ (ONLY | WRITE))
)* FOR FILE CHAR_STRING (',' CHAR_STRING)*
;
file_owner_clause
: SET OWNERSHIP (OWNER | GROUP) '=' CHAR_STRING (',' (OWNER | GROUP) '=' CHAR_STRING)* FOR FILE CHAR_STRING (
',' CHAR_STRING
)*
;
scrub_clause
: SCRUB (FILE CHAR_STRING | DISK id_expression)? (REPAIR | NOREPAIR)? (
POWER (AUTO | LOW | HIGH | MAX)
)? wait_nowait? force_noforce? STOP?
;
quotagroup_clauses
: ADD QUOTAGROUP id_expression (SET property_name '=' property_value)?
| MODIFY QUOTAGROUP id_expression SET property_name '=' property_value
| MOVE QUOTAGROUP id_expression TO id_expression
| DROP QUOTAGROUP id_expression
;
property_name
: id_expression
;
property_value
: id_expression
;
filegroup_clauses
: add_filegroup_clause
| modify_filegroup_clause
| move_to_filegroup_clause
| drop_filegroup_clause
;
add_filegroup_clause
: ADD FILEGROUP id_expression ((DATABASE | CLUSTER | VOLUME) id_expression | TEMPLATE) (
FROM TEMPLATE id_expression
)? (SET CHAR_STRING '=' CHAR_STRING)?
;
modify_filegroup_clause
: MODIFY FILEGROUP id_expression SET CHAR_STRING '=' CHAR_STRING
;
move_to_filegroup_clause
: MOVE FILE CHAR_STRING TO FILEGROUP id_expression
;
drop_filegroup_clause
: DROP FILEGROUP id_expression CASCADE?
;
quorum_regular
: QUORUM
| REGULAR
;
undrop_disk_clause
: UNDROP DISKS
;
diskgroup_availability
: MOUNT (RESTRICTED | NORMAL)? (FORCE | NOFORCE)?
| DISMOUNT (FORCE | NOFORCE)?
;
enable_disable_volume
: (ENABLE | DISABLE) VOLUME (id_expression (',' id_expression)* | ALL)
;
// DDL -> SQL Statements for Stored PL/SQL Units
// Function DDLs
drop_function
: DROP FUNCTION function_name
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-FLASHBACK-ARCHIVE.html
alter_flashback_archive
: ALTER FLASHBACK ARCHIVE fa = id_expression (
SET DEFAULT
| (ADD | MODIFY) TABLESPACE ts = id_expression flashback_archive_quota?
| REMOVE TABLESPACE rts = id_expression
| MODIFY /*RETENTION*/ flashback_archive_retention // inconsistent documentation
| PURGE (ALL | BEFORE (SCN expression | TIMESTAMP expression))
| NO? OPTIMIZE DATA
)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-HIERARCHY.html
alter_hierarchy
: ALTER HIERARCHY (schema_name '.')? hn = id_expression (
RENAME TO nhn = id_expression
| COMPILE
)
;
alter_function
: ALTER FUNCTION function_name (
EDITIONABLE
| NONEDITIONABLE
| COMPILE DEBUG? compiler_parameters_clause* (REUSE SETTINGS)?
)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-JAVA.html
alter_java
: ALTER JAVA (SOURCE | CLASS) (schema_name '.')? o = id_expression (
RESOLVER '(' ('(' match_string ','? (schema_name | '-') ')')+ ')'
)? (COMPILE | RESOLVE | invoker_rights_clause)
;
match_string
: DELIMITED_ID
| '*'
;
create_function_body
: CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? FUNCTION function_name (
'(' parameter (',' parameter)* ')'
)? RETURN type_spec (SHARING '=' (METADATA | NONE))? (
invoker_rights_clause
| accessible_by_clause
| default_collation_clause
| parallel_enable_clause
| result_cache_clause
| PIPELINED
| DETERMINISTIC
)* (
((IS | AS) (DECLARE? seq_of_declare_specs? body | call_spec))
| aggregate_clause
| pipelined_using_clause
| sql_macro_body
)
;
sql_macro_body
: SQL_MACRO IS BEGIN RETURN quoted_string SEMICOLON END
;
// Creation Function - Specific Clauses
parallel_enable_clause
: PARALLEL_ENABLE partition_by_clause?
;
partition_by_clause
: '(' PARTITION expression BY (ANY | (HASH | RANGE | LIST) paren_column_list) streaming_clause? ')'
;
result_cache_clause
: RESULT_CACHE relies_on_part? ('(' MODE (DEFAULT | FORCE ) ')')?
;
accessible_by_clause
: ACCESSIBLE BY '(' accessor (',' accessor)* ')'
;
default_collation_clause
: DEFAULT COLLATION USING_NLS_COMP
;
aggregate_clause
: AGGREGATE USING implementation_type_name
;
pipelined_using_clause
: PIPELINED ((ROW | TABLE) POLYMORPHIC)? USING implementation_type_name
;
accessor
: unitKind = (FUNCTION | PROCEDURE | PACKAGE | TRIGGER | TYPE) function_name
;
relies_on_part
: RELIES_ON '(' tableview_name (',' tableview_name)* ')'
;
streaming_clause
: (ORDER | CLUSTER) expression BY paren_column_list
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-OUTLINE.html
alter_outline
: ALTER OUTLINE (PUBLIC | PRIVATE)? o = id_expression outline_options+
;
outline_options
: REBUILD
| RENAME TO non = id_expression
| CHANGE CATEGORY TO ncn = id_expression
| ENABLE
| DISABLE
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-LOCKDOWN-PROFILE.html
alter_lockdown_profile
: ALTER LOCKDOWN PROFILE id_expression (
lockdown_feature
| lockdown_options
| lockdown_statements
) (USERS '=' (ALL | COMMON | LOCAL))?
;
lockdown_feature
: disable_enable FEATURE ('=' '(' string_list ')' | ALL (EXCEPT '=' '(' string_list ')')?)
;
lockdown_options
: disable_enable OPTION ('=' '(' string_list ')' | ALL (EXCEPT '=' '(' string_list ')')?)
;
lockdown_statements
: disable_enable STATEMENT (
'=' '(' string_list ')'
| '=' '(' CHAR_STRING ')' statement_clauses
| ALL (EXCEPT '=' '(' string_list ')')?
)
;
statement_clauses
: CLAUSE (
'=' '(' string_list ')'
| '=' '(' CHAR_STRING ')' clause_options
| ALL (EXCEPT '=' '(' string_list ')')?
)
;
clause_options
: OPTION (
'=' '(' string_list ')'
| '=' '(' CHAR_STRING ')' option_values+
| ALL (EXCEPT '=' '(' string_list ')')?
)
;
option_values
: VALUE '=' '(' string_list ')'
| (MINVALUE | MAXVALUE) '=' CHAR_STRING
;
string_list
: CHAR_STRING (',' CHAR_STRING)*
;
disable_enable
: DISABLE
| ENABLE
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-LOCKDOWN-PROFILE.html
drop_lockdown_profile
: DROP LOCKDOWN PROFILE p = id_expression
;
// Package DDLs
drop_package
: DROP PACKAGE BODY? (schema_object_name '.')? package_name
;
alter_package
: ALTER PACKAGE package_name COMPILE DEBUG? (PACKAGE | BODY | SPECIFICATION)? compiler_parameters_clause* (
REUSE SETTINGS
)?
;
create_package
: CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? PACKAGE (schema_object_name '.')? package_name invoker_rights_clause? (
IS
| AS
) package_obj_spec* END package_name?
;
create_package_body
: CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? PACKAGE BODY (schema_object_name '.')? package_name (
IS
| AS
) package_obj_body*? (BEGIN seq_of_statements (EXCEPTION exception_handler+)?)? END package_name?
;
// Create Package Specific Clauses
package_obj_spec
: pragma_declaration
| exception_declaration
| procedure_spec
| function_spec
| variable_declaration
| subtype_declaration
| cursor_declaration
| type_declaration
;
procedure_spec
: PROCEDURE identifier ('(' parameter ( ',' parameter)* ')')? (
accessible_by_clause
| PARALLEL_ENABLE
| DETERMINISTIC
)* (AS call_spec)? ';'
;
function_spec
: FUNCTION identifier ('(' parameter ( ',' parameter)* ')')? RETURN type_spec (
DETERMINISTIC
| PIPELINED
| parallel_enable_clause
| RESULT_CACHE
| streaming_clause
)* (AS call_spec)? ';'
;
package_obj_body
: pragma_declaration
| exception_declaration
| procedure_spec
| function_spec
| subtype_declaration
| cursor_declaration
| variable_declaration
| type_declaration
| procedure_body
| function_body
| selection_directive
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/alter-pmem-filestore.html
alter_pmem_filestore
: ALTER PMEM FILESTORE fsn = id_expression (
RESIZE size_clause
| autoextend_clause
| MOUNT (MOUNTPOINT file_path)? (BACKINGFILE filename)? FORCE? //inconsistent documentation
| DISMOUNT
)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/drop-pmem-filestore.html
drop_pmem_filestore
: DROP PMEM FILESTORE fsn = id_expression ((FORCE? INCLUDING | EXCLUDING) CONTENTS)?
;
// Procedure DDLs
drop_procedure
: DROP PROCEDURE procedure_name
;
alter_procedure
: ALTER PROCEDURE procedure_name COMPILE DEBUG? compiler_parameters_clause* (REUSE SETTINGS)?
;
function_body
: FUNCTION identifier ('(' parameter (',' parameter)* ')')? RETURN type_spec (
PIPELINED
| DETERMINISTIC
| invoker_rights_clause
| parallel_enable_clause
| result_cache_clause
| streaming_clause
// 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
)* (
( (IS | AS) (DECLARE? seq_of_declare_specs? body | call_spec))
| (PIPELINED | AGGREGATE) USING implementation_type_name
) ';'
;
procedure_body
: PROCEDURE identifier ('(' parameter (',' parameter)* ')')? (
accessible_by_clause
| PARALLEL_ENABLE
| DETERMINISTIC
)* (IS | AS) (DECLARE? seq_of_declare_specs? body | call_spec | EXTERNAL) ';'
;
create_procedure_body
: CREATE (OR REPLACE)? PROCEDURE procedure_name ('(' parameter (',' parameter)* ')')? invoker_rights_clause? (PARALLEL_ENABLE | DETERMINISTIC)* (
IS
| AS
) (DECLARE? seq_of_declare_specs? body | call_spec | EXTERNAL)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-RESOURCE-COST.html
alter_resource_cost
: ALTER RESOURCE COST (
(CPU_PER_SESSION | CONNECT_TIME | LOGICAL_READS_PER_SESSION | PRIVATE_SGA) UNSIGNED_INTEGER
)+
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-OUTLINE.html
drop_outline
: DROP OUTLINE o = id_expression
;
// Rollback Segment DDLs
//https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_2011.htm#SQLRF00816
alter_rollback_segment
: ALTER ROLLBACK SEGMENT rollback_segment_name (
ONLINE
| OFFLINE
| storage_clause
| SHRINK (TO size_clause)?
)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-RESTORE-POINT.html
drop_restore_point
: DROP RESTORE POINT rp = id_expression (FOR PLUGGABLE DATABASE pdb = id_expression)?
;
drop_rollback_segment
: DROP ROLLBACK SEGMENT rollback_segment_name
;
drop_role
: DROP ROLE role_name
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/create-pmem-filestore.html
create_pmem_filestore
: CREATE PMEM FILESTORE fsn = id_expression pmem_filestore_options+
;
pmem_filestore_options
: MOUNTPOINT file_path
| BACKINGFILE filename REUSE?
| (SIZE | BLOCKSIZE) size_clause
| autoextend_clause
;
file_path
: CHAR_STRING
;
create_rollback_segment
: CREATE PUBLIC? ROLLBACK SEGMENT rollback_segment_name (
TABLESPACE tablespace
| storage_clause
)*
;
// Trigger DDLs
drop_trigger
: DROP TRIGGER trigger_name
;
alter_trigger
: ALTER TRIGGER alter_trigger_name = trigger_name (
(ENABLE | DISABLE)
| RENAME TO rename_trigger_name = trigger_name
| COMPILE DEBUG? compiler_parameters_clause* (REUSE SETTINGS)?
)
;
create_trigger
: CREATE (OR REPLACE)? TRIGGER trigger_name (
simple_dml_trigger
| compound_dml_trigger
| non_dml_trigger
) trigger_follows_clause? (ENABLE | DISABLE)? trigger_when_clause? trigger_body
;
trigger_follows_clause
: FOLLOWS trigger_name (',' trigger_name)*
;
trigger_when_clause
: WHEN '(' condition ')'
;
// Create Trigger Specific Clauses
simple_dml_trigger
: (BEFORE | AFTER | INSTEAD OF) dml_event_clause referencing_clause? for_each_row?
;
for_each_row
: FOR EACH ROW
;
compound_dml_trigger
: FOR dml_event_clause referencing_clause?
;
non_dml_trigger
: (BEFORE | AFTER) non_dml_event (OR non_dml_event)* ON (DATABASE | (schema_name '.')? SCHEMA)
;
trigger_body
: compound_trigger_block
| CALL identifier
| trigger_block
;
compound_trigger_block
: COMPOUND TRIGGER seq_of_declare_specs? timing_point_section+ END trigger_name?
;
timing_point_section
: bk = BEFORE STATEMENT IS tps_block BEFORE STATEMENT ';'
| bk = BEFORE EACH ROW IS tps_block BEFORE EACH ROW ';'
| ak = AFTER STATEMENT IS tps_block AFTER STATEMENT ';'
| ak = AFTER EACH ROW IS tps_block AFTER EACH ROW ';'
;
non_dml_event
: ALTER
| ANALYZE
| ASSOCIATE STATISTICS
| AUDIT
| COMMENT
| CREATE
| DISASSOCIATE STATISTICS
| DROP
| GRANT
| NOAUDIT
| RENAME
| REVOKE
| TRUNCATE
| DDL
| STARTUP
| SHUTDOWN
| DB_ROLE_CHANGE
| LOGON
| LOGOFF
| SERVERERROR
| SUSPEND
| DATABASE
| SCHEMA
| FOLLOWS
;
dml_event_clause
: dml_event_element (OR dml_event_element)* ON dml_event_nested_clause? tableview_name
;
dml_event_element
: (DELETE | INSERT | UPDATE) (OF column_list)?
;
dml_event_nested_clause
: NESTED TABLE tableview_name OF
;
referencing_clause
: (REFERENCING referencing_element | REFERENCES) referencing_element*
;
referencing_element
: (NEW | OLD | PARENT) column_alias
;
// DDLs
drop_type
: DROP TYPE BODY? type_name (FORCE | VALIDATE)?
;
alter_type
: ALTER TYPE type_name (
compile_type_clause
| replace_type_clause
| alter_method_spec
| alter_collection_clauses
| modifier_clause
| overriding_subprogram_spec
) dependent_handling_clause?
;
// Alter Type Specific Clauses
compile_type_clause
: COMPILE DEBUG? (SPECIFICATION | BODY)? compiler_parameters_clause* (REUSE SETTINGS)?
;
replace_type_clause
: REPLACE invoker_rights_clause? AS OBJECT '(' object_member_spec (',' object_member_spec)* ')'
;
alter_method_spec
: alter_method_element (',' alter_method_element)*
;
alter_method_element
: (ADD | DROP) (map_order_function_spec | subprogram_spec)
;
alter_collection_clauses
: MODIFY (LIMIT expression | ELEMENT TYPE type_spec)
;
dependent_handling_clause
: INVALIDATE
| CASCADE (CONVERT TO SUBSTITUTABLE | NOT? INCLUDING TABLE DATA)? dependent_exceptions_part?
;
dependent_exceptions_part
: FORCE? EXCEPTIONS INTO tableview_name
;
create_type
: CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? TYPE (type_definition | type_body)
;
// Create Type Specific Clauses
type_definition
: type_name (OID CHAR_STRING)? FORCE? object_type_def?
;
object_type_def
: invoker_rights_clause? (object_as_part | object_under_part) sqlj_object_type? (
'(' object_member_spec (',' object_member_spec)* ')'
)? modifier_clause*
;
object_as_part
: (IS | AS) (OBJECT | varray_type_def | nested_table_type_def)
;
object_under_part
: UNDER type_spec
;
nested_table_type_def
: TABLE OF type_spec (NOT NULL_)?
;
sqlj_object_type
: EXTERNAL NAME expression LANGUAGE JAVA USING (SQLDATA | CUSTOMDATUM | ORADATA)
;
type_body
: BODY type_name (IS | AS) (type_body_elements)+ END
;
type_body_elements
: map_order_func_declaration
| subprog_decl_in_type
| overriding_subprogram_spec
;
map_order_func_declaration
: (MAP | ORDER) MEMBER func_decl_in_type
;
subprog_decl_in_type
: (MEMBER | STATIC)? (proc_decl_in_type | func_decl_in_type | constructor_declaration)
;
proc_decl_in_type
: PROCEDURE procedure_name
(
'(' type_elements_parameter (',' type_elements_parameter)* ')'
)?
(IS | AS) (call_spec | DECLARE? seq_of_declare_specs? body ';')
;
func_decl_in_type
: FUNCTION function_name ('(' type_elements_parameter (',' type_elements_parameter)* ')')? RETURN type_spec (
IS
| AS
) (call_spec | DECLARE? seq_of_declare_specs? body ';')
;
constructor_declaration
: FINAL? INSTANTIABLE? CONSTRUCTOR FUNCTION function_name
(
'(' (SELF IN OUT type_spec ',')? (type_elements_parameter (',' type_elements_parameter)*)? ')'
)?
RETURN SELF AS RESULT (IS | AS) (call_spec | DECLARE? seq_of_declare_specs? body ';')
;
// Common Type Clauses
modifier_clause
: NOT? (INSTANTIABLE | FINAL | OVERRIDING)
;
object_member_spec
: identifier type_spec sqlj_object_type_attr?
| element_spec
;
sqlj_object_type_attr
: EXTERNAL NAME expression
;
element_spec
: modifier_clause? element_spec_options+ (',' pragma_clause)?
;
element_spec_options
: subprogram_spec
| constructor_spec
| map_order_function_spec
;
subprogram_spec
: (MEMBER | STATIC) (type_procedure_spec | type_function_spec)
;
// TODO: should be refactored such as Procedure body and Function body, maybe Type_Function_Body and overriding_function_body
overriding_subprogram_spec
: OVERRIDING MEMBER overriding_function_spec
| OVERRIDING MEMBER overriding_procedure_spec
;
overriding_function_spec
: FUNCTION function_name ('(' type_elements_parameter (',' type_elements_parameter)* ')')? RETURN (
type_spec
| SELF AS RESULT
) (PIPELINED? (IS | AS) (DECLARE? seq_of_declare_specs? body))? ';'?
;
overriding_procedure_spec
: PROCEDURE procedure_name
(
'(' type_elements_parameter (',' type_elements_parameter)* ')'
)?
(IS | AS) (call_spec | DECLARE? seq_of_declare_specs? body ';')
;
type_procedure_spec
: PROCEDURE procedure_name ('(' type_elements_parameter (',' type_elements_parameter)* ')')? (
(IS | AS) call_spec
)?
;
type_function_spec
: FUNCTION function_name ('(' type_elements_parameter (',' type_elements_parameter)* ')')? RETURN (
type_spec
| SELF AS RESULT
) ((IS | AS) call_spec | EXTERNAL VARIABLE? NAME expression)?
;
constructor_spec
: FINAL? INSTANTIABLE? CONSTRUCTOR FUNCTION type_spec (
'(' (SELF IN OUT type_spec ',')? (type_elements_parameter (',' type_elements_parameter)*)? ')'
)? RETURN SELF AS RESULT ((IS | AS) call_spec)?
;
map_order_function_spec
: (MAP | ORDER) MEMBER type_function_spec
;
pragma_clause
: PRAGMA RESTRICT_REFERENCES '(' pragma_elements (',' pragma_elements)* ')'
;
pragma_elements
: identifier
| DEFAULT
;
type_elements_parameter
: parameter_name (IN OUT NOCOPY | IN OUT | OUT NOCOPY | OUT | IN)? type_spec (ASSIGN_OP constant)?
;
// Sequence DDLs
drop_sequence
: DROP SEQUENCE sequence_name
;
alter_sequence
: ALTER SEQUENCE sequence_name sequence_spec+
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-SESSION.html
alter_session
: ALTER SESSION (
ADVISE ( COMMIT | ROLLBACK | NOTHING)
| CLOSE DATABASE LINK parameter_name
| enable_or_disable COMMIT IN PROCEDURE
| enable_or_disable GUARD
| (enable_or_disable | FORCE) PARALLEL (DML | DDL | QUERY) (
PARALLEL (literal | parameter_name)
)?
| SET alter_session_set_clause
)
;
alter_session_set_clause
: (parameter_name '=' parameter_value)+
| EDITION '=' en = id_expression
| CONTAINER '=' cn = id_expression (SERVICE '=' sn = id_expression)?
| ROW ARCHIVAL VISIBILITY '=' (ACTIVE | ALL)
| DEFAULT_COLLATION '=' (c = id_expression | NONE)
;
create_sequence
: CREATE SEQUENCE (IF NOT EXISTS)? sequence_name sequence_spec* (SHARING '=' (METADATA | DATA | NONE))?
;
// Common Sequence
sequence_spec
: INCREMENT BY UNSIGNED_INTEGER
| sequence_start_clause
| MAXVALUE UNSIGNED_INTEGER
| NOMAXVALUE
| MINVALUE UNSIGNED_INTEGER
| NOMINVALUE
| CYCLE
| NOCYCLE
| CACHE UNSIGNED_INTEGER
| NOCACHE
| ORDER
| NOORDER
| KEEP
| NOKEEP
| SCALE (EXTEND | NOEXTEND)?
| NOSCALE
| SHARD (EXTEND | NOEXTEND)?
| NOSHARD
| SESSION
| GLOBAL
;
sequence_start_clause
: START WITH UNSIGNED_INTEGER
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-ANALYTIC-VIEW.html
create_analytic_view
: CREATE (OR REPLACE)? (NOFORCE | FORCE)? ANALYTIC VIEW av = id_expression (
SHARING '=' (METADATA | NONE)
)? classification_clause* cav_using_clause? dim_by_clause? measures_clause? default_measure_clause? default_aggregate_clause? cache_clause?
fact_columns_clause? qry_transform_clause?
;
classification_clause
// : (CAPTION c=quoted_string)? (DESCRIPTION d=quoted_string)? classification_item*
// to handle - 'rule contains a closure with at least one alternative that can match an empty string'
: (caption_clause description_clause? | caption_clause? description_clause) classification_item*
| caption_clause? description_clause? classification_item+
;
caption_clause
: CAPTION c = quoted_string
;
description_clause
: DESCRIPTION d = quoted_string
;
classification_item
: CLASSIFICATION cn = id_expression (VALUE cv = quoted_string)? (LANGUAGE language)?
;
language
: NULL_
| nls = id_expression
;
cav_using_clause
: USING (schema_name '.')? t = id_expression REMOTE? (AS? ta = id_expression)?
;
dim_by_clause
: DIMENSION BY '(' dim_key (',' dim_key)* ')'
;
dim_key
: dim_ref classification_clause* KEY (
'(' (a = id_expression '.')? f = column_name (',' (a = id_expression '.')? f = column_name)* ')'
| (a = id_expression '.')? f = column_name
) REFERENCES DISTINCT? ('(' attribute_name (',' attribute_name) ')' | attribute_name) HIERARCHIES '(' hier_ref (
',' hier_ref
)* ')'
;
dim_ref
: (schema_name '.')? ad = id_expression (AS? da = id_expression)?
;
hier_ref
: (schema_name '.')? h = id_expression (AS? ha = id_expression)? DEFAULT?
;
measures_clause
: MEASURES '(' av_measure (',' av_measure)* ')'
;
av_measure
: mn = id_expression (base_meas_clause | calc_meas_clause)? //classification_clause*
;
base_meas_clause
: FACT /*FOR MEASURE*/ bm = id_expression meas_aggregate_clause? //FIXME inconsistent documentation
;
meas_aggregate_clause
: AGGREGATE BY aggregate_function_name
;
calc_meas_clause
: /*m=id_expression*/ AS '(' expression ')' //FIXME inconsistent documentation
;
default_measure_clause
: DEFAULT MEASURE m = id_expression
;
default_aggregate_clause
: DEFAULT AGGREGATE BY aggregate_function_name
;
cache_clause
: CACHE cache_specification (',' cache_specification)*
;
cache_specification
: MEASURE GROUP (
ALL
| '(' id_expression (',' id_expression)* ')' levels_clause (',' levels_clause)*
)
;
levels_clause
: LEVELS '(' level_specification (',' level_specification)* ')' level_group_type
;
level_specification
: '(' ((d = id_expression '.')? h = id_expression '.')? l = id_expression ')'
;
level_group_type
: DYNAMIC
| MATERIALIZED (USING (schema_name '.')? t = id_expression)?
;
fact_columns_clause
: FACT COLUMN f = column_name (AS? fa = id_expression (',' AS? fa = id_expression)*)?
;
qry_transform_clause
: ENABLE QUERY TRANSFORM (RELY | NORELY)?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-ATTRIBUTE-DIMENSION.html
create_attribute_dimension
: CREATE (OR REPLACE)? (NOFORCE | FORCE)? ATTRIBUTE DIMENSION (schema_name '.')? ad = id_expression (
SHARING '=' (METADATA | NONE)
)? classification_clause* (DIMENSION TYPE (STANDARD | TIME))? ad_using_clause attributes_clause ad_level_clause+ all_clause?
;
ad_using_clause
: USING source_clause (',' source_clause)* join_path_clause*
;
source_clause
: (schema_name '.')? ftov = id_expression REMOTE? (AS? a = id_expression)?
;
join_path_clause
: JOIN PATH jpn = id_expression ON join_condition
;
join_condition
: join_condition_item (AND join_condition_item)*
;
join_condition_item
: (a = id_expression '.')? column_name '=' (b = id_expression '.')? column_name
;
attributes_clause
: ATTRIBUTES '(' ad_attributes_clause (',' ad_attributes_clause)* ')'
;
ad_attributes_clause
: (a = id_expression '.')? column_name (AS? an = id_expression)? classification_clause*
;
ad_level_clause
: LEVEL l = id_expression (NOT NULL_ | SKIP_ WHEN NULL_)? (
LEVEL TYPE (
STANDARD
| YEARS
| HALF_YEARS
| QUARTERS
| MONTHS
| WEEKS
| DAYS
| HOURS
| MINUTES
| SECONDS
)
)? classification_clause* //inconsistent documentation - LEVEL TYPE goes after the classification_clause rule
key_clause alternate_key_clause? (MEMBER NAME expression)? (MEMBER CAPTION expression)? (
MEMBER DESCRIPTION expression
)? (ORDER BY (MIN | MAX)? dim_order_clause (',' (MIN | MAX)? dim_order_clause)*)? (
DETERMINES '(' id_expression (',' id_expression)* ')'
)?
;
key_clause
: KEY (a = id_expression | '(' id_expression (',' id_expression)* ')')
;
alternate_key_clause
: ALTERNATE key_clause
;
dim_order_clause
: a = id_expression (ASC | DESC)? (NULLS (FIRST | LAST))?
;
all_clause
: ALL MEMBER (
NAME expression (MEMBER CAPTION expression)?
| CAPTION expression (MEMBER DESCRIPTION expression)?
| DESCRIPTION expression
)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-AUDIT-POLICY-Unified-Auditing.html
create_audit_policy
: CREATE AUDIT POLICY p = id_expression privilege_audit_clause? action_audit_clause? role_audit_clause? (
WHEN quoted_string EVALUATE PER (STATEMENT | SESSION | INSTANCE)
)? (ONLY TOPLEVEL)? container_clause?
;
privilege_audit_clause
: PRIVILEGES system_privilege (',' system_privilege)*
;
action_audit_clause
: (standard_actions | component_actions | system_actions)+
;
system_actions
: ACTIONS system_privilege (',' system_privilege)*
;
standard_actions
: ACTIONS actions_clause (',' actions_clause)*
;
actions_clause
: (object_action | ALL) ON (
DIRECTORY directory_name
| (MINING MODEL)? (schema_name '.')? id_expression
)
| (system_action | ALL)
;
object_action
: ALTER
| GRANT
| READ
| EXECUTE
| AUDIT
| COMMENT
| DELETE
| INDEX
| INSERT
| LOCK
| SELECT
| UPDATE
| FLASHBACK
| RENAME
;
system_action
: id_expression // SELECT name FROM AUDITABLE_SYSTEM_ACTIONS WHERE component = 'Standard';
| (CREATE | ALTER | DROP) JAVA
| LOCK TABLE
| (READ | WRITE | EXECUTE) DIRECTORY
;
component_actions
: ACTIONS COMPONENT '=' (
(DATAPUMP | DIRECT_LOAD | OLS | XS) component_action (',' component_action)*
| DV component_action ON id_expression (',' component_action ON id_expression)*
| PROTOCOL (FTP | HTTP | AUTHENTICATION)
)
;
component_action
: id_expression // SELECT name FROM auditable_system_actions WHERE component = 'Datapump';
;
role_audit_clause
: ROLES role_name (',' role_name)*
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-CONTROLFILE.html
create_controlfile
: CREATE CONTROLFILE REUSE? SET? DATABASE d = id_expression logfile_clause? (
RESETLOGS
| NORESETLOGS
) (DATAFILE file_specification (',' file_specification)*)? controlfile_options* character_set_clause?
;
controlfile_options
: MAXLOGFILES numeric
| MAXLOGMEMBERS numeric
| MAXLOGHISTORY numeric
| MAXDATAFILES numeric
| MAXINSTANCES numeric
| ARCHIVELOG
| NOARCHIVELOG
| FORCE LOGGING
| SET STANDBY NOLOGGING FOR (DATA AVAILABILITY | LOAD PERFORMANCE)
;
logfile_clause
: LOGFILE (GROUP? numeric)? file_specification (',' (GROUP? numeric)? file_specification)*
;
character_set_clause
: CHARACTER SET cs = id_expression
;
file_specification
: datafile_tempfile_spec
| redo_log_file_spec
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-DISKGROUP.html
create_diskgroup
: CREATE DISKGROUP id_expression (
(HIGH | NORMAL | FLEX | EXTENDED (SITE sn = id_expression)? | EXTERNAL) REDUNDANCY
)? (
quorum_regular? (FAILGROUP fg = id_expression)? DISK qualified_disk_clause (
',' qualified_disk_clause
)*
)+ (ATTRIBUTE an = CHAR_STRING '=' av = CHAR_STRING (',' CHAR_STRING '=' CHAR_STRING)*)?
;
qualified_disk_clause
: ss = CHAR_STRING (NAME dn = id_expression)? (SIZE size_clause)? force_noforce?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-EDITION.html
create_edition
: CREATE EDITION e = id_expression (AS CHILD OF pe = id_expression)?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-FLASHBACK-ARCHIVE.html
create_flashback_archive
: CREATE FLASHBACK ARCHIVE DEFAULT? fa = id_expression TABLESPACE ts = id_expression flashback_archive_quota? (
NO? OPTIMIZE DATA
)? flashback_archive_retention
;
flashback_archive_quota
: QUOTA UNSIGNED_INTEGER (M_LETTER | G_LETTER | T_LETTER | P_LETTER | E_LETTER)
;
flashback_archive_retention
: RETENTION UNSIGNED_INTEGER (YEAR | MONTH | DAY)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-HIERARCHY.html
create_hierarchy
: CREATE (OR REPLACE)? (NO? FORCE)? HIERARCHY (schema_name '.')? h = id_expression (
SHARING '=' (METADATA | NONE)
)? classification_clause* hier_using_clause level_hier_clause hier_attrs_clause?
;
hier_using_clause
: USING (schema_name '.')? ad = id_expression
;
level_hier_clause
: '(' (l = id_expression (CHILD OF)?)+ ')'
;
hier_attrs_clause
: HIERARCHICAL ATTRIBUTES '(' hier_attr_clause ')'
;
hier_attr_clause
: hier_attr_name classification_clause*
;
hier_attr_name
: MEMBER_NAME
| MEMBER_UNIQUE_NAME
| MEMBER_CAPTION
| MEMBER_DESCRIPTION
| LEVEL_NAME
| HIER_ORDER
| DEPTH
| IS_LEAF
| PARENT_LEVEL_NAME
| PARENT_UNIQUE_NAME
;
create_index
: CREATE (UNIQUE | BITMAP)? INDEX index_name (IF NOT EXISTS)? ON (
cluster_index_clause
| table_index_clause
| bitmap_join_index_clause
) (USABLE | UNUSABLE)? ((DEFERRED | IMMEDIATE) INVALIDATION)?
;
cluster_index_clause
: CLUSTER cluster_name index_attributes?
;
cluster_name
: (id_expression '.')? id_expression
;
table_index_clause
: tableview_name table_alias? '(' index_expr (ASC | DESC)? (',' index_expr (ASC | DESC)?)* ')' index_properties?
;
bitmap_join_index_clause
: tableview_name '(' (tableview_name | table_alias)? column_name (ASC | DESC)? (
',' (tableview_name | table_alias)? column_name (ASC | DESC)?
)* ')' FROM tableview_name table_alias (',' tableview_name table_alias)* where_clause local_partitioned_index? index_attributes?
;
index_expr
: column_name
| expression
;
index_properties
: (global_partitioned_index | local_partitioned_index | index_attributes)+
| INDEXTYPE IS (domain_index_clause | xmlindex_clause)
;
domain_index_clause
: indextype local_domain_index_clause? parallel_clause? (PARAMETERS '(' odci_parameters ')')?
;
local_domain_index_clause
: LOCAL (
'(' PARTITION partition_name (PARAMETERS '(' odci_parameters ')')? (
',' PARTITION partition_name (PARAMETERS '(' odci_parameters ')')?
)* ')'
)?
;
xmlindex_clause
: (XDB '.')? XMLINDEX local_xmlindex_clause? parallel_clause? //TODO xmlindex_parameters_clause?
;
local_xmlindex_clause
: LOCAL (
'(' PARTITION partition_name (
',' PARTITION partition_name //TODO xmlindex_parameters_clause?
)* ')'
)?
;
global_partitioned_index
: GLOBAL PARTITION BY (
RANGE '(' column_name (',' column_name)* ')' '(' index_partitioning_clause (
',' index_partitioning_clause
)* ')'
| HASH '(' column_name (',' column_name)* ')' (
individual_hash_partitions
| hash_partitions_by_quantity
)
)
;
index_partitioning_clause
: PARTITION partition_name? VALUES LESS THAN '(' index_partitioning_values_list ')' segment_attributes_clause?
;
index_partitioning_values_list
: literal (',' literal)*
| TIMESTAMP literal (',' TIMESTAMP literal)*
;
local_partitioned_index
: LOCAL (
on_range_partitioned_table
| on_list_partitioned_table
| on_hash_partitioned_table
| on_comp_partitioned_table
)?
;
on_range_partitioned_table
: '(' partitioned_table (',' partitioned_table)* ')'
;
on_list_partitioned_table
: '(' partitioned_table (',' partitioned_table)* ')'
;
partitioned_table
: PARTITION partition_name? (segment_attributes_clause | key_compression)* UNUSABLE?
;
on_hash_partitioned_table
: STORE IN '(' tablespace (',' tablespace)* ')'
| '(' on_hash_partitioned_clause (',' on_hash_partitioned_clause)* ')'
;
on_hash_partitioned_clause
: PARTITION partition_name? (TABLESPACE tablespace)? key_compression? UNUSABLE?
;
on_comp_partitioned_table
: (STORE IN '(' tablespace (',' tablespace)* ')')? '(' on_comp_partitioned_clause (
',' on_comp_partitioned_clause
)* ')'
;
on_comp_partitioned_clause
: PARTITION partition_name? (segment_attributes_clause | key_compression)* UNUSABLE? index_subpartition_clause?
;
index_subpartition_clause
: STORE IN '(' tablespace (',' tablespace)* ')'
| '(' index_subpartition_subclause (',' index_subpartition_subclause)* ')'
;
index_subpartition_subclause
: SUBPARTITION subpartition_name? (TABLESPACE tablespace)? key_compression? UNUSABLE?
;
odci_parameters
: CHAR_STRING
;
indextype
: (id_expression '.')? id_expression
;
//https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_1010.htm#SQLRF00805
alter_index
: ALTER INDEX index_name (alter_index_ops_set1 | alter_index_ops_set2)
;
alter_index_ops_set1
: (
deallocate_unused_clause
| allocate_extent_clause
| shrink_clause
| parallel_clause
| physical_attributes_clause
| logging_clause
)+
;
alter_index_ops_set2
: rebuild_clause
| PARAMETERS '(' odci_parameters ')'
| COMPILE
| enable_or_disable
| UNUSABLE
| visible_or_invisible
| RENAME TO new_index_name
| COALESCE
| monitoring_nomonitoring USAGE
| UPDATE BLOCK REFERENCES
| alter_index_partitioning
;
visible_or_invisible
: VISIBLE
| INVISIBLE
;
monitoring_nomonitoring
: MONITORING
| NOMONITORING
;
rebuild_clause
: REBUILD (PARTITION partition_name | SUBPARTITION subpartition_name | REVERSE | NOREVERSE)? (
parallel_clause
| TABLESPACE tablespace
| PARAMETERS '(' odci_parameters ')'
//TODO | xmlindex_parameters_clause
| ONLINE
| physical_attributes_clause
| key_compression
| logging_clause
)*
;
alter_index_partitioning
: modify_index_default_attrs
| add_hash_index_partition
| modify_index_partition
| rename_index_partition
| drop_index_partition
| split_index_partition
| coalesce_index_partition
| modify_index_subpartition
;
modify_index_default_attrs
: MODIFY DEFAULT ATTRIBUTES (FOR PARTITION partition_name)? (
physical_attributes_clause
| TABLESPACE (tablespace | DEFAULT)
| logging_clause
)
;
add_hash_index_partition
: ADD PARTITION partition_name? (TABLESPACE tablespace)? key_compression? parallel_clause?
;
coalesce_index_partition
: COALESCE PARTITION parallel_clause?
;
modify_index_partition
: MODIFY PARTITION partition_name (
modify_index_partitions_ops+
| PARAMETERS '(' odci_parameters ')'
| COALESCE
| UPDATE BLOCK REFERENCES
| UNUSABLE
)
;
modify_index_partitions_ops
: deallocate_unused_clause
| allocate_extent_clause
| physical_attributes_clause
| logging_clause
| key_compression
| shrink_clause
;
rename_index_partition
: RENAME (PARTITION partition_name | SUBPARTITION subpartition_name) TO new_partition_name
;
drop_index_partition
: DROP PARTITION partition_name
;
split_index_partition
: SPLIT PARTITION partition_name_old AT '(' literal (',' literal)* ')' (
INTO '(' index_partition_description ',' index_partition_description ')'
)? parallel_clause?
;
index_partition_description
: PARTITION (
partition_name (
(segment_attributes_clause | key_compression)+
| PARAMETERS '(' odci_parameters ')'
) UNUSABLE?
)?
;
modify_index_subpartition
: MODIFY SUBPARTITION subpartition_name (UNUSABLE | modify_index_partitions_ops)
;
partition_name_old
: partition_name
;
new_partition_name
: partition_name
;
new_index_name
: index_name
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-INMEMORY-JOIN-GROUP.html
alter_inmemory_join_group
: ALTER INMEMORY JOIN GROUP (schema_name '.')? jg = id_expression (ADD | REMOVE) '(' (
schema_name '.'
)? t = id_expression '(' c = id_expression ')' ')'
;
create_user
: CREATE USER user_object_name (IF NOT EXISTS)? (
identified_by
| identified_other_clause
| user_tablespace_clause
| quota_clause
| profile_clause
| password_expire_clause
| user_lock_clause
| user_editions_clause
| container_clause
)+
;
// The standard clauses only permit one user per statement.
// The proxy clause allows multiple users for a proxy designation.
alter_user
: ALTER USER user_object_name (
alter_identified_by
| identified_other_clause
| user_tablespace_clause
| quota_clause
| profile_clause
| user_default_role_clause
| password_expire_clause
| user_lock_clause
| alter_user_editions_clause
| container_clause
| container_data_clause
)+
| user_object_name (',' user_object_name)* proxy_clause
;
drop_user
: DROP USER user_object_name (IF EXISTS)? CASCADE?
;
alter_identified_by
: identified_by (REPLACE id_expression)?
;
identified_by
: IDENTIFIED BY id_expression
;
identified_other_clause
: IDENTIFIED (EXTERNALLY | GLOBALLY) (AS quoted_string)?
;
user_tablespace_clause
: (DEFAULT | TEMPORARY) TABLESPACE id_expression
;
quota_clause
: QUOTA (size_clause | UNLIMITED) ON id_expression
;
profile_clause
: PROFILE id_expression
;
role_clause
: role_name (',' role_name)*
| ALL (EXCEPT role_name (',' role_name)*)*
;
user_default_role_clause
: DEFAULT ROLE (NONE | role_clause)
;
password_expire_clause
: PASSWORD EXPIRE
;
user_lock_clause
: ACCOUNT (LOCK | UNLOCK)
;
user_editions_clause
: ENABLE EDITIONS
;
alter_user_editions_clause
: user_editions_clause (FOR regular_id (',' regular_id)*)? FORCE?
;
proxy_clause
: REVOKE CONNECT THROUGH (ENTERPRISE USERS | user_object_name)
| GRANT CONNECT THROUGH (
ENTERPRISE USERS
| user_object_name (WITH (NO ROLES | ROLE role_clause))? (AUTHENTICATION REQUIRED)? (
AUTHENTICATED USING (PASSWORD | CERTIFICATE | DISTINGUISHED NAME)
)?
)
;
container_names
: LEFT_PAREN id_expression (',' id_expression)* RIGHT_PAREN
;
set_container_data
: SET CONTAINER_DATA EQUALS_OP (ALL | DEFAULT | container_names)
;
add_rem_container_data
: (ADD | REMOVE) CONTAINER_DATA EQUALS_OP container_names
;
container_data_clause
: set_container_data
| add_rem_container_data (FOR container_tableview_name)?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ADMINISTER-KEY-MANAGEMENT.html
administer_key_management
: ADMINISTER KEY MANAGEMENT (
keystore_management_clauses
| key_management_clauses
| secret_management_clauses
| zero_downtime_software_patching_clauses
)
;
keystore_management_clauses
: create_keystore
| open_keystore
| close_keystore
| backup_keystore
| alter_keystore_password
| merge_into_new_keystore
| merge_into_existing_keystore
| isolate_keystore
| unite_keystore
;
create_keystore
: CREATE (
KEYSTORE ksl = CHAR_STRING
| LOCAL? AUTO_LOGIN KEYSTORE FROM KEYSTORE ksl = CHAR_STRING
) IDENTIFIED BY keystore_password
;
open_keystore
: SET KEYSTORE OPEN force_keystore? identified_by_store container_clause?
;
force_keystore
: FORCE KEYSTORE
;
close_keystore
: SET KEYSTORE CLOSE identified_by_store? container_clause?
;
backup_keystore
: BACKUP KEYSTORE (USING bi = CHAR_STRING)? force_keystore? identified_by_store (
TO ksl = CHAR_STRING
)?
;
alter_keystore_password
: ALTER KEYSTORE PASSWORD force_keystore? IDENTIFIED BY o = keystore_password SET n = keystore_password with_backup_clause?
;
merge_into_new_keystore
: MERGE KEYSTORE ksl1 = CHAR_STRING identified_by_password_clause? AND KEYSTORE ksl2 = CHAR_STRING identified_by_password_clause? INTO NEW
KEYSTORE ksl2 = CHAR_STRING identified_by_password_clause
;
merge_into_existing_keystore
: MERGE KEYSTORE ksl1 = CHAR_STRING identified_by_password_clause? INTO EXISTING KEYSTORE ksl2 = CHAR_STRING identified_by_password_clause
with_backup_clause?
;
isolate_keystore
: FORCE? ISOLATE KEYSTORE IDENTIFIED BY i = keystore_password FROM ROOT KEYSTORE force_keystore? identified_by_store with_backup_clause?
;
unite_keystore
: UNITE KEYSTORE IDENTIFIED BY i = keystore_password WITH ROOT KEYSTORE force_keystore? identified_by_store with_backup_clause?
;
key_management_clauses
: set_key
| create_key
| use_key
| set_key_tag
| export_keys
| import_keys
| migrate_keys
| reverse_migrate_keys
| move_keys
;
set_key
: SET ENCRYPTION? KEY ((mkid ':')? mk)? using_tag_clause? using_algorithm_clause? force_keystore? identified_by_store with_backup_clause?
container_clause?
;
create_key
: CREATE ENCRYPTION? KEY ((mkid ':')? mk)? using_tag_clause? using_algorithm_clause? force_keystore? identified_by_store with_backup_clause?
container_clause?
;
mkid
: CHAR_STRING
;
mk
: CHAR_STRING
;
use_key
: USE ENCRYPTION? KEY k = CHAR_STRING using_tag_clause? force_keystore? identified_by_store with_backup_clause?
;
set_key_tag
: SET TAG t = CHAR_STRING FOR k = CHAR_STRING force_keystore? identified_by_store with_backup_clause?
;
export_keys
: EXPORT ENCRYPTION? KEYS WITH SECRET secret TO filename force_keystore? identified_by_store (
WITH IDENTIFIER IN (CHAR_STRING (',' CHAR_STRING)* | '(' subquery ')')
)?
;
import_keys
: IMPORT ENCRYPTION? KEYS WITH SECRET secret FROM filename force_keystore? identified_by_store with_backup_clause?
;
migrate_keys
: SET ENCRYPTION? KEY IDENTIFIED BY hsm = secret force_keystore? MIGRATE USING keystore_password with_backup_clause?
;
reverse_migrate_keys
: SET ENCRYPTION? KEY IDENTIFIED BY s = secret force_keystore? REVERSE MIGRATE USING hsm = secret
;
move_keys
: MOVE ENCRYPTION? KEYS TO NEW KEYSTORE ksl1 = CHAR_STRING IDENTIFIED BY ksp1 = keystore_password FROM FORCE? KEYSTORE IDENTIFIED BY ksp =
keystore_password (WITH IDENTIFIER IN (CHAR_STRING (',' CHAR_STRING)* | subquery))? with_backup_clause?
;
identified_by_store
: IDENTIFIED BY (EXTERNAL STORE | keystore_password)
;
using_algorithm_clause
: USING ALGORITHM ea = CHAR_STRING
;
using_tag_clause
: USING TAG t = CHAR_STRING
;
secret_management_clauses
: add_update_secret
| delete_secret
| add_update_secret_seps
| delete_secret_seps
;
add_update_secret
: (ADD | UPDATE) SECRET s = CHAR_STRING FOR CLIENT ci = CHAR_STRING using_tag_clause? force_keystore? identified_by_store? with_backup_clause?
;
delete_secret
: DELETE SECRET FOR CLIENT ci = CHAR_STRING force_keystore? identified_by_store with_backup_clause?
;
add_update_secret_seps
: (ADD | UPDATE) SECRET s = CHAR_STRING FOR CLIENT ci = CHAR_STRING using_tag_clause? TO LOCAL? AUTO_LOGIN KEYSTORE directory_path
;
delete_secret_seps
: DELETE SECRET s = CHAR_STRING SQ FOR CLIENT ci = CHAR_STRING FROM LOCAL? AUTO_LOGIN KEYSTORE directory_path
;
zero_downtime_software_patching_clauses
: SWITCHOVER TO? LIBRARY path FOR ALL CONTAINERS //inconsistent documentation
;
with_backup_clause
: WITH BACKUP (USING bi = CHAR_STRING)?
;
identified_by_password_clause
: IDENTIFIED BY keystore_password
;
keystore_password
: DELIMITED_ID
;
path
: CHAR_STRING
;
secret
: DELIMITED_ID
;
// https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_4005.htm#SQLRF01105
analyze
: (
ANALYZE (TABLE tableview_name | INDEX index_name) partition_extention_clause?
| ANALYZE CLUSTER cluster_name
) (
validation_clauses
| compute_clauses
| ESTIMATE SYSTEM? STATISTICS for_clause? (SAMPLE UNSIGNED_INTEGER (ROWS | PERCENT_KEYWORD))?
| LIST CHAINED ROWS into_clause1?
| DELETE SYSTEM? STATISTICS)
;
partition_extention_clause
: PARTITION (
'(' partition_name ')'
| FOR '(' partition_key_value (',' partition_key_value)* ')'
)
| SUBPARTITION (
'(' subpartition_name ')'
| FOR '(' subpartition_key_value (',' subpartition_key_value)* ')'
)
;
validation_clauses
: VALIDATE REF UPDATE (SET DANGLING TO NULL_)?
| VALIDATE STRUCTURE (CASCADE FAST | CASCADE online_or_offline? into_clause? | CASCADE)? online_or_offline? into_clause?
;
compute_clauses
: COMPUTE SYSTEM? STATISTICS for_clause?
;
for_clause
: FOR (
TABLE for_clause*
| ALL (INDEXED? COLUMNS (SIZE UNSIGNED_INTEGER)? for_clause* | LOCAL? INDEXES)
| COLUMNS (SIZE UNSIGNED_INTEGER)? (column_name SIZE UNSIGNED_INTEGER)+ for_clause*
)
;
online_or_offline
: OFFLINE
| ONLINE
;
into_clause1
: INTO tableview_name?
;
//Making assumption on partition ad subpartition key value clauses
partition_key_value
: literal
| TIMESTAMP quoted_string
;
subpartition_key_value
: literal
| TIMESTAMP quoted_string
;
//https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_4006.htm#SQLRF01106
associate_statistics
: ASSOCIATE STATISTICS WITH (column_association | function_association) storage_table_clause?
;
column_association
: COLUMNS tableview_name '.' column_name (',' tableview_name '.' column_name)* using_statistics_type
;
function_association
: (
FUNCTIONS function_name (',' function_name)*
| PACKAGES package_name (',' package_name)*
| TYPES type_name (',' type_name)*
| INDEXES index_name (',' index_name)*
| INDEXTYPES indextype_name (',' indextype_name)*
) (
using_statistics_type
| default_cost_clause (',' default_selectivity_clause)?
| default_selectivity_clause (',' default_cost_clause)?
)
;
indextype_name
: id_expression
;
using_statistics_type
: USING (statistics_type_name | NULL_)
;
statistics_type_name
: regular_id
;
default_cost_clause
: DEFAULT COST '(' cpu_cost ',' io_cost ',' network_cost ')'
;
cpu_cost
: UNSIGNED_INTEGER
;
io_cost
: UNSIGNED_INTEGER
;
network_cost
: UNSIGNED_INTEGER
;
default_selectivity_clause
: DEFAULT SELECTIVITY default_selectivity
;
default_selectivity
: UNSIGNED_INTEGER
;
storage_table_clause
: WITH (SYSTEM | USER) MANAGED STORAGE TABLES
;
// https://docs.oracle.com/database/121/SQLRF/statements_4008.htm#SQLRF56110
unified_auditing
: {this.isVersion12()}? AUDIT (
POLICY policy_name ((BY | EXCEPT) audit_user (',' audit_user)*)? (WHENEVER NOT? SUCCESSFUL)?
| CONTEXT NAMESPACE oracle_namespace ATTRIBUTES attribute_name (',' attribute_name)* (
BY audit_user (',' audit_user)*
)?
)
;
policy_name
: identifier
;
// https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_4007.htm#SQLRF01107
// https://docs.oracle.com/database/121/SQLRF/statements_4007.htm#SQLRF01107
audit_traditional
: AUDIT (
audit_operation_clause (auditing_by_clause | IN SESSION CURRENT)?
| audit_schema_object_clause
| NETWORK
| audit_direct_path
) (BY (SESSION | ACCESS))? (WHENEVER NOT? SUCCESSFUL)? audit_container_clause?
;
audit_direct_path
: {this.isVersion12()}? DIRECT_PATH auditing_by_clause
;
audit_container_clause
: {this.isVersion12()}? (CONTAINER EQUALS_OP (CURRENT | ALL))
;
audit_operation_clause
: (
(sql_statement_shortcut | ALL STATEMENTS?) (',' (sql_statement_shortcut | ALL STATEMENTS?))*
| (system_privilege | ALL PRIVILEGES) (',' (system_privilege | ALL PRIVILEGES))*
)
;
auditing_by_clause
: BY audit_user (',' audit_user)*
;
audit_user
: regular_id
;
audit_schema_object_clause
: (sql_operation (',' sql_operation)* | ALL) auditing_on_clause
;
sql_operation
: ALTER
| AUDIT
| COMMENT
| DELETE
| EXECUTE
| FLASHBACK
| GRANT
| INDEX
| INSERT
| LOCK
| READ
| RENAME
| SELECT
| UPDATE
;
auditing_on_clause
: ON (
object_name
| DIRECTORY regular_id
| MINING MODEL model_name
| {this.isVersion12()}? SQL TRANSLATION PROFILE profile_name
| DEFAULT
)
;
model_name
: (id_expression '.')? id_expression
;
object_name
: (id_expression '.')? id_expression
;
profile_name
: (id_expression '.')? id_expression
;
sql_statement_shortcut
: ALTER SYSTEM
| CLUSTER
| CONTEXT
| DATABASE LINK
| DIMENSION
| DIRECTORY
| INDEX
| MATERIALIZED VIEW
| NOT EXISTS
| OUTLINE
| {this.isVersion12()}? PLUGGABLE DATABASE
| PROCEDURE
| PROFILE
| PUBLIC DATABASE LINK
| PUBLIC SYNONYM
| ROLE
| ROLLBACK SEGMENT
| SEQUENCE
| SESSION
| SYNONYM
| SYSTEM AUDIT
| SYSTEM GRANT
| TABLE
| TABLESPACE
| TRIGGER
| TYPE
| USER
| VIEW
| ALTER SEQUENCE
| ALTER TABLE
| COMMENT TABLE
| DELETE TABLE
| EXECUTE PROCEDURE
| GRANT DIRECTORY
| GRANT PROCEDURE
| GRANT SEQUENCE
| GRANT TABLE
| GRANT TYPE
| INSERT TABLE
| LOCK TABLE
| SELECT SEQUENCE
| SELECT TABLE
| UPDATE TABLE
;
drop_index
: DROP INDEX index_name (IF EXISTS)?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DISASSOCIATE-STATISTICS.html
disassociate_statistics
: DISASSOCIATE STATISTICS FROM (
COLUMNS (schema_name '.')? tb = id_expression '.' c = id_expression (
',' (schema_name '.')? tb = id_expression '.' c = id_expression
)*
| FUNCTIONS (schema_name '.')? fn = id_expression (
',' (schema_name '.')? fn = id_expression
)*
| PACKAGES (schema_name '.')? pkg = id_expression (
',' (schema_name '.')? pkg = id_expression
)*
| TYPES (schema_name '.')? t = id_expression (',' (schema_name '.')? t = id_expression)*
| INDEXES (schema_name '.')? ix = id_expression (',' (schema_name '.')? ix = id_expression)*
| INDEXTYPES (schema_name '.')? it = id_expression (
',' (schema_name '.')? it = id_expression
)*
) FORCE?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-INDEXTYPE.html
drop_indextype
: DROP INDEXTYPE (schema_name '.')? it = id_expression FORCE?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-INMEMORY-JOIN-GROUP.html
drop_inmemory_join_group
: DROP INMEMORY JOIN GROUP (schema_name '.')? jg = id_expression
;
flashback_table
: FLASHBACK TABLE tableview_name (',' tableview_name)* TO (
((SCN | TIMESTAMP) expression | RESTORE POINT restore_point) ((ENABLE | DISABLE) TRIGGERS)?
| BEFORE DROP (RENAME TO tableview_name)?
)
;
restore_point
: identifier ('.' id_expression)*
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/PURGE.html
purge_statement
: PURGE (
(TABLE | INDEX) id_expression
| TABLESPACE SET? ts = id_expression (USER u = id_expression)?
| RECYCLEBIN
| DBA_RECYCLEBIN
)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/NOAUDIT-Traditional-Auditing.html
noaudit_statement
: NOAUDIT (
audit_operation_clause auditing_by_clause?
| audit_schema_object_clause
| NETWORK
| DIRECT_PATH LOAD auditing_by_clause?
) (WHENEVER NOT? SUCCESSFUL)? container_clause?
;
rename_object
: RENAME object_name TO object_name
;
grant_statement
: GRANT (','? (role_name | system_privilege | object_privilege paren_column_list?))+ (
ON grant_object_name
)? TO (grantee_name | PUBLIC) (',' (grantee_name | PUBLIC))* (WITH (ADMIN | DELEGATE) OPTION)? (
WITH HIERARCHY OPTION
)? (WITH GRANT OPTION)? container_clause?
;
container_clause
: CONTAINER EQUALS_OP (CURRENT | ALL)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/REVOKE.html
revoke_statement
: REVOKE (
(revoke_system_privilege | revoke_object_privileges) container_clause?
| revoke_roles_from_programs
)
;
revoke_system_privilege
: (system_privilege | role_name | ALL PRIVILEGES) FROM revokee_clause
;
revokee_clause
: (id_expression | PUBLIC) (',' (id_expression | PUBLIC))*
;
revoke_object_privileges
: (object_privilege | ALL PRIVILEGES?) (',' (object_privilege | ALL PRIVILEGES?))* on_object_clause FROM revokee_clause (
CASCADE CONSTRAINTS
| FORCE
)?
;
on_object_clause
: ON (
(schema_name '.')? o = id_expression
| USER id_expression (',' id_expression)*
| DIRECTORY directory_name
| EDITION edition_name
| MINING MODEL (schema_name '.')? mmn = id_expression
| JAVA (SOURCE | RESOURCE) (schema_name '.')? o2 = id_expression
| SQL TRANSLATION PROFILE (schema_name '.')? p = id_expression
)
;
revoke_roles_from_programs
: (role_name (',' role_name)* | ALL) FROM program_unit (',' program_unit)*
;
program_unit
: (FUNCTION | PROCEDURE | PACKAGE) (schema_name '.')? id_expression
;
create_dimension
: CREATE DIMENSION identifier level_clause+ (
hierarchy_clause
| attribute_clause
| extended_attribute_clause
)+
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-DIRECTORY.html
create_directory
: CREATE (OR REPLACE)? DIRECTORY directory_name (SHARING '=' (METADATA | NONE))? AS directory_path
;
directory_name
: regular_id
;
directory_path
: CHAR_STRING
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-INMEMORY-JOIN-GROUP.html
create_inmemory_join_group
: CREATE INMEMORY JOIN GROUP (schema_name '.')? jg = id_expression '(' (schema_name '.')? t = id_expression '(' c = id_expression ')' (
',' (schema_name '.')? t = id_expression '(' c = id_expression ')'
)+ ')'
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-HIERARCHY.html
drop_hierarchy
: DROP HIERARCHY (schema_name '.')? hn = id_expression
;
// https://docs.oracle.com/cd/E11882_01/appdev.112/e25519/alter_library.htm#LNPLS99946
// https://docs.oracle.com/database/121/LNPLS/alter_library.htm#LNPLS99946
alter_library
: ALTER LIBRARY library_name (
COMPILE library_debug? compiler_parameters_clause* (REUSE SETTINGS)?
| library_editionable
)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-JAVA.html
drop_java
: DROP JAVA (SOURCE | CLASS | RESOURCE) (schema_name '.')? id_expression
;
drop_library
: DROP LIBRARY library_name
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-JAVA.html
create_java
: CREATE (OR REPLACE)? (AND (RESOLVE | COMPILE))? NOFORCE? JAVA (
(SOURCE | RESOURCE) NAMED (schema_name '.')? pn = id_expression
| CLASS (SCHEMA id_expression)?
) (SHARING '=' (METADATA | NONE))? invoker_rights_clause? (
RESOLVER '(' ('(' CHAR_STRING ','? (sn = id_expression | '-') ')')+ ')'
)? (
USING (
BFILE '(' d = id_expression ',' filename ')'
| (CLOB | BLOB | BFILE) subquery
| CHAR_STRING
)
| AS CHAR_STRING
)
;
create_library
: CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? LIBRARY plsql_library_source
;
plsql_library_source
: library_name (IS | AS) quoted_string (IN directory_name)? (AGENT quoted_string)? (
CREDENTIAL credential_name
)?
;
credential_name
: (id_expression '.')? id_expression
;
library_editionable
: {this.isVersion12()}? (EDITIONABLE | NONEDITIONABLE)
;
library_debug
: {this.isVersion12()}? DEBUG
;
compiler_parameters_clause
: parameter_name EQUALS_OP parameter_value
;
parameter_value
: regular_id
| CHAR_STRING
;
library_name
: (regular_id '.')? regular_id
;
alter_dimension
: ALTER DIMENSION identifier (
(ADD (level_clause | hierarchy_clause | attribute_clause | extended_attribute_clause))+
| (
DROP (
LEVEL identifier (RESTRICT | CASCADE)?
| HIERARCHY identifier
| ATTRIBUTE identifier (
LEVEL identifier (COLUMN column_name (',' COLUMN column_name)*)?
)?
)
)+
| COMPILE
)
;
level_clause
: LEVEL identifier IS (
table_name '.' column_name
| '(' table_name '.' column_name (',' table_name '.' column_name)* ')'
) (SKIP_ WHEN NULL_)?
;
hierarchy_clause
: HIERARCHY identifier '(' identifier (CHILD OF identifier)+ dimension_join_clause? ')'
;
dimension_join_clause
: (JOIN KEY column_one_or_more_sub_clause REFERENCES identifier)+
;
attribute_clause
: (ATTRIBUTE identifier DETERMINES column_one_or_more_sub_clause)+
;
extended_attribute_clause
: ATTRIBUTE identifier (LEVEL identifier DETERMINES column_one_or_more_sub_clause)+
;
column_one_or_more_sub_clause
: column_name
| '(' column_name (',' column_name)* ')'
;
// https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_4004.htm#SQLRF01104
// https://docs.oracle.com/database/121/SQLRF/statements_4004.htm#SQLRF01104
alter_view
: ALTER VIEW tableview_name (
ADD out_of_line_constraint
| MODIFY CONSTRAINT constraint_name (RELY | NORELY)
| DROP (
CONSTRAINT constraint_name
| PRIMARY KEY
| UNIQUE '(' column_name (',' column_name)* ')'
)
| COMPILE
| READ (ONLY | WRITE)
| alter_view_editionable?
)
;
alter_view_editionable
: {this.isVersion12()}? (EDITIONABLE | NONEDITIONABLE)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-VIEW.html
create_view
: CREATE (OR REPLACE)? (NO? FORCE)? editioning_clause? VIEW (schema_name '.')? v = id_expression (
IF NOT EXISTS
)? (SHARING '=' (METADATA | EXTENDED? DATA | NONE))? view_options? (
DEFAULT COLLATION cn = id_expression
)? (BEQUEATH (CURRENT_USER | DEFINER))? AS select_only_statement subquery_restriction_clause? (
CONTAINER_MAP
| CONTAINERS_DEFAULT
)?
;
editioning_clause
: EDITIONING
| EDITIONABLE EDITIONING?
| NONEDITIONABLE
;
view_options
: view_alias_constraint
| object_view_clause
| xmltype_view_clause
;
view_alias_constraint
: '(' (','? (table_alias inline_constraint* | out_of_line_constraint))+ ')'
;
object_view_clause
: OF (schema_name '.')? tn = id_expression (
WITH OBJECT (IDENTIFIER | ID) (DEFAULT | '(' REGULAR_ID (',' REGULAR_ID)* ')')
| UNDER (schema_name '.')? sv = id_expression
) ('(' (','? (out_of_line_constraint | REGULAR_ID inline_constraint))+ ')')*
;
inline_constraint
: (CONSTRAINT constraint_name)? (
NOT? NULL_
| UNIQUE
| PRIMARY KEY
| references_clause
| check_constraint
) constraint_state?
;
inline_ref_constraint
: SCOPE IS tableview_name
| WITH ROWID
| (CONSTRAINT constraint_name)? references_clause constraint_state?
;
out_of_line_ref_constraint
: SCOPE FOR '(' ref_col_or_attr = regular_id ')' IS tableview_name
| REF '(' ref_col_or_attr = regular_id ')' WITH ROWID
| (CONSTRAINT constraint_name)? FOREIGN KEY '(' (','? ref_col_or_attr = regular_id)+ ')' references_clause constraint_state?
;
out_of_line_constraint
: (
((CONSTRAINT | CONSTRAINTS) constraint_name)? (
UNIQUE '(' column_name (',' column_name)* ')'
| PRIMARY KEY '(' column_name (',' column_name)* ')'
| foreign_key_clause
| CHECK '(' condition ')'
)
)
constraint_state?
parallel_clause?
;
constraint_state
: (
NOT? DEFERRABLE
| INITIALLY (IMMEDIATE | DEFERRED)
| (RELY | NORELY)
| (ENABLE | DISABLE)
| (VALIDATE | NOVALIDATE)
| using_index_clause
)+
;
xmltype_view_clause
: OF XMLTYPE xml_schema_spec? WITH OBJECT (IDENTIFIER | ID) (
DEFAULT
| '(' expression (',' expression)* ')'
)
;
xml_schema_spec
: (XMLSCHEMA xml_schema_url)? ELEMENT (element | xml_schema_url '#' element) (
STORE ALL VARRAYS AS (LOBS | TABLES)
)? (allow_or_disallow NONSCHEMA)? (allow_or_disallow ANYSCHEMA)?
;
xml_schema_url
: DELIMITED_ID
;
element
: DELIMITED_ID
;
alter_tablespace
: ALTER TABLESPACE tablespace (
DEFAULT table_compression? storage_clause?
| MINIMUM EXTENT size_clause
| RESIZE size_clause
| COALESCE
| SHRINK SPACE_KEYWORD (KEEP size_clause)?
| RENAME TO new_tablespace_name
| begin_or_end BACKUP
| datafile_tempfile_clauses
| tablespace_logging_clauses
| tablespace_group_clause
| tablespace_state_clauses
| autoextend_clause
| flashback_mode_clause
| tablespace_retention_clause
)
;
datafile_tempfile_clauses
: ADD (datafile_specification | tempfile_specification)
| DROP (DATAFILE | TEMPFILE) (filename | UNSIGNED_INTEGER) (KEEP size_clause)?
| SHRINK TEMPFILE (filename | UNSIGNED_INTEGER) (KEEP size_clause)?
| RENAME DATAFILE filename (',' filename)* TO filename (',' filename)*
| (DATAFILE | TEMPFILE) (online_or_offline)
;
tablespace_logging_clauses
: logging_clause
| NO? FORCE LOGGING
;
tablespace_group_clause
: TABLESPACE GROUP (tablespace_group_name | CHAR_STRING)
;
tablespace_group_name
: regular_id
;
tablespace_state_clauses
: ONLINE
| OFFLINE (NORMAL | TEMPORARY | IMMEDIATE)?
| READ (ONLY | WRITE)
| PERMANENT
| TEMPORARY
;
flashback_mode_clause
: FLASHBACK (ON | OFF)
;
new_tablespace_name
: tablespace
;
create_tablespace
: CREATE (BIGFILE | SMALLFILE)? (
permanent_tablespace_clause
| temporary_tablespace_clause
| undo_tablespace_clause
)
;
permanent_tablespace_clause
: TABLESPACE id_expression (IF NOT EXISTS)? datafile_specification? (
MINIMUM EXTENT size_clause
| BLOCKSIZE size_clause
| logging_clause
| FORCE LOGGING
| (ONLINE | OFFLINE)
| ENCRYPTION tablespace_encryption_spec
| DEFAULT //TODO table_compression? storage_clause?
| extent_management_clause
| segment_management_clause
| flashback_mode_clause
)*
;
tablespace_encryption_spec
: USING encrypt_algorithm = CHAR_STRING
;
logging_clause
: LOGGING
| NOLOGGING
| FILESYSTEM_LIKE_LOGGING
;
extent_management_clause
: EXTENT MANAGEMENT LOCAL (AUTOALLOCATE | UNIFORM (SIZE size_clause)?)?
;
segment_management_clause
: SEGMENT SPACE_KEYWORD MANAGEMENT (AUTO | MANUAL)
;
temporary_tablespace_clause
: TEMPORARY TABLESPACE tablespace_name = id_expression (IF NOT EXISTS)? tempfile_specification? tablespace_group_clause? extent_management_clause?
;
undo_tablespace_clause
: UNDO TABLESPACE tablespace_name = id_expression (IF NOT EXISTS)? datafile_specification? extent_management_clause? tablespace_retention_clause?
;
tablespace_retention_clause
: RETENTION (GUARANTEE | NOGUARANTEE)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-TABLESPACE-SET.html
create_tablespace_set
: CREATE TABLESPACE SET tss = id_expression (IN SHARDSPACE ss = id_expression)? (
USING TEMPLATE '(' (DATAFILE file_specification (',' file_specification)*)? permanent_tablespace_attrs+ ')'
)?
;
permanent_tablespace_attrs
: MINIMUM EXTENT size_clause
| BLOCKSIZE numeric K_LETTER?
| logging_clause
| FORCE LOGGING
| tablespace_encryption_clause
| default_tablespace_params
| ONLINE
| OFFLINE
| extent_management_clause
| segment_management_clause
| flashback_mode_clause
| lost_write_protection
;
tablespace_encryption_clause
: ENCRYPTION (tablespace_encryption_spec? ENCRYPT | DECRYPT)
;
default_tablespace_params
: DEFAULT default_table_compression? default_index_compression? inmmemory_clause? ilm_clause? storage_clause?
;
default_table_compression
: TABLE (COMPRESS FOR (OLTP | QUERY low_high | ARCHIVE low_high) | NOCOMPRESS)
;
low_high
: LOW
| HIGH
;
default_index_compression
: INDEX (COMPRESS ADVANCED low_high | NOCOMPRESS)
;
inmmemory_clause
: INMEMORY inmemory_attributes? (
TEXT (
column_name (',' column_name)*
| column_name USING policy_name (',' column_name USING policy_name)*
)
)?
| NO INMEMORY
;
// asm_filename is just a charater string. Would need to parse the string
// to find diskgroup...
datafile_specification
: DATAFILE (','? datafile_tempfile_spec)
;
tempfile_specification
: TEMPFILE (','? datafile_tempfile_spec)
;
datafile_tempfile_spec
: CHAR_STRING? (SIZE size_clause)? REUSE? autoextend_clause?
;
redo_log_file_spec
: (filename | '(' filename (',' filename)* ')') (SIZE size_clause)? (BLOCKSIZE size_clause)? REUSE?
;
autoextend_clause
: AUTOEXTEND (OFF | ON (NEXT size_clause)? maxsize_clause?)
;
maxsize_clause
: MAXSIZE (UNLIMITED | size_clause)
;
build_clause
: BUILD (IMMEDIATE | DEFERRED)
;
parallel_clause
: NOPARALLEL
| PARALLEL (
parallel_count = UNSIGNED_INTEGER parallel_instances_clause?
// Deprecated, legacy format from Oracle 8 and prior, and while this is no longer documented,
// the DEGREE syntax continues to be accepted by the database engine.
| '(' DEGREE parallel_count = UNSIGNED_INTEGER parallel_instances_clause? ')'
)?
;
// This is Oracle RAC specific.
// In modern Oracle, parallelism is controlled by the database initialization parameter PARALLEL_DEGREE_POLICY,
// however, the database continues to accept and record this SQL syntax if its used.
parallel_instances_clause
: INSTANCES (UNSIGNED_INTEGER | DEFAULT)
;
alter_materialized_view
: ALTER MATERIALIZED VIEW tableview_name (
physical_attributes_clause
| modify_mv_column_clause
| table_compression
| lob_storage_clause (',' lob_storage_clause)*
| modify_lob_storage_clause (',' modify_lob_storage_clause)*
//TODO | alter_table_partitioning
| parallel_clause
| logging_clause
| allocate_extent_clause
| deallocate_unused_clause
| shrink_clause
| (cache_or_nocache)
)? alter_iot_clauses? (USING INDEX physical_attributes_clause)? alter_mv_option1? (
enable_or_disable QUERY REWRITE
| COMPILE
| CONSIDER FRESH
)?
;
alter_mv_option1
: alter_mv_refresh
//TODO | MODIFY scoped_table_ref_constraint
;
alter_mv_refresh
: REFRESH (
FAST
| COMPLETE
| FORCE
| ON (DEMAND | COMMIT)
| START WITH expression
| NEXT expression
| WITH PRIMARY KEY
| USING DEFAULT? MASTER ROLLBACK SEGMENT rollback_segment?
| USING (ENFORCED | TRUSTED) CONSTRAINTS
)+
;
rollback_segment
: regular_id
;
modify_mv_column_clause
: MODIFY '(' column_name (ENCRYPT encryption_spec | DECRYPT)? ')'
;
alter_materialized_view_log
: ALTER MATERIALIZED VIEW LOG FORCE? ON tableview_name (
physical_attributes_clause
| add_mv_log_column_clause
//TODO | alter_table_partitioning
| parallel_clause
| logging_clause
| allocate_extent_clause
| shrink_clause
| move_mv_log_clause
| cache_or_nocache
)? mv_log_augmentation? mv_log_purge_clause?
;
add_mv_log_column_clause
: ADD '(' column_name ')'
;
move_mv_log_clause
: MOVE segment_attributes_clause parallel_clause?
;
mv_log_augmentation
: ADD (
(OBJECT ID | PRIMARY KEY | ROWID | SEQUENCE) ('(' column_name (',' column_name)* ')')?
| '(' column_name (',' column_name)* ')'
) new_values_clause?
;
create_materialized_view_log
: CREATE MATERIALIZED VIEW LOG ON tableview_name (
(
physical_attributes_clause
| TABLESPACE tablespace_name = id_expression
| logging_clause
| (CACHE | NOCACHE)
)+
)? parallel_clause?
// table_partitioning_clauses TODO
(
WITH (','? ( OBJECT ID | PRIMARY KEY | ROWID | SEQUENCE | COMMIT SCN))* (
'(' ( ','? regular_id)+ ')' new_values_clause?
)? mv_log_purge_clause?
)*
;
new_values_clause
: (INCLUDING | EXCLUDING) NEW VALUES
;
mv_log_purge_clause
: PURGE (
IMMEDIATE (SYNCHRONOUS | ASYNCHRONOUS)?
// |START WITH CLAUSES TODO
)
;
create_materialized_zonemap
: CREATE MATERIALIZED ZONEMAP zonemap_name (LEFT_PAREN column_list RIGHT_PAREN)? zonemap_attributes? zonemap_refresh_clause? (
(ENABLE | DISABLE) PRUNING
)? (create_zonemap_on_table | create_zonemap_as_subquery)
;
alter_materialized_zonemap
: ALTER MATERIALIZED ZONEMAP zonemap_name (
zonemap_attributes
| zonemap_refresh_clause
| (ENABLE | DISABLE) PRUNING
| COMPILE
| REBUILD
| UNUSABLE
)
;
drop_materialized_zonemap
: DROP MATERIALIZED ZONEMAP zonemap_name
;
zonemap_refresh_clause
: REFRESH (FAST | COMPILE | FORCE)? (
ON (DEMAND | COMMIT | LOAD | DATA MOVEMENT | LOAD DATA MOVEMENT)
)?
;
zonemap_attributes
: (
PCTFREE numeric
| PCTUSED numeric
| SCALE numeric
| TABLESPACE tablespace
| (CACHE | NOCACHE)
)+
;
zonemap_name
: identifier ('.' id_expression)?
;
operator_name
: identifier ('.' id_expression)?
;
operator_function_name
: identifier ('.' id_expression)*
;
create_zonemap_on_table
: ON tableview_name LEFT_PAREN column_list RIGHT_PAREN
;
create_zonemap_as_subquery
: AS subquery
;
alter_operator
: ALTER OPERATOR operator_name (add_binding_clause | drop_binding_clause | COMPILE)
;
drop_operator
: DROP OPERATOR operator_name FORCE?
;
create_operator
: CREATE (OR REPLACE)? OPERATOR operator_name BINDING binding_clause (COMMA binding_clause)* (
SHARING '=' (METADATA | NONE)
)?
;
binding_clause
: LEFT_PAREN datatype (COMMA datatype)* RIGHT_PAREN RETURN LEFT_PAREN? datatype RIGHT_PAREN? implementation_clause? using_function_clause
;
add_binding_clause
: ADD BINDING binding_clause
;
implementation_clause
: ANCILLARY TO primary_operator_list
| operator_context_clause
;
primary_operator_list
: primary_operator_item (COMMA primary_operator_item)*
;
primary_operator_item
: schema_object_name LEFT_PAREN datatype (COMMA datatype)* RIGHT_PAREN
;
operator_context_clause
: WITH INDEX CONTEXT COMMA SCAN CONTEXT implementation_type_name (COMPUTE ANCILLARY DATA)? (
WITH COLUMN CONTEXT
)?
;
using_function_clause
: USING operator_function_name
;
drop_binding_clause
: DROP BINDING LEFT_PAREN datatype (COMMA datatype)* RIGHT_PAREN FORCE?
;
create_materialized_view
: CREATE MATERIALIZED VIEW tableview_name (OF type_name)? (
'(' (scoped_table_ref_constraint | mv_column_alias) (
',' (scoped_table_ref_constraint | mv_column_alias)
)* ')'
)? (
ON PREBUILT TABLE ( (WITH | WITHOUT) REDUCED PRECISION)?
| physical_properties? (CACHE | NOCACHE)? parallel_clause? build_clause?
) (
USING INDEX ((physical_attributes_clause | TABLESPACE mv_tablespace = id_expression)+)*
| USING NO INDEX
)? create_mv_refresh? (FOR UPDATE)? ((DISABLE | ENABLE) QUERY REWRITE)? AS select_only_statement
;
scoped_table_ref_constraint
: SCOPE FOR '(' ref_column_or_attribute = identifier ')' IS (schema_name '.')? scope_table_name_or_c_alias = identifier
;
mv_column_alias
: (identifier | quoted_string) (ENCRYPT encryption_spec)?
;
create_mv_refresh
: (
NEVER REFRESH
| REFRESH (
(FAST | COMPLETE | FORCE)
| ON (DEMAND | COMMIT)
| (START WITH | NEXT) //date goes here TODO
| WITH (PRIMARY KEY | ROWID)
| USING (
DEFAULT (MASTER | LOCAL)? ROLLBACK SEGMENT
| (MASTER | LOCAL)? ROLLBACK SEGMENT rb_segment = REGULAR_ID
)
| USING (ENFORCED | TRUSTED) CONSTRAINTS
)+
)
;
drop_materialized_view
: DROP MATERIALIZED VIEW tableview_name (PRESERVE TABLE)?
;
drop_materialized_view_log
: DROP MATERIALIZED VIEW LOG (IF EXISTS)? ON tableview_name
;
create_context
: CREATE (OR REPLACE)? CONTEXT oracle_namespace USING (schema_object_name '.')? package_name (
INITIALIZED (EXTERNALLY | GLOBALLY)
| ACCESSED GLOBALLY
)?
;
oracle_namespace
: id_expression
;
//https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_5001.htm#SQLRF01201
create_cluster
: CREATE CLUSTER cluster_name '(' column_name datatype SORT? (',' column_name datatype SORT?)* ')' (
physical_attributes_clause
| SIZE size_clause
| TABLESPACE tablespace
| INDEX
| (SINGLE TABLE)? HASHKEYS UNSIGNED_INTEGER (HASH IS expression)?
)* parallel_clause? (ROWDEPENDENCIES | NOROWDEPENDENCIES)? (CACHE | NOCACHE)?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-PROFILE.html
create_profile
: CREATE MANDATORY? PROFILE p = id_expression LIMIT (resource_parameters | password_parameters)+ container_clause?
;
resource_parameters
: (
SESSIONS_PER_USER
| CPU_PER_SESSION
| CPU_PER_CALL
| CONNECT_TIME
| IDLE_TIME
| LOGICAL_READS_PER_SESSION
| LOGICAL_READS_PER_CALL
| COMPOSITE_LIMIT
) (UNSIGNED_INTEGER | UNLIMITED | DEFAULT)
| PRIVATE_SGA (size_clause | UNLIMITED | DEFAULT)
;
password_parameters
: (
FAILED_LOGIN_ATTEMPTS
| PASSWORD_LIFE_TIME
| PASSWORD_REUSE_TIME
| PASSWORD_REUSE_MAX
| PASSWORD_LOCK_TIME
| PASSWORD_GRACE_TIME
| INACTIVE_ACCOUNT_TIME
) (expression | UNLIMITED | DEFAULT)
| PASSWORD_VERIFY_FUNCTION (function_name | NULL_ | DEFAULT)
| PASSWORD_ROLLOVER_TIME (expression | DEFAULT)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-LOCKDOWN-PROFILE.html
create_lockdown_profile
: CREATE LOCKDOWN PROFILE id_expression (static_base_profile | dynamic_base_profile)?
;
static_base_profile
: FROM bp = id_expression
;
dynamic_base_profile
: INCLUDING bp = id_expression
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-OUTLINE.html
create_outline
: CREATE (OR REPLACE)? (PUBLIC | PRIVATE)? OUTLINE (o = id_expression)? (
FROM (PUBLIC | PRIVATE)? so = id_expression
)? (FOR CATEGORY c = id_expression)? (ON statement)?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-RESTORE-POINT.html
create_restore_point
: CREATE CLEAN? RESTORE POINT rp = id_expression (FOR PLUGGABLE DATABASE pdb = id_expression)? (
AS OF (TIMESTAMP | SCN) expression
)? (PRESERVE | GUARANTEE FLASHBACK DATABASE)?
;
create_role
: CREATE ROLE role_name role_identified_clause? container_clause?
;
create_table
: CREATE (
(GLOBAL | PRIVATE) TEMPORARY
| SHARDED
| DUPLICATED
| IMMUTABLE? BLOCKCHAIN
| IMMUTABLE
)? TABLE (schema_name '.')? table_name (IF NOT EXISTS)? (
SHARING '=' (METADATA | EXTENDED? DATA | NONE)
)? (relational_table | xmltype_table | object_table) memoptimize_read_write_clause? (
PARENT tableview_name
)? (USAGE QUEUE)?
;
xmltype_table
: OF XMLTYPE ('(' object_properties ')')? (XMLTYPE xmltype_storage)? xmlschema_spec? xmltype_virtual_columns? (
ON COMMIT (DELETE | PRESERVE) ROWS
)? oid_clause? oid_index_clause? physical_properties? table_properties?
;
xmltype_virtual_columns
: VIRTUAL COLUMNS '(' column_name AS '(' expression ')' (',' column_name AS '(' expression ')')* ')'
;
xmltype_column_properties
: XMLTYPE COLUMN? column_name xmltype_storage? xmlschema_spec?
;
xmltype_storage
: STORE AS (
OBJECT RELATIONAL
| (SECUREFILE | BASICFILE)? (CLOB | BINARY XML) (
lob_segname ('(' lob_parameters ')')?
| '(' lob_parameters ')'
)?
)
| STORE VARRAYS AS (LOBS | TABLES)
;
xmlschema_spec
: (XMLSCHEMA DELIMITED_ID)? ELEMENT DELIMITED_ID (allow_or_disallow NONSCHEMA)? (
allow_or_disallow ANYSCHEMA
)?
;
object_table
: OF (schema_name '.')? object_type object_table_substitution? (
'(' object_properties (',' object_properties)* ')'
)? (ON COMMIT (DELETE | PRESERVE) ROWS)? oid_clause? oid_index_clause? physical_properties? table_properties?
;
object_type
: regular_id
;
oid_index_clause
: OIDINDEX index_name? '(' (physical_attributes_clause | TABLESPACE tablespace)+ ')'
;
oid_clause
: OBJECT IDENTIFIER IS (SYSTEM GENERATED | PRIMARY KEY)
;
object_properties
: (column_name | attribute_name) (DEFAULT expression)? (
inline_constraint (',' inline_constraint)*
| inline_ref_constraint
)?
| out_of_line_constraint
| out_of_line_ref_constraint
| supplemental_logging_props
;
object_table_substitution
: NOT? SUBSTITUTABLE AT ALL LEVELS
;
relational_table
: ('(' relational_property (',' relational_property)* ')')? relational_table_properties?
;
relational_table_properties
: relational_table_property+
;
relational_table_property
: immutable_table_clauses
| blockchain_table_clauses
| DEFAULT COLLATION collation_name
| ON COMMIT ((DROP | PRESERVE) DEFINITION | (DELETE | PRESERVE) ROWS)
| physical_properties
| table_properties
;
immutable_table_clauses
: immutable_table_no_drop_clause
| immutable_table_no_delete_clause
;
immutable_table_no_drop_clause
: NO DROP (UNTIL numeric DAYS IDLE)?
;
immutable_table_no_delete_clause
: NO DELETE (LOCKED? | UNTIL numeric DAYS AFTER INSERT LOCKED?)
;
blockchain_table_clauses
: blockchain_drop_table_clause blockchain_row_retention_clause blockchain_hash_and_data_format_clause
;
blockchain_drop_table_clause
: NO DROP (UNTIL numeric DAYS IDLE)?
;
blockchain_row_retention_clause
: NO DELETE (LOCKED? | UNTIL numeric DAYS AFTER INSERT LOCKED?)
;
blockchain_hash_and_data_format_clause
: HASHING USING SHA2_512_Q VERSION V1_Q
;
collation_name
: identifier
;
// While Oracle's documented grammar defines an explicit order of clauses, in practice these clauses can
// be specified in any order. This rule is designed to follow the grammar intent, and so semantic checks
// should exist in the listeners to deal with concepts such as duplicates.
table_properties
: column_properties
| read_only_clause
| indexing_clause
| table_partitioning_clauses
| attribute_clustering_clause
| (CACHE | NOCACHE)
| result_cache_clause
| parallel_clause
| monitoring_nomonitoring
| (ROWDEPENDENCIES | NOROWDEPENDENCIES)
| enable_disable_clause
| row_movement_clause
| logical_replication_clause
| flashback_archive_clause
| physical_properties
| ROW ARCHIVAL
| AS select_only_statement
| FOR EXCHANGE WITH TABLE (schema_name '.')? table_name
| annotations_clause
;
read_only_clause
: READ (ONLY | WRITE)
;
indexing_clause
: INDEXING (ON | OFF)
;
attribute_clustering_clause
: CLUSTERING clustering_join? cluster_clause (yes_no? ON LOAD)? (yes_no? ON DATA MOVEMENT)? zonemap_clause?
;
clustering_join
: (schema_name '.')? table_name clustering_join_item (',' clustering_join_item)*
;
clustering_join_item
: JOIN (schema_name '.')? table_name ON '(' equijoin_condition ')'
;
equijoin_condition
: expression
;
cluster_clause
: BY (LINEAR | INTERLEAVED)? ORDER clustering_columns
;
clustering_columns
: clustering_column_group
| '(' clustering_column_group (',' clustering_column_group)* ')'
;
clustering_column_group
: '(' column_name (',' column_name)* ')'
;
yes_no
: YES
| NO
;
zonemap_clause
: WITH MATERIALIZED ZONEMAP ('(' zonemap_name ')')?
| WITHOUT MATERIALIZED ZONEMAP
;
logical_replication_clause
: DISABLE LOGICAL REPLICATION
| ENABLE LOGICAL REPLICATION (
(ALL | ALLOW NOVALIDATE) KEYS
| NO? PARTIAL JSON
)?
;
table_name
: identifier
;
relational_property
: out_of_line_constraint
| out_of_line_ref_constraint
| column_definition
| virtual_column_definition
| period_definition
| supplemental_logging_props
;
table_partitioning_clauses
: range_partitions
| list_partitions
| hash_partitions
| composite_range_partitions
| composite_list_partitions
| composite_hash_partitions
| reference_partitioning
| system_partitioning
;
range_partitions
: PARTITION BY RANGE '(' column_name (',' column_name)* ')' (
INTERVAL '(' expression ')' (STORE IN '(' tablespace (',' tablespace)* ')')?
)? '(' PARTITION partition_name? range_values_clause table_partition_description (
',' PARTITION partition_name? range_values_clause table_partition_description
)* ')'
;
list_partitions
: PARTITION BY LIST '(' column_name ')' (
AUTOMATIC (STORE IN '(' tablespace (',' tablespace)* ')')?
)? (
'(' PARTITION partition_name? list_values_clause table_partition_description (
',' PARTITION partition_name? list_values_clause table_partition_description
)* ')'
)?
;
hash_partitions
: PARTITION BY HASH '(' column_name (',' column_name)* ')' (
individual_hash_partitions
| hash_partitions_by_quantity
)
;
individual_hash_partitions
: '(' PARTITION partition_name? partitioning_storage_clause? (
',' PARTITION partition_name? partitioning_storage_clause?
)* ')'
;
hash_partitions_by_quantity
: PARTITIONS hash_partition_quantity (STORE IN '(' tablespace (',' tablespace)* ')')? (
table_compression
| key_compression
)? (OVERFLOW_ STORE IN '(' tablespace (',' tablespace)* ')')?
;
hash_partition_quantity
: UNSIGNED_INTEGER
;
composite_range_partitions
: PARTITION BY RANGE '(' column_name (',' column_name)* ')' (
INTERVAL '(' expression ')' (STORE IN '(' tablespace (',' tablespace)* ')')?
)? (subpartition_by_range | subpartition_by_list | subpartition_by_hash) '(' range_partition_desc (
',' range_partition_desc
)* ')'
;
composite_list_partitions
: PARTITION BY LIST '(' column_name ')' (
subpartition_by_range
| subpartition_by_list
| subpartition_by_hash
) '(' list_partition_desc (',' list_partition_desc)* ')'
;
composite_hash_partitions
: PARTITION BY HASH '(' (',' column_name)+ ')' (
subpartition_by_range
| subpartition_by_list
| subpartition_by_hash
) (individual_hash_partitions | hash_partitions_by_quantity)
;
reference_partitioning
: PARTITION BY REFERENCE '(' constraint_name ')' (
'(' reference_partition_desc (',' reference_partition_desc)* ')'
)?
;
reference_partition_desc
: PARTITION partition_name? table_partition_description
;
system_partitioning
: PARTITION BY SYSTEM (
PARTITIONS UNSIGNED_INTEGER
| reference_partition_desc (',' reference_partition_desc)*
)?
;
range_partition_desc
: PARTITION partition_name? range_values_clause? table_partition_description (
(
'(' (
range_subpartition_desc (',' range_subpartition_desc)*
| list_subpartition_desc (',' list_subpartition_desc)*
| individual_hash_subparts (',' individual_hash_subparts)*
) ')'
| hash_subparts_by_quantity
)
)?
;
list_partition_desc
: PARTITION partition_name? list_values_clause? table_partition_description (
(
'(' (
range_subpartition_desc (',' range_subpartition_desc)*
| list_subpartition_desc (',' list_subpartition_desc)*
| individual_hash_subparts (',' individual_hash_subparts)*
) ')'
| hash_subparts_by_quantity
)
)?
;
subpartition_template
: SUBPARTITION TEMPLATE (
(
'(' (
range_subpartition_desc (',' range_subpartition_desc)*
| list_subpartition_desc (',' list_subpartition_desc)*
| individual_hash_subparts (',' individual_hash_subparts)*
) ')'
| hash_subpartition_quantity
)
)
;
hash_subpartition_quantity
: UNSIGNED_INTEGER
;
subpartition_by_range
: SUBPARTITION BY RANGE '(' column_name (',' column_name)* ')' subpartition_template?
;
subpartition_by_list
: SUBPARTITION BY LIST '(' column_name ')' subpartition_template?
;
subpartition_by_hash
: SUBPARTITION BY HASH '(' column_name (',' column_name)* ')' (
SUBPARTITIONS UNSIGNED_INTEGER (STORE IN '(' tablespace (',' tablespace)* ')')?
| subpartition_template
)?
;
subpartition_name
: partition_name
;
range_subpartition_desc
: SUBPARTITION subpartition_name? range_values_clause partitioning_storage_clause?
;
list_subpartition_desc
: SUBPARTITION subpartition_name? list_values_clause partitioning_storage_clause?
;
individual_hash_subparts
: SUBPARTITION subpartition_name? partitioning_storage_clause?
;
hash_subparts_by_quantity
: SUBPARTITIONS UNSIGNED_INTEGER (STORE IN '(' tablespace (',' tablespace)* ')')?
;
range_values_clause
: VALUES LESS THAN '(' range_values_list ')'
;
range_values_list
: literal (',' literal)*
| TIMESTAMP literal (',' TIMESTAMP literal)*
;
list_values_clause
: VALUES '(' (literal (',' literal)* | TIMESTAMP literal (',' TIMESTAMP literal)* | DEFAULT) ')'
;
table_partition_description
: (INTERNAL | EXTERNAL)? deferred_segment_creation? read_only_clause? indexing_clause? segment_attributes_clause? (
table_compression
| key_compression
)? inmemory_table_clause? ilm_clause? (
OVERFLOW_ segment_attributes_clause?
)? (lob_storage_clause | varray_col_properties | nested_table_col_properties)*
;
partitioning_storage_clause
: (
TABLESPACE tablespace
| OVERFLOW_ (TABLESPACE tablespace)?
| table_compression
| key_compression
| inmemory_table_clause
| lob_partitioning_storage
| VARRAY varray_item STORE AS (BASICFILE | SECUREFILE)? LOB lob_segname
)+
;
lob_partitioning_storage
: LOB '(' lob_item ')' STORE AS (BASICFILE | SECUREFILE)? (
lob_segname ('(' TABLESPACE tablespace ')')?
| '(' TABLESPACE tablespace ')'
)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/size_clause.html
// Technically, this should only allow 'K' | 'M' | 'G' | 'T' | 'P' | 'E'
// but having issues with examples/numbers01.sql line 11 "sysdate -1m"
size_clause
: UNSIGNED_INTEGER (K_LETTER | M_LETTER | G_LETTER | T_LETTER | P_LETTER | E_LETTER)?
;
table_compression
: COMPRESS (
BASIC
| FOR (
OLTP
| (QUERY | ARCHIVE) (LOW | HIGH)?
| ALL OPERATIONS
| DIRECT_LOAD OPERATIONS
)
)?
| ROW STORE COMPRESS (BASIC | ADVANCED)?
| COLUMN STORE COMPRESS (FOR (QUERY | ARCHIVE) (LOW | HIGH)?)? (NO? ROW LEVEL LOCKING)?
| NOCOMPRESS
;
// avoid to match an empty string in
inmemory_table_clause
: inmemory_column_clause+
| (INMEMORY inmemory_attributes? | NO INMEMORY) inmemory_column_clause*
;
inmemory_attributes
: (
inmemory_memcompress
| inmemory_priority
| inmemory_distribute
| inmemory_duplicate
)+
;
inmemory_memcompress
: MEMCOMPRESS FOR (DML | (QUERY | CAPACITY) (LOW | HIGH)?)
| NO MEMCOMPRESS
;
inmemory_priority
: PRIORITY (NONE | LOW | MEDIUM | HIGH | CRITICAL)
;
inmemory_distribute
: DISTRIBUTE (AUTO | BY (ROWID RANGE | PARTITION | SUBPARTITION))? (
FOR SERVICE (DEFAULT | ALL | identifier | NONE)
)?
;
inmemory_duplicate
: DUPLICATE ALL?
| NO DUPLICATE
;
inmemory_column_clause
: (INMEMORY inmemory_memcompress? | NO INMEMORY) '(' column_list ')'
;
physical_attributes_clause
: (
PCTFREE pctfree = UNSIGNED_INTEGER
| PCTUSED pctused = UNSIGNED_INTEGER
| INITRANS inittrans = UNSIGNED_INTEGER
| MAXTRANS maxtrans = UNSIGNED_INTEGER
| storage_clause
| compute_clauses
)+
;
storage_clause
: STORAGE '(' (
INITIAL initial_size = size_clause
| NEXT next_size = size_clause
| MINEXTENTS minextents = (UNSIGNED_INTEGER | UNLIMITED)
| MAXEXTENTS minextents = (UNSIGNED_INTEGER | UNLIMITED)
| PCTINCREASE pctincrease = UNSIGNED_INTEGER
| FREELISTS freelists = UNSIGNED_INTEGER
| FREELIST GROUPS freelist_groups = UNSIGNED_INTEGER
| OPTIMAL (size_clause | NULL_)
| BUFFER_POOL (KEEP | RECYCLE | DEFAULT)
| FLASH_CACHE (KEEP | NONE | DEFAULT)
| CELL_FLASH_CACHE (KEEP | NONE | DEFAULT)
| ENCRYPT
)+ ')'
;
deferred_segment_creation
: SEGMENT CREATION (IMMEDIATE | DEFERRED)
;
segment_attributes_clause
: (
physical_attributes_clause
| TABLESPACE (tablespace_name = id_expression | SET? identifier)
| table_compression
| logging_clause
)+
;
physical_properties
: deferred_segment_creation
| segment_attributes_clause
| table_compression
| inmemory_table_clause
| ilm_clause
| ORGANIZATION (
HEAP segment_attributes_clause? heap_org_table_clause
| INDEX segment_attributes_clause? index_org_table_clause?
| EXTERNAL external_table_clause
)
| EXTERNAL PARTITION ATTRIBUTES external_table_clause (REJECT LIMIT)?
| CLUSTER cluster_name '(' column_name (',' column_name)* ')'
;
ilm_clause
: ILM (
ADD POLICY ilm_policy_clause
| (DELETE | ENABLE | DISABLE) POLICY ilm_policy_clause
| DELETE_ALL
| ENABLE_ALL
| DISABLE_ALL
)
;
ilm_policy_clause
: ilm_compression_policy
| ilm_tiering_policy
| ilm_inmemory_policy
;
ilm_compression_policy
: table_compression segment_group ilm_after_on
| ((ROW | COLUMN) STORE COMPRESS (ADVANCED | FOR QUERY)) ROW AFTER ilm_time_period OF NO MODIFICATION
;
ilm_tiering_policy
: TIER TO tablespace (
segment_group? (ON function_name)?
| READ ONLY segment_group? ilm_after_on
)
;
ilm_after_on
: AFTER ilm_time_period OF (NO (ACCESS | MODIFICATION) | CREATION)
| ON function_name
;
segment_group
: SEGMENT
| GROUP
;
ilm_inmemory_policy
: (SET INMEMORY inmemory_attributes? | MODIFY INMEMORY inmemory_memcompress | NO INMEMORY) SEGMENT? ilm_after_on
;
ilm_time_period
: numeric (DAY | DAYS | MONTH | MONTHS | YEAR | YEARS)
;
heap_org_table_clause
: table_compression? inmemory_table_clause? ilm_clause?
;
external_table_clause
: '(' (TYPE access_driver_type)? external_table_data_props ')' parallel_clause? (
REJECT LIMIT (numeric | UNLIMITED)
)? inmemory_table_clause?
;
access_driver_type
: ORACLE_LOADER
| ORACLE_DATAPUMP
| ORACLE_HDFS
| ORACLE_HIVE
;
external_table_data_props
: (DEFAULT DIRECTORY external_table_directory)? (
ACCESS PARAMETERS (
'(' CHAR_STRING ')'
| '(' external_table_data_format+ ')'
| USING CLOB select_only_statement
)
)? (LOCATION '(' external_table_directory (',' external_table_directory)* ')')?
;
external_table_data_format
: RECORDS DELIMITED BY NEWLINE_
| COLUMN TRANSFORMS '(' external_table_transform (',' external_table_transform)* ')'
| external_table_records
| external_table_fields
| external_table_datapump
| external_table_hive
;
external_table_transform
: column_name FROM (
NULL_
| CONSTANT quoted_string
| (CONCAT | LOBFILE) (external_table_field | CONSTANT quoted_string)
| (
FROM '(' external_table_directory (',' external_table_directory)* ')'
| CLOB
| BLOB
| CHARACTERSET '=' char_set_name
)
| STARTOF external_table_field_list '(' UNSIGNED_INTEGER ')'
)
;
external_table_field
: column_name type_name? (NOT NULL_)? default_value_part?
;
external_table_field_list
: external_table_fields_clause (',' external_table_fields_clause)*
;
external_table_fields_clause
: external_table_field (
external_table_position_clause
| external_table_datatype_clause
| external_table_init_clause
| external_table_lls_clause
)*
;
external_table_position_clause
: POSITION? '(' ('*'? ('+' | '-')? UNSIGNED_INTEGER?) (BINDVAR | (':' ('+' | '-')? UNSIGNED_INTEGER)) ')'
;
external_table_datatype_clause
: UNSIGNED? INTEGER EXTERNAL? UNSIGNED_INTEGER? external_table_delimit_clause?
| (DECIMAL | ZONED) (
'(' UNSIGNED_INTEGER (',' UNSIGNED_INTEGER)? ')'
| EXTERNAL ('(' UNSIGNED_INTEGER ')')? external_table_delimit_clause?
)
| ORACLE_DATE
| ORACLE_NUMBER COUNTED?
| FLOAT EXTERNAL? UNSIGNED_INTEGER? external_table_delimit_clause?
| DOUBLE
| BINARY_FLOAT EXTERNAL? UNSIGNED_INTEGER? external_table_delimit_clause?
| BINARY_DOUBLE
| RAW UNSIGNED_INTEGER?
| CHAR EXTERNAL? ('(' UNSIGNED_INTEGER ')' )? external_table_delimit_clause? external_table_trim_clause? external_table_date_format_clause?
| (VARCHAR | VARRAW | VARCHARC | VARRAWC) '(' (UNSIGNED_INTEGER ',')? UNSIGNED_INTEGER ')'
;
external_table_delimit_clause
: ENCLOSED BY quoted_string (AND quoted_string)?
| TERMINATED BY (quoted_string | WHITESPACE) (OPTIONALLY? ENCLOSED BY quoted_string (AND quoted_string)?)?
;
external_table_trim_clause
: LRTRIM
| NOTRIM
| LTRIM
| RTRIM
| LDRTRIM
;
external_table_date_format_clause
: DATE_FORMAT? (
DATE
| TIMESTAMP (WITH LOCAL? TIME ZONE)? MASK quoted_string
| INTERVAL (YEAR_TO_MONTH | DAY_TO_SECOND)
)
;
external_table_init_clause
: (DEFAULTIF | NULLIF) external_table_condition_clause
;
external_table_condition_clause
: (field_spec | '(' UNSIGNED_INTEGER BINDVAR ')') relational_operator (quoted_string | HEX_STRING_LIT | BLANKS)
| external_table_condition_clause (AND | OR) external_table_condition_clause
;
external_table_lls_clause
: LLS external_table_directory
;
external_table_records
: RECORDS (
FIXED UNSIGNED_INTEGER
| VARIABLE UNSIGNED_INTEGER
| DELIMITED BY (DETECTED? NEWLINE_ | quoted_string)
| XMLTAG '('? id_expression (',' id_expression)* ')'?
) external_table_record_options_clause*
| external_table_record_options_clause+
;
external_table_record_options_clause
: CHARACTERSET char_set_name
| EXTERNAL VARIABLE DATA
| PREPROCESSOR external_table_directory
| DATA IS (LITTLE | BIG) ENDIAN
| BYTEORDERMARK (CHECK | NOCHECK)
| STRING SIZES ARE IN (BYTES | CHARACTERS)
| LOAD WHEN external_table_condition_clause
| external_table_output_files
| READSIZE '='? UNSIGNED_INTEGER
| DISABLE_DIRECTORY_LINK_CHECK
| DATE_CACHE UNSIGNED_INTEGER
| SKIP_ UNSIGNED_INTEGER
| IO_OPTIONS (DIRECTIO | NODIRECTIO)
| (DNFS_ENABLE | DNFS_DISABLE)
| DNFS_READBUFFERS UNSIGNED_INTEGER
;
external_table_output_files
: (
(NOBADFILE | NODISCARDFILE | NOLOGFILE)
| (BADFILE | DISCARDFILE | LOGFILE) external_table_directory? filename
)
;
external_table_fields
: FIELDS
IGNORE_CHARS_AFTER_EOR?
(CSV (WITH | WITHOUT) EMBEDDED)?
external_table_delimit_clause?
external_table_trim_clause?
(ALL FIELDS OVERRIDE THESE FIELDS)?
(MISSING FIELD VALUES ARE NULL_)?
(REJECT ROWS WITH ALL NULL_ FIELDS)?
(DATE_FORMAT (DATE | TIMESTAMP) MASK quoted_string)?
(NULLIF (EQUALS_OP | NOT_EQUAL_OP) (quoted_string | HEX_STRING_LIT | BLANKS) | NONULLIF)?
'('? external_table_field_list? ')'?
;
external_table_datapump
: ENCRYPTION (ENABLE | DISABLED)
| NOLOGFILE
| LOGFILE external_table_directory? filename
| COMPRESSION (ENABLED (BASIC | LOW | MEDIUM | HIGH)? | DISABLED)?
| HADOOP_TRAILERS (ENABLED | DISABLED) VERSION (COMPATIBLE | LATEST | quoted_string)
| NOLOG
| DEBUG '=' '(' UNSIGNED_INTEGER ',' UNSIGNED_INTEGER ')'
| DATAPUMP INTERNAL TABLE tableview_name
| TEMPLATE_TABLE tableview_name
| JOB '(' schema_name ',' tableview_name ',' UNSIGNED_INTEGER ')'
| WORKERID UNSIGNED_INTEGER
| PARALLEL UNSIGNED_INTEGER
| VERSION quoted_string
| ENCRYPTPASSWORDISNULL
| DBLINK quoted_string
;
external_table_hive
: id_expression ('.' id_expression)* ('=' | ':') (
tableview_name
| external_table_hive_parameter_map
| '[' external_table_hive_parameter_map (',' external_table_hive_parameter_map)* ']'
| external_table_field datatype (COMMENT quoted_string)? (',' COMMENT quoted_string)*
| SEQUENCEFILE
| TEXTFILE
| RCFILE
| ORC
| PARQUET
| INPUTFORMAT quoted_string OUTPUTFORMAT quoted_string
| external_table_directory
| DELIMITED? (
FIELDS TERMINATED BY CHARACTER (ESCAPED BY CHARACTER)
| (COLLECTION ITEMS | MAP KEYS | LINES ) TERMINATED BY CHARACTER
| NULL_ DEFINED AS CHARACTER
)
| SERDE quoted_string (
WITH SERDEPROPERTIES (
quoted_string '=' quoted_string (',' quoted_string '=' quoted_string)*
)
)?
) external_table_hive?
;
external_table_hive_parameter_map
: LEFT_CURLY_PAREN (external_table_hive_parameter_map_entry (',' external_table_hive_parameter_map_entry)*) RIGHT_CURLY_PAREN
;
external_table_hive_parameter_map_entry
: id_expression BINDVAR
| id_expression ':' '[' id_expression (',' id_expression)* ']'
| '[' id_expression (',' id_expression)* ']'
;
external_table_directory
: directory_name COLON CHAR_STRING
| (directory_name object_name? COLON)? CHAR_STRING
| quoted_string
| variable_name
;
row_movement_clause
: (ENABLE | DISABLE)? ROW MOVEMENT
;
flashback_archive_clause
: FLASHBACK ARCHIVE fa = id_expression?
| NO FLASHBACK ARCHIVE
;
log_grp
: UNSIGNED_INTEGER
| identifier
;
supplemental_table_logging
: ADD SUPPLEMENTAL LOG (supplemental_log_grp_clause | supplemental_id_key_clause) (
',' SUPPLEMENTAL LOG (supplemental_log_grp_clause | supplemental_id_key_clause)
)*
| DROP SUPPLEMENTAL LOG (supplemental_id_key_clause | GROUP log_grp) (
',' SUPPLEMENTAL LOG (supplemental_id_key_clause | GROUP log_grp)
)*
;
supplemental_log_grp_clause
: GROUP log_grp '(' column_name (NO LOG)? (',' column_name (NO LOG)?)* ')' ALWAYS?
;
supplemental_id_key_clause
: DATA '(' (','? ( ALL | PRIMARY KEY | UNIQUE INDEX? | FOREIGN KEY))+ ')' COLUMNS
;
allocate_extent_clause
: ALLOCATE EXTENT (
'(' (
SIZE size_clause
| DATAFILE datafile = CHAR_STRING
| INSTANCE inst_num = UNSIGNED_INTEGER
)+ ')'
)?
;
deallocate_unused_clause
: DEALLOCATE UNUSED (KEEP size_clause)?
;
// CHECK is an internal, undocumented Oracle option that is allowed and sometimes specified, used to check for proper
// segment type and segment attributes allowed to shrink.
shrink_clause
: SHRINK SPACE_KEYWORD COMPACT? CASCADE? CHECK?
;
records_per_block_clause
: (MINIMIZE | NOMINIMIZE)? RECORDS_PER_BLOCK
;
upgrade_table_clause
: UPGRADE (NOT? INCLUDING DATA) column_properties
;
truncate_table
: TRUNCATE TABLE tableview_name ((PRESERVE | PURGE) (MATERIALIZED VIEW LOG)?)? ((DROP ALL? | REUSE) STORAGE)? CASCADE?
;
drop_table
: DROP TABLE tableview_name (IF EXISTS)? (AS tableview_name)? (CASCADE (CONSTRAINT | CONSTRAINTS))? PURGE? (AS table_alias)? FORCE?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-TABLESPACE.html
drop_tablespace
: DROP TABLESPACE ts = id_expression (IF EXISTS)? ((DROP | KEEP) QUOTA?)? including_contents_clause?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-TABLESPACE-SET.html
drop_tablespace_set
: DROP TABLESPACE SET tss = id_expression including_contents_clause?
;
including_contents_clause
: INCLUDING CONTENTS ((AND | KEEP) DATAFILES)? (CASCADE CONSTRAINTS)?
;
drop_view
: DROP VIEW tableview_name (IF EXISTS)? (CASCADE CONSTRAINT)?
;
comment_on_column
: COMMENT ON COLUMN column_name IS quoted_string
;
enable_or_disable
: ENABLE
| DISABLE
;
allow_or_disallow
: ALLOW
| DISALLOW
;
// Synonym DDL Clauses
alter_synonym
: ALTER PUBLIC? SYNONYM (schema_name '.')? synonym_name (
EDITIONABLE
| NONEDITIONABLE
| COMPILE
)
;
create_synonym
// Synonym's schema cannot be specified for public synonyms
: CREATE (OR REPLACE)? PUBLIC SYNONYM synonym_name FOR (schema_name PERIOD)? schema_object_name (
AT_SIGN link_name
)?
| CREATE (OR REPLACE)? SYNONYM (schema_name PERIOD)? synonym_name FOR (schema_name PERIOD)? schema_object_name (
AT_SIGN (schema_name PERIOD)? link_name
)?
;
drop_synonym
: DROP PUBLIC? SYNONYM (schema_name '.')? synonym_name FORCE?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-SPFILE.html
create_spfile
: CREATE SPFILE ('=' spfile_name)? FROM (PFILE ('=' pfile_name)? (AS COPY)? | MEMORY)
;
spfile_name
: CHAR_STRING
;
pfile_name
: CHAR_STRING
;
comment_on_table
: COMMENT ON TABLE tableview_name IS quoted_string
;
comment_on_materialized
: COMMENT ON MATERIALIZED VIEW tableview_name IS quoted_string
;
alter_analytic_view
: ALTER ANALYTIC VIEW (schema_name '.')? av = id_expression (
RENAME TO id_expression
| COMPILE
| alter_add_cache_clause
| alter_drop_cache_clause
)
;
alter_add_cache_clause
: ADD CACHE MEASURE GROUP '(' (ALL | measure_list)? ')' LEVELS '(' levels_item (
',' levels_item
)* ')'
;
levels_item
: ((d = id_expression '.')? h = id_expression '.')? l = id_expression
;
measure_list
: id_expression (',' id_expression)*
;
alter_drop_cache_clause
: DROP CACHE MEASURE GROUP '(' (ALL | measure_list)? ')' LEVELS '(' levels_item (
',' levels_item
)* ')'
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-ATTRIBUTE-DIMENSION.html
alter_attribute_dimension
: ALTER ATTRIBUTE DIMENSION (schema_name '.')? ad = id_expression (
RENAME TO nad = id_expression
| COMPILE
)
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-AUDIT-POLICY-Unified-Auditing.html
alter_audit_policy
: ALTER AUDIT POLICY p = id_expression ADD? (
privilege_audit_clause? action_audit_clause? role_audit_clause?
| (ONLY TOPLEVEL)?
) DROP? (privilege_audit_clause? action_audit_clause? role_audit_clause? | (ONLY TOPLEVEL)?) (
CONDITION (DROP | CHAR_STRING EVALUATE PER (STATEMENT | SESSION | INSTANCE))
)?
;
alter_cluster
: ALTER CLUSTER cluster_name (
physical_attributes_clause
| SIZE size_clause
| allocate_extent_clause
| deallocate_unused_clause
| cache_or_nocache
)+ parallel_clause?
;
drop_analytic_view
: DROP ANALYTIC VIEW (schema_name '.')? av = id_expression
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-ATTRIBUTE-DIMENSION.html
drop_attribute_dimension
: DROP ATTRIBUTE DIMENSION (schema_name '.')? ad = id_expression
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-AUDIT-POLICY-Unified-Auditing.html
drop_audit_policy
: DROP AUDIT POLICY p = id_expression
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-FLASHBACK-ARCHIVE.html
drop_flashback_archive
: DROP FLASHBACK ARCHIVE fa = id_expression
;
drop_cluster
: DROP CLUSTER cluster_name (INCLUDING TABLES (CASCADE CONSTRAINTS)?)?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-CONTEXT.html
drop_context
: DROP CONTEXT ns = id_expression
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-DIRECTORY.html
drop_directory
: DROP DIRECTORY dn = id_expression
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-DISKGROUP.html
drop_diskgroup
: DROP DISKGROUP dgn = id_expression ((FORCE? INCLUDING | EXCLUDING) CONTENTS)?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-EDITION.html
drop_edition
: DROP EDITION e = id_expression CASCADE?
;
truncate_cluster
: TRUNCATE CLUSTER cluster_name ((DROP | REUSE) STORAGE)?
;
cache_or_nocache
: CACHE
| NOCACHE
;
database_name
: id_expression
;
alter_database
: ALTER database_clause (
startup_clauses
| recovery_clauses
| database_file_clauses
| logfile_clauses
| controlfile_clauses
| standby_database_clauses
| default_settings_clause
| instance_clauses
| security_clause
| prepare_clause
| drop_mirror_clause
| lost_write_protection
| cdb_fleet_clauses
| property_clauses
| replay_upgrade_clauses
)
;
database_clause
: PLUGGABLE? DATABASE database_name?
;
startup_clauses
: MOUNT ((STANDBY | CLONE) DATABASE)?
| OPEN (READ WRITE)? resetlogs_or_noresetlogs? upgrade_or_downgrade?
| OPEN READ ONLY
;
resetlogs_or_noresetlogs
: RESETLOGS
| NORESETLOGS
;
upgrade_or_downgrade
: UPGRADE
| DOWNGRADE
;
recovery_clauses
: general_recovery
| managed_standby_recovery
| begin_or_end BACKUP
;
begin_or_end
: BEGIN
| END
;
general_recovery
: RECOVER AUTOMATIC? (FROM CHAR_STRING)? (
(full_database_recovery | partial_database_recovery | LOGFILE CHAR_STRING)? (
(TEST | ALLOW UNSIGNED_INTEGER CORRUPTION | parallel_clause)+
)?
| CONTINUE DEFAULT?
| CANCEL
)
;
//Need to come back to
full_database_recovery
: STANDBY? DATABASE (
(
UNTIL (CANCEL | TIME CHAR_STRING | CHANGE UNSIGNED_INTEGER | CONSISTENT)
| USING BACKUP CONTROLFILE
| SNAPSHOT TIME CHAR_STRING
)+
)?
;
partial_database_recovery
: TABLESPACE tablespace (',' tablespace)*
| DATAFILE CHAR_STRING
| filenumber (',' CHAR_STRING | filenumber)*
| partial_database_recovery_10g
;
partial_database_recovery_10g
: {this.isVersion10()}? STANDBY (
TABLESPACE tablespace (',' tablespace)*
| DATAFILE CHAR_STRING
| filenumber (',' CHAR_STRING | filenumber)*
) UNTIL (CONSISTENT WITH)? CONTROLFILE
;
managed_standby_recovery
: RECOVER (
MANAGED STANDBY DATABASE (
(
USING CURRENT LOGFILE
| DISCONNECT (FROM SESSION)?
| NODELAY
| UNTIL CHANGE UNSIGNED_INTEGER
| UNTIL CONSISTENT
| parallel_clause
)+
| FINISH
| CANCEL
)?
| TO LOGICAL STANDBY (db_name | KEEP IDENTITY)
)
;
db_name
: regular_id
;
database_file_clauses
: RENAME FILE filename (',' filename)* TO filename
| create_datafile_clause
| alter_datafile_clause
| alter_tempfile_clause
| move_datafile_clause
;
create_datafile_clause
: CREATE DATAFILE (filename | filenumber) (',' (filename | filenumber))* (
AS (
//TODO (','? file_specification)+ |
NEW
)
)?
;
alter_datafile_clause
: DATAFILE (filename | filenumber) (',' (filename | filenumber))* (
ONLINE
| OFFLINE (FOR DROP)?
| RESIZE size_clause
| autoextend_clause
| END BACKUP
)
;
alter_tempfile_clause
: TEMPFILE (filename | filenumber) (',' (filename | filenumber))* (
RESIZE size_clause
| autoextend_clause
| DROP (INCLUDING DATAFILES)
| ONLINE
| OFFLINE
)
;
move_datafile_clause
: MOVE DATAFILE (filename | filenumber) (',' (filename | filenumber))* (TO filename)? REUSE? KEEP?
;
logfile_clauses
: (ARCHIVELOG MANUAL? | NOARCHIVELOG)
| NO? FORCE LOGGING
| SET STANDBY NOLOGGING FOR (DATA AVAILABILITY | LOAD PERFORMANCE)
| RENAME FILE filename (',' filename)* TO filename
| CLEAR UNARCHIVED? LOGFILE logfile_descriptor (',' logfile_descriptor)* (
UNRECOVERABLE DATAFILE
)?
| add_logfile_clauses
| drop_logfile_clauses
| switch_logfile_clause
| supplemental_db_logging
;
add_logfile_clauses
: ADD STANDBY? LOGFILE (
(INSTANCE CHAR_STRING | THREAD UNSIGNED_INTEGER)? group_redo_logfile+
| MEMBER filename REUSE? (',' filename REUSE?)* TO logfile_descriptor (
',' logfile_descriptor
)*
)
;
group_redo_logfile
: (GROUP UNSIGNED_INTEGER)? redo_log_file_spec
;
drop_logfile_clauses
: DROP STANDBY? LOGFILE (
logfile_descriptor (',' logfile_descriptor)*
| MEMBER filename (',' filename)*
)
;
switch_logfile_clause
: SWITCH ALL LOGFILES TO BLOCKSIZE UNSIGNED_INTEGER
;
supplemental_db_logging
: add_or_drop SUPPLEMENTAL LOG (DATA | supplemental_id_key_clause | supplemental_plsql_clause)
;
add_or_drop
: ADD
| DROP
;
supplemental_plsql_clause
: DATA FOR PROCEDURAL REPLICATION
;
logfile_descriptor
: GROUP UNSIGNED_INTEGER
| '(' filename (',' filename)* ')'
| filename
;
controlfile_clauses
: CREATE (LOGICAL | PHYSICAL)? STANDBY CONTROLFILE AS filename REUSE?
| BACKUP CONTROLFILE TO (filename REUSE? | trace_file_clause)
;
trace_file_clause
: TRACE (AS filename REUSE?)? (RESETLOGS | NORESETLOGS)?
;
standby_database_clauses
: (
activate_standby_db_clause
| maximize_standby_db_clause
| register_logfile_clause
| commit_switchover_clause
| start_standby_clause
| stop_standby_clause
| convert_database_clause
) parallel_clause?
;
activate_standby_db_clause
: ACTIVATE (PHYSICAL | LOGICAL)? STANDBY DATABASE (FINISH APPLY)?
;
maximize_standby_db_clause
: SET STANDBY DATABASE TO MAXIMIZE (PROTECTION | AVAILABILITY | PERFORMANCE)
;
register_logfile_clause
: REGISTER (OR REPLACE)? (PHYSICAL | LOGICAL) LOGFILE //TODO (','? file_specification)+
//TODO (FOR logminer_session_name)?
;
commit_switchover_clause
: (PREPARE | COMMIT) TO SWITCHOVER (
(
TO (
((PHYSICAL | LOGICAL)? PRIMARY | PHYSICAL? STANDBY) (
(WITH | WITHOUT)? SESSION SHUTDOWN (WAIT | NOWAIT)
)?
| LOGICAL STANDBY
)
| LOGICAL STANDBY
)
| CANCEL
)?
;
start_standby_clause
: START LOGICAL STANDBY APPLY IMMEDIATE? NODELAY? (
NEW PRIMARY regular_id
| INITIAL scn_value = UNSIGNED_INTEGER?
| SKIP_ FAILED TRANSACTION
| FINISH
)?
;
stop_standby_clause
: (STOP | ABORT) LOGICAL STANDBY APPLY
;
convert_database_clause
: CONVERT TO (PHYSICAL | SNAPSHOT) STANDBY
;
default_settings_clause
: DEFAULT EDITION EQUALS_OP edition_name
| SET DEFAULT (BIGFILE | SMALLFILE) TABLESPACE
| DEFAULT TABLESPACE tablespace
| DEFAULT TEMPORARY TABLESPACE (tablespace | tablespace_group_name)
| RENAME GLOBAL_NAME TO database ('.' domain)+
| ENABLE BLOCK CHANGE TRACKING (USING FILE filename REUSE?)?
| DISABLE BLOCK CHANGE TRACKING
| flashback_mode_clause
| set_time_zone_clause
;
set_time_zone_clause
: SET TIMEZONE EQUALS_OP CHAR_STRING
;
instance_clauses
: enable_or_disable INSTANCE CHAR_STRING
;
security_clause
: GUARD (ALL | STANDBY | NONE)
;
domain
: id_expression
;
database
: id_expression
;
edition_name
: regular_id
;
filenumber
: UNSIGNED_INTEGER
;
filename
: CHAR_STRING
;
prepare_clause
: PREPARE MIRROR COPY c = id_expression (WITH (UNPROTECTED | MIRROR | HIGH) REDUNDANCY)? (
FOR DATABASE id_expression
)?
;
drop_mirror_clause
: DROP MIRROR COPY mn = id_expression
;
lost_write_protection
: (ENABLE | DISABLE | REMOVE | SUSPEND) LOST WRITE PROTECTION
;
cdb_fleet_clauses
: lead_cdb_clause
| lead_cdb_uri_clause
;
lead_cdb_clause
: SET LEAD_CDB '=' (TRUE | FALSE)
;
lead_cdb_uri_clause
: SET LEAD_CDB_URI '=' CHAR_STRING
;
property_clauses
: PROPERTY (SET | REMOVE) DEFAULT_CREDENTIAL '=' qcn = id_expression
;
replay_upgrade_clauses
: UPGRADE SYNC (ON | OFF)
;
alter_database_link
: ALTER SHARED? PUBLIC? DATABASE LINK local_link_name (
CONNECT TO user_object_name IDENTIFIED BY password_value link_authentication?
| link_authentication
)
;
password_value
: id_expression
| numeric
| VALUES CHAR_STRING
;
link_authentication
: AUTHENTICATED BY user_object_name IDENTIFIED BY password_value
;
//https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/CREATE-SCHEMA.html
create_schema
: CREATE SCHEMA AUTHORIZATION schema_name (create_table | create_view | grant_statement)*
;
// added by zrh
create_database
: CREATE DATABASE database_name (
USER (SYS | SYSTEM) IDENTIFIED BY password_value
| CONTROLFILE REUSE
| (MAXDATAFILES | MAXINSTANCES) UNSIGNED_INTEGER
| NATIONAL? CHARACTER SET char_set_name
| SET DEFAULT (BIGFILE | SMALLFILE) TABLESPACE
| database_logging_clauses
| tablespace_clauses
| set_time_zone_clause
| (BIGFILE | SMALLFILE)? USER_DATA TABLESPACE tablespace_group_name DATAFILE datafile_tempfile_spec (
',' datafile_tempfile_spec
)*
| enable_pluggable_database
)+
;
database_logging_clauses
: LOGFILE database_logging_sub_clause (',' database_logging_sub_clause)*
| (MAXLOGFILES | MAXLOGMEMBERS | MAXLOGHISTORY) UNSIGNED_INTEGER
| ARCHIVELOG
| NOARCHIVELOG
| FORCE LOGGING
;
database_logging_sub_clause
: (GROUP UNSIGNED_INTEGER)? file_specification
;
tablespace_clauses
: EXTENT MANAGEMENT LOCAL
| SYSAUX? DATAFILE file_specification (',' file_specification)*
| default_tablespace
| default_temp_tablespace
| undo_tablespace
;
enable_pluggable_database
: ENABLE PLUGGABLE DATABASE (
SEED file_name_convert? (SYSTEM tablespace_datafile_clauses)? (
SYSAUX tablespace_datafile_clauses
)?
)? undo_mode_clause?
;
file_name_convert
: FILE_NAME_CONVERT EQUALS_OP (
'(' filename_convert_sub_clause (',' filename_convert_sub_clause)* ')'
| NONE
)
;
filename_convert_sub_clause
: CHAR_STRING (',' CHAR_STRING)?
;
tablespace_datafile_clauses
: DATAFILES (SIZE size_clause | autoextend_clause)+
;
undo_mode_clause
: LOCAL UNDO (ON | OFF)
;
default_tablespace
: DEFAULT TABLESPACE tablespace (DATAFILE datafile_tempfile_spec)? extent_management_clause?
;
default_temp_tablespace
: (BIGFILE | SMALLFILE)? DEFAULT (
TEMPORARY TABLESPACE
| LOCAL TEMPORARY TABLESPACE FOR (ALL | LEAF)
) tablespace (TEMPFILE file_specification (',' file_specification)*)? extent_management_clause?
;
undo_tablespace
: (BIGFILE | SMALLFILE)? UNDO TABLESPACE tablespace (
DATAFILE file_specification (',' file_specification)*
)?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/DROP-DATABASE.html
drop_database
: DROP DATABASE (INCLUDING BACKUPS)? NOPROMPT?
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-DATABASE-LINK.html
create_database_link
: CREATE SHARED? PUBLIC? DATABASE LINK link_name (
CONNECT TO (
CURRENT_USER
| user_object_name IDENTIFIED BY password_value link_authentication?
)
| link_authentication
)* (USING CHAR_STRING)?
;
drop_database_link
: DROP PUBLIC? DATABASE LINK link_name
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ALTER-TABLESPACE-SET.html
alter_tablespace_set
: ALTER TABLESPACE SET tss = id_expression alter_tablespace_attrs
;
alter_tablespace_attrs
: default_tablespace_params
| MINIMUM EXTENT size_clause
| RESIZE size_clause
| COALESCE
| SHRINK SPACE_KEYWORD (KEEP size_clause)?
| RENAME TO nts = id_expression
| (BEGIN | END) BACKUP
| datafile_tempfile_clauses
| tablespace_logging_clauses
| tablespace_group_clause
| tablespace_state_clauses
| autoextend_clause
| flashback_mode_clause
| tablespace_retention_clause
| alter_tablespace_encryption
| lost_write_protection
;
alter_tablespace_encryption
: ENCRYPTION (
OFFLINE (tablespace_encryption_spec? ENCRYPT | DECRYPT)
| ONLINE (tablespace_encryption_spec? (ENCRYPT | REKEY) | DECRYPT) ts_file_name_convert?
| FINISH (ENCRYPT | REKEY | DECRYPT) ts_file_name_convert?
)
;
ts_file_name_convert
: FILE_NAME_CONVERT '=' '(' CHAR_STRING ',' CHAR_STRING (',' CHAR_STRING ',' CHAR_STRING)* ')' KEEP?
;
alter_role
: ALTER ROLE role_name role_identified_clause container_clause?
;
role_identified_clause
: NOT IDENTIFIED
| IDENTIFIED (
BY identifier
| USING identifier ('.' id_expression)?
| EXTERNALLY
| GLOBALLY (AS CHAR_STRING)?
)
;
alter_table
: ALTER TABLE tableview_name memoptimize_read_write_clause* (
| alter_table_properties
| constraint_clauses
| column_clauses
| alter_table_partitioning
//TODO | alter_external_table
| move_table_clause
) ((enable_disable_clause | enable_or_disable (TABLE LOCK | ALL TRIGGERS))+)?
;
memoptimize_read_write_clause
: NO? MEMOPTIMIZE FOR (READ | WRITE)
;
alter_table_properties
: alter_table_properties_1
| RENAME TO tableview_name
| shrink_clause
| READ ONLY
| READ WRITE
| REKEY CHAR_STRING
| annotations_clause
;
alter_table_partitioning
: add_table_partition
| drop_table_partition
| merge_table_partition
| modify_table_partition
| split_table_partition
| truncate_table_partition
| exchange_table_partition
| coalesce_table_partition
| alter_interval_partition
| move_table_partition
| rename_table_partition
;
add_table_partition
: ADD (
range_partition_desc
| list_partition_desc
| PARTITION partition_name? (TABLESPACE tablespace)? key_compression? UNUSABLE?
)
;
drop_table_partition
: DROP (partition_extended_names | subpartition_extended_names) (
update_index_clauses parallel_clause?
)?
;
merge_table_partition
: MERGE PARTITION partition_name AND partition_name INTO PARTITION partition_name
;
modify_table_partition
: MODIFY (
(PARTITION | SUBPARTITION) partition_name ((ADD | DROP) list_values_clause)? (ADD range_subpartition_desc)? (
REBUILD? UNUSABLE LOCAL INDEXES
)? shrink_clause?
| range_partitions
)
;
split_table_partition
: SPLIT partition_extended_names (
AT '(' literal (',' literal)* ')' INTO '(' range_partition_desc (',' range_partition_desc)* ')'
| INTO '(' (
range_partition_desc (',' range_partition_desc)*
| list_partition_desc (',' list_partition_desc)*
) ')'
) (update_global_index_clause | update_index_clauses | ONLINE)?
;
truncate_table_partition
: TRUNCATE (partition_extended_names | subpartition_extended_names) (
(DROP ALL? | REUSE)? STORAGE
)? CASCADE? (update_index_clauses parallel_clause?)?
;
exchange_table_partition
: EXCHANGE PARTITION partition_name WITH TABLE tableview_name ((INCLUDING | EXCLUDING) INDEXES)? (
(WITH | WITHOUT) VALIDATION
)?
;
coalesce_table_partition
: COALESCE PARTITION parallel_clause? (allow_or_disallow CLUSTERING)?
;
alter_interval_partition
: SET INTERVAL '(' (constant | expression)? ')'
;
move_table_partition
: MOVE (
partition_extended_names (MAPPING TABLE)? table_partition_description
| subpartition_extended_names indexing_clause? partitioning_storage_clause?
) (
filter_condition
| update_index_clauses
| parallel_clause
| allow_or_disallow CLUSTERING
| ONLINE
)*
;
filter_condition
: INCLUDING ROWS where_clause
;
rename_table_partition
: RENAME (partition_extended_names | subpartition_extended_names) TO partition_name
;
partition_extended_names
: (PARTITION | PARTITIONS) (
partition_name (',' partition_name)*
| '(' partition_name (',' partition_name)* ')'
| FOR '('? partition_key_value (',' partition_key_value)* ')'?
)
;
subpartition_extended_names
: (SUBPARTITION | SUBPARTITIONS) (
partition_name (UPDATE INDEXES)?
| '(' partition_name (',' partition_name)* ')'
| FOR '('? subpartition_key_value (',' subpartition_key_value)* ')'?
)
;
alter_table_properties_1
: (
physical_attributes_clause
| logging_clause
| table_compression
| inmemory_table_clause
| supplemental_table_logging
| allocate_extent_clause
| deallocate_unused_clause
| (CACHE | NOCACHE)
| RESULT_CACHE '(' MODE (DEFAULT | FORCE) ')'
| upgrade_table_clause
| records_per_block_clause
| parallel_clause
| row_movement_clause
| logical_replication_clause
| flashback_archive_clause
)+ alter_iot_clauses?
;
alter_iot_clauses
: index_org_table_clause
| alter_overflow_clause
| alter_mapping_table_clause
| COALESCE
;
alter_mapping_table_clause
: MAPPING TABLE (allocate_extent_clause | deallocate_unused_clause)
;
alter_overflow_clause
: add_overflow_clause
| OVERFLOW_ (
segment_attributes_clause
| allocate_extent_clause
| shrink_clause
| deallocate_unused_clause
)+
;
add_overflow_clause
: ADD OVERFLOW_ segment_attributes_clause? (
'(' PARTITION segment_attributes_clause? (',' PARTITION segment_attributes_clause?)* ')'
)?
;
update_index_clauses
: update_global_index_clause
| update_all_indexes_clause
;
update_global_index_clause
: (UPDATE | INVALIDATE) GLOBAL INDEXES
;
update_all_indexes_clause
: UPDATE INDEXES ('(' update_all_indexes_index_clause ')')?
;
update_all_indexes_index_clause
: index_name '(' (update_index_partition | update_index_subpartition) ')' (
',' update_all_indexes_clause
)*
;
update_index_partition
: index_partition_description index_subpartition_clause? (',' update_index_partition)*
;
update_index_subpartition
: SUBPARTITION subpartition_name? (TABLESPACE tablespace)? (',' update_index_subpartition)*
;
enable_disable_clause
: (ENABLE | DISABLE) (VALIDATE | NOVALIDATE)? (
UNIQUE '(' column_name (',' column_name)* ')'
| PRIMARY KEY
| CONSTRAINT constraint_name
) using_index_clause? exceptions_clause? CASCADE? ((KEEP | DROP) INDEX)?
;
using_index_clause
: USING INDEX (index_name | '(' create_index ')' | index_properties)
;
index_attributes
: (
physical_attributes_clause
| logging_clause
| TABLESPACE (tablespace | DEFAULT)
| key_compression
| sort_or_nosort
| REVERSE
| visible_or_invisible
| parallel_clause
)+
;
sort_or_nosort
: SORT
| NOSORT
;
exceptions_clause
: EXCEPTIONS INTO tableview_name
;
move_table_clause
: MOVE ONLINE? segment_attributes_clause? table_compression? index_org_table_clause? (
lob_storage_clause
| varray_col_properties
)* parallel_clause?
;
index_org_table_clause
: (mapping_table_clause | PCTTHRESHOLD UNSIGNED_INTEGER | key_compression)+ index_org_overflow_clause?
| index_org_overflow_clause // rule move_table_clause contains an optional block with at least one alternative that can match an empty string
;
mapping_table_clause
: MAPPING TABLE
| NOMAPPING
;
key_compression
: NOCOMPRESS
| COMPRESS UNSIGNED_INTEGER
;
index_org_overflow_clause
: (INCLUDING column_name)? OVERFLOW_ segment_attributes_clause?
;
column_clauses
: add_modify_drop_column_clauses
| rename_column_clause
| modify_collection_retrieval
| modify_lob_storage_clause
;
modify_collection_retrieval
: MODIFY NESTED TABLE collection_item RETURN AS (LOCATOR | VALUE)
;
collection_item
: tableview_name
;
rename_column_clause
: RENAME COLUMN old_column_name TO new_column_name
;
old_column_name
: column_name
;
new_column_name
: column_name
;
add_modify_drop_column_clauses
: (constraint_clauses | add_column_clause | modify_column_clauses | drop_column_clause)+
;
drop_column_clause
: SET UNUSED (COLUMN column_name | ('(' column_name (',' column_name)* ')')) (
CASCADE CONSTRAINTS
| INVALIDATE
)*
| DROP (COLUMN column_name | '(' column_name (',' column_name)* ')') (
CASCADE CONSTRAINTS
| INVALIDATE
)* (CHECKPOINT UNSIGNED_INTEGER)?
| DROP (UNUSED COLUMNS | COLUMNS CONTINUE) (CHECKPOINT UNSIGNED_INTEGER)
;
modify_column_clauses
: MODIFY (
'(' modify_col_properties (',' modify_col_properties)* ')'
| '(' modify_col_visibility (',' modify_col_visibility)* ')'
| modify_col_properties
| modify_col_visibility
| modify_col_substitutable
)
;
modify_col_properties
: column_name datatype? (DEFAULT (ON NULL_)? expression)? (ENCRYPT encryption_spec | DECRYPT)? inline_constraint* lob_storage_clause? annotations_clause?
//TODO alter_xmlschema_clause
;
modify_col_visibility
: column_name (VISIBLE | INVISIBLE)
;
modify_col_substitutable
: COLUMN column_name NOT? SUBSTITUTABLE AT ALL LEVELS FORCE?
;
add_column_clause
: ADD (
'(' (column_definition | virtual_column_definition) (
',' (column_definition | virtual_column_definition)
)* ')'
| ( column_definition | virtual_column_definition)
) column_properties?
;
varray_col_properties
: VARRAY varray_item (
substitutable_column_clause? varray_storage_clause
| substitutable_column_clause
)
;
varray_storage_clause
: STORE AS (SECUREFILE | BASICFILE)? LOB (
lob_segname? '(' lob_storage_parameters ')'
| lob_segname
)?
;
lob_segname
: regular_id
;
lob_item
: regular_id
| quoted_string
| DELIMITED_ID
;
lob_storage_parameters
: TABLESPACE tablespace_name = id_expression
| (lob_parameters storage_clause?)
| storage_clause
;
lob_storage_clause
: LOB (
'(' lob_item (',' lob_item)* ')' STORE AS (
(SECUREFILE | BASICFILE)
| '(' lob_storage_parameters* ')'
)+
| '(' lob_item ')' STORE AS (
(SECUREFILE | BASICFILE)
| lob_segname
| '(' lob_storage_parameters* ')'
)+
)
;
modify_lob_storage_clause
: MODIFY LOB '(' lob_item ')' '(' modify_lob_parameters ')'
;
modify_lob_parameters
: (
storage_clause
| (PCTVERSION | FREEPOOLS) UNSIGNED_INTEGER
| REBUILD FREEPOOLS
| lob_retention_clause
| lob_deduplicate_clause
| lob_compression_clause
| ENCRYPT encryption_spec
| DECRYPT
| CACHE
| (CACHE | NOCACHE | CACHE READS) logging_clause?
| allocate_extent_clause
| shrink_clause
| deallocate_unused_clause
)+
;
lob_parameters
: (
(ENABLE | DISABLE) STORAGE IN ROW
| CHUNK UNSIGNED_INTEGER
| PCTVERSION UNSIGNED_INTEGER
| FREEPOOLS UNSIGNED_INTEGER
| lob_retention_clause
| lob_deduplicate_clause
| lob_compression_clause
| ENCRYPT encryption_spec
| DECRYPT
| (CACHE | NOCACHE | CACHE READS) logging_clause?
)+
;
lob_deduplicate_clause
: DEDUPLICATE
| KEEP_DUPLICATES
;
lob_compression_clause
: NOCOMPRESS
| COMPRESS (HIGH | MEDIUM | LOW)?
;
lob_retention_clause
: RETENTION (MAX | MIN UNSIGNED_INTEGER | AUTO | NONE)?
;
encryption_spec
: (USING CHAR_STRING)? (IDENTIFIED BY REGULAR_ID)? CHAR_STRING? (NO? SALT)?
;
tablespace
: id_expression
;
varray_item
: (id_expression '.')? (id_expression '.')? id_expression
;
column_properties
: (
object_type_col_properties
| nested_table_col_properties
| (varray_col_properties | lob_storage_clause) (
'(' lob_partition_storage (',' lob_partition_storage)* ')'
)? //TODO '(' ( ','? lob_partition_storage)+ ')'
| xmltype_column_properties
)+
;
lob_partition_storage
: LOB (
'(' lob_item (',' lob_item) ')' STORE AS (
(SECUREFILE | BASICFILE)
| '(' lob_storage_parameters ')'
)+
| '(' lob_item ')' STORE AS (
(SECUREFILE | BASICFILE)
| lob_segname
| '(' lob_storage_parameters ')'
)+
)
;
period_definition
: {this.isVersion12()}? PERIOD FOR column_name ('(' start_time_column ',' end_time_column ')')?
;
start_time_column
: column_name
;
end_time_column
: column_name
;
column_definition
: column_name ((datatype | type_name) (COLLATE column_collation_name)?)? SORT? (
VISIBLE
| INVISIBLE
)? (DEFAULT (ON NULL_)? expression | identity_clause)? (ENCRYPT encryption_spec)? (
inline_constraint+
| inline_ref_constraint
)? annotations_clause?
;
column_collation_name
: id_expression
;
identity_clause
: GENERATED (ALWAYS | BY DEFAULT (ON NULL_)?)? AS IDENTITY identity_options_parentheses?
;
//https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-TABLE.html#GUID-F9CE0CC3-13AE-4744-A43C-EAC7A71AAAB6
// NOTE to identity options
// according to the SQL Reference, identity_options be nested in parentheses.
// But statements without parentheses can also be executed successfully on a oracle database.
// See this issue for more details: https://github.com/antlr/grammars-v4/issues/3183
identity_options_parentheses
: identity_options+
| '(' identity_options+ ')'
;
identity_options
: START WITH (numeric | LIMIT VALUE)
| INCREMENT BY numeric
| MAXVALUE numeric
| NOMAXVALUE
| MINVALUE numeric
| NOMINVALUE
| CYCLE
| NOCYCLE
| CACHE numeric
| NOCACHE
| ORDER
| NOORDER
| SCALE (EXTEND | NOEXTEND)
| NOSCALE
| KEEP
| NOKEEP
;
virtual_column_definition
: column_name (datatype (COLLATE column_collation_name)?)? (VISIBLE | INVISIBLE)? virtual_column_expression? VIRTUAL?
evaluation_edition_clause? (UNUSABLE BEFORE (CURRENT EDITION | EDITION edition_name))? (
UNUSABLE BEGINNING WITH ((CURRENT | NULL_) EDITION | EDITION edition_name)
)? inline_constraint* by_user_for_statistics_clause?
;
virtual_column_expression
: autogenerated_sequence_definition
| (GENERATED ALWAYS?)? AS '(' expression ')'
;
autogenerated_sequence_definition
: GENERATED (ALWAYS | BY DEFAULT (ON NULL_)?)? AS IDENTITY (
'(' (sequence_start_clause | sequence_spec)* ')'
)?
;
// Oracle tools and DBMS_METADATA can return this in some use cases
// This is used internally by Oracle to mark the virtual column for statistics only
by_user_for_statistics_clause
: BY USER FOR STATISTICS
;
evaluation_edition_clause
: EVALUATE USING ((CURRENT | NULL_) EDITION | EDITION edition_name)
;
nested_table_col_properties
: NESTED TABLE (nested_item | COLUMN_VALUE) substitutable_column_clause? (LOCAL | GLOBAL)? STORE AS tableview_name (
'(' ('(' object_properties ')' | physical_properties | column_properties)+ ')'
)? (RETURN AS? (LOCATOR | VALUE))?
;
nested_item
: regular_id
;
substitutable_column_clause
: ELEMENT? IS OF TYPE? '(' type_name ')'
| NOT? SUBSTITUTABLE AT ALL LEVELS
;
partition_name
: regular_id
| DELIMITED_ID
;
supplemental_logging_props
: SUPPLEMENTAL LOG (supplemental_log_grp_clause | supplemental_id_key_clause)
;
object_type_col_properties
: COLUMN column = regular_id substitutable_column_clause
;
constraint_clauses
: ADD '(' (out_of_line_constraint (',' out_of_line_constraint)* | out_of_line_ref_constraint) ')'
| ADD (out_of_line_constraint | out_of_line_ref_constraint)
| MODIFY (
CONSTRAINT constraint_name
| PRIMARY KEY
| UNIQUE '(' column_name (',' column_name)* ')'
) constraint_state CASCADE?
| RENAME CONSTRAINT old_constraint_name TO new_constraint_name
| drop_constraint_clause+
;
old_constraint_name
: constraint_name
;
new_constraint_name
: constraint_name
;
drop_constraint_clause
: DROP (
PRIMARY KEY
| UNIQUE '(' column_name (',' column_name)* ')'
| CONSTRAINT constraint_name
) CASCADE? ((KEY | DROP) INDEX)? ONLINE?
;
check_constraint
: CHECK '(' condition ')' DISABLE?
;
foreign_key_clause
: FOREIGN KEY paren_column_list references_clause on_delete_clause?
;
references_clause
: REFERENCES tableview_name paren_column_list? (ON DELETE (CASCADE | SET NULL_))?
;
on_delete_clause
: ON DELETE (CASCADE | SET NULL_)
;
// Anonymous PL/SQL code block
anonymous_block
: (DECLARE seq_of_declare_specs?)? BEGIN seq_of_statements (EXCEPTION exception_handler+)? END
;
// Common DDL Clauses
invoker_rights_clause
: AUTHID (CURRENT_USER | DEFINER)
;
call_spec
: java_spec
| c_spec
;
// Call Spec Specific Clauses
java_spec
: LANGUAGE JAVA NAME CHAR_STRING
;
c_spec
: (LANGUAGE C_LETTER | EXTERNAL) (
NAME id_expression LIBRARY identifier
| LIBRARY identifier (NAME id_expression)?
) c_agent_in_clause? (WITH CONTEXT)? c_parameters_clause?
;
c_agent_in_clause
: AGENT IN '(' expressions_ ')'
;
c_parameters_clause
: PARAMETERS '(' c_external_parameter (',' c_external_parameter)* ')'
;
c_external_parameter
: CONTEXT
| SELF (TDO | c_property)?
| (parameter_name | RETURN) c_property? (BY REFERENCE)? external_datatype = regular_id?
;
c_property
: INDICATOR (STRUCT | TDO)?
| LENGTH
| DURATION
| MAXLEN
| CHARSETID
| CHARSETFORM
;
parameter
: parameter_name (IN | OUT | INOUT | NOCOPY)* type_spec? default_value_part?
;
default_value_part
: (ASSIGN_OP | DEFAULT) expression
;
// Elements Declarations
seq_of_declare_specs
: declare_spec+
;
declare_spec
: pragma_declaration
| exception_declaration
| procedure_spec
| function_spec
| variable_declaration
| subtype_declaration
| cursor_declaration
| type_declaration
| procedure_body
| function_body
| selection_directive
;
// incorporates constant_declaration
variable_declaration
: identifier CONSTANT? type_spec (NOT? NULL_)? default_value_part? ';'
;
subtype_declaration
: SUBTYPE identifier IS type_spec (RANGE expression '..' expression)? (NOT NULL_)? ';'
;
// cursor_declaration incorportates curscursor_body and cursor_spec
cursor_declaration
: CURSOR identifier ('(' parameter_spec (',' parameter_spec)* ')')? (RETURN type_spec)? (
IS select_statement
)? ';'
;
parameter_spec
: parameter_name (IN? type_spec)? default_value_part?
;
exception_declaration
: identifier EXCEPTION ';'
;
pragma_declaration
: PRAGMA (
SERIALLY_REUSABLE
| AUTONOMOUS_TRANSACTION
| EXCEPTION_INIT '(' exception_name ',' numeric_negative ')'
| INLINE '(' id1 = identifier ',' expression ')'
| RESTRICT_REFERENCES '(' (identifier | DEFAULT) (',' identifier)+ ')'
| DEPRECATE '(' identifier ( ',' CHAR_STRING)? ')'
| UDF
) ';'
;
// Record Declaration Specific Clauses
// incorporates ref_cursor_type_definition
record_type_def
: RECORD '(' field_spec (',' field_spec)* ')'
;
field_spec
: column_name type_spec? (NOT NULL_)? default_value_part?
;
ref_cursor_type_def
: REF CURSOR (RETURN type_spec)?
;
type_declaration
: TYPE identifier IS (table_type_def | varray_type_def | record_type_def | ref_cursor_type_def) ';'
;
table_type_def
: TABLE OF type_spec (NOT NULL_)? table_indexed_by_part?
;
table_indexed_by_part
: (idx1 = INDEXED | idx2 = INDEX) BY type_spec
;
//https://docs.oracle.com/en/database/oracle/oracle-database/21/lnpls/collection-variable.html#GUID-89A1863C-65A1-40CF-9392-86E9FDC21BE9
varray_type_def
: (VARRAY | VARYING? ARRAY) '(' expression ')' OF type_spec (NOT NULL_)?
;
// Statements
seq_of_statements
: (pragma_declaration* statement (';' | EOF) | label_declaration | selection_directive)+
;
label_declaration
: ltp1 = '<' '<' label_name '>' '>'
;
statement
: body
| block
| assignment_statement
| continue_statement
| exit_statement
| goto_statement
| if_statement
| loop_statement
| forall_statement
| null_statement
| raise_statement
| return_statement
| case_statement
| sql_statement
| call_statement
| pipe_row_statement
| grant_statement
;
assignment_statement
: (general_element | bind_variable) ASSIGN_OP expression
;
continue_statement
: CONTINUE label_name? (WHEN condition)?
;
exit_statement
: EXIT label_name? (WHEN condition)?
;
goto_statement
: GOTO label_name
;
if_statement
: IF condition THEN seq_of_statements elsif_part* else_part? END IF
;
elsif_part
: ELSIF condition THEN seq_of_statements
;
else_part
: ELSE seq_of_statements
;
loop_statement
: label_declaration? (WHILE condition | FOR cursor_loop_param)? LOOP seq_of_statements END LOOP label_name?
;
// Loop Specific Clause
cursor_loop_param
: index_name IN REVERSE? lower_bound range_separator = '..' upper_bound
| record_name IN (cursor_name ('(' expressions_? ')')? | '(' select_statement ')')
;
//https://docs.oracle.com/en/database/oracle/oracle-database/21/lnpls/FORALL-statement.html#GUID-C45B8241-F9DF-4C93-8577-C840A25963DB
forall_statement
: FORALL index_name IN bounds_clause (SAVE EXCEPTIONS)? (data_manipulation_language_statements | execute_immediate)
;
bounds_clause
: lower_bound '..' upper_bound
| INDICES OF general_element between_bound?
| VALUES OF index_name
;
between_bound
: BETWEEN lower_bound AND upper_bound
;
lower_bound
: concatenation
;
upper_bound
: concatenation
;
null_statement
: NULL_
;
raise_statement
: RAISE exception_name?
;
return_statement
: RETURN expression?
;
call_statement
: CALL? routine_name function_argument? ('.' routine_name function_argument?)* (
INTO bind_variable
)?
;
pipe_row_statement
: PIPE ROW '(' expression ')'
;
selection_directive
: DOLLAR_IF condition DOLLAR_THEN selection_directive_body (
DOLLAR_ELSIF selection_directive_body
)* (DOLLAR_ELSE selection_directive_body)? DOLLAR_END
;
error_directive
: DOLLAR_ERROR concatenation DOLLAR_END
;
selection_directive_body
: (
pragma_declaration? statement ';'
| variable_declaration
| error_directive
| function_body
| procedure_body
)+
;
body
: BEGIN seq_of_statements (EXCEPTION exception_handler+)? END label_name?
;
// Body Specific Clause
exception_handler
: WHEN exception_name (OR exception_name)* THEN seq_of_statements
;
trigger_block
: (DECLARE declare_spec*)? body
;
tps_block
: declare_spec* body
;
block
: (DECLARE declare_spec*)? body
;
// SQL Statements
sql_statement
: execute_immediate
| data_manipulation_language_statements
| cursor_manipulation_statements
| transaction_control_statements
| collection_method_call
;
execute_immediate
: EXECUTE IMMEDIATE expression (
into_clause using_clause?
| using_clause dynamic_returning_clause?
| dynamic_returning_clause
)?
;
// Execute Immediate Specific Clause
dynamic_returning_clause
: (RETURNING | RETURN) into_clause
;
// DML Statements
data_manipulation_language_statements
: merge_statement
| lock_table_statement
| select_statement
| update_statement
| delete_statement
| insert_statement
| explain_statement
;
// Cursor Manipulation Statements
cursor_manipulation_statements
: close_statement
| open_statement
| fetch_statement
| open_for_statement
;
close_statement
: CLOSE cursor_name
;
open_statement
: OPEN cursor_name ('(' expressions_? ')')?
;
fetch_statement
: FETCH cursor_name (
it1 = INTO variable_or_collection (',' variable_or_collection)*
| BULK COLLECT INTO variable_or_collection (',' variable_or_collection)* (
LIMIT (numeric | variable_or_collection)
)?
)
;
variable_or_collection
: variable_name
| collection_expression
;
open_for_statement
: OPEN variable_name FOR (select_statement | expression) using_clause?
;
// Transaction Control SQL Statements
transaction_control_statements
: set_transaction_command
| set_constraint_command
| commit_statement
| rollback_statement
| savepoint_statement
;
set_transaction_command
: SET TRANSACTION (
READ (ONLY | WRITE)
| ISOLATION LEVEL (SERIALIZABLE | READ COMMITTED)
| USE ROLLBACK SEGMENT rollback_segment_name
)? (NAME quoted_string)?
;
set_constraint_command
: SET (CONSTRAINT | CONSTRAINTS) (ALL | constraint_name (',' constraint_name)*) (
IMMEDIATE
| DEFERRED
)
;
// https://docs.oracle.com/cd/E18283_01/server.112/e17118/statements_4010.htm#SQLRF01110
// https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/COMMIT.html
commit_statement
: COMMIT WORK? write_clause? (
COMMENT CHAR_STRING write_clause?
| FORCE (CHAR_STRING (',' numeric)? | CORRUPT_XID CHAR_STRING | CORRUPT_XID_ALL)
)?
;
write_clause
: WRITE (
(IMMEDIATE | BATCH)
| (WAIT | NOWAIT)
)*
;
rollback_statement
: ROLLBACK WORK? (TO SAVEPOINT? savepoint_name | FORCE quoted_string)?
;
savepoint_statement
: SAVEPOINT savepoint_name
;
// https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/collection-method.html#GUID-7AF1A3C4-D04B-4F91-9D7B-C92C75E3A300
collection_method_call // collection methods invocation that could be used as a statement
: expression '.' (
(DELETE | EXTEND) ('(' index += expression (',' index += expression)* ')')?
| TRIM ('(' index += expression ')')?
)
;
// Dml
/* TODO
//SHOULD BE OVERRIDEN!
compilation_unit
: seq_of_statements* EOF
;
//SHOULD BE OVERRIDEN!
seq_of_statements
: select_statement
| update_statement
| delete_statement
| insert_statement
| lock_table_statement
| merge_statement
| explain_statement
// | case_statement[true]
;
*/
explain_statement
: EXPLAIN PLAN (SET STATEMENT_ID '=' quoted_string)? (INTO tableview_name)? FOR (
select_statement
| update_statement
| delete_statement
| insert_statement
| merge_statement
)
;
select_only_statement
: with_clause? subquery
;
select_statement
: select_only_statement (for_update_clause | order_by_clause | offset_clause | fetch_clause)*
;
// Select Specific Clauses
with_clause
: WITH (function_body | procedure_body)* with_factoring_clause (',' with_factoring_clause)*
| WITH (function_body | procedure_body)+ (with_factoring_clause (',' with_factoring_clause)*)?
;
with_factoring_clause
: subquery_factoring_clause
| subav_factoring_clause
;
subquery_factoring_clause
: query_name paren_column_list? AS '(' subquery order_by_clause? ')' search_clause? cycle_clause?
;
search_clause
: SEARCH (DEPTH | BREADTH) FIRST BY column_name ASC? DESC? (NULLS FIRST)? (NULLS LAST)? (
',' column_name ASC? DESC? (NULLS FIRST)? (NULLS LAST)?
)* SET column_name
;
cycle_clause
: CYCLE column_list SET column_name TO expression DEFAULT expression
;
subav_factoring_clause
: subav_name = id_expression ANALYTIC VIEW AS '(' subav_clause ')'
;
subav_clause
: USING subav_name = object_name hierarchies_clause? filter_clauses? add_calcs_clause?
;
hierarchies_clause
: HIERARCHIES '(' hier_alias += object_name (',' hier_alias += object_name)* ')'
;
filter_clauses
: FILTER FACT '(' filter_clause (',' filter_clause)* ')'
;
filter_clause
: (MEASURES | hier_alias = object_name) TO condition
;
add_calcs_clause
: ADD MEASURES '(' add_calc_meas_clause (',' add_calc_meas_clause)* ')'
;
add_calc_meas_clause
: meas_name = id_expression AS '(' expression ')'
;
subquery
: subquery_basic_elements subquery_operation_part*
;
subquery_basic_elements
: query_block
| '(' subquery ')'
;
subquery_operation_part
: (UNION ALL? | INTERSECT | MINUS) subquery_basic_elements
;
query_block
: SELECT (DISTINCT | UNIQUE | ALL)? selected_list into_clause? from_clause where_clause? (
hierarchical_query_clause
| group_by_clause
)* model_clause? order_by_clause? offset_clause? fetch_clause?
;
selected_list
: '*'
| select_list_elements (',' select_list_elements)*
;
from_clause
: FROM table_ref_list
;
select_list_elements
: tableview_name '.' ASTERISK
| expression column_alias?
;
table_ref_list
: table_ref (',' table_ref)*
;
// NOTE to PIVOT clause
// according the SQL reference this should not be possible
// according to he reality it is. Here we probably apply pivot/unpivot onto whole join clause
// eventhough it is not enclosed in parenthesis. See pivot examples 09,10,11
table_ref
: table_ref_aux join_clause* (pivot_clause | unpivot_clause)?
;
table_ref_aux
: table_ref_aux_internal flashback_query_clause* (/*{isTableAlias()}?*/ table_alias)?
;
table_ref_aux_internal
: dml_table_expression_clause (pivot_clause | unpivot_clause)? # table_ref_aux_internal_one
| '(' table_ref subquery_operation_part* ')' (pivot_clause | unpivot_clause)? # table_ref_aux_internal_two
| ONLY '(' dml_table_expression_clause ')' # table_ref_aux_internal_thre
;
join_clause
: query_partition_clause? (CROSS | NATURAL)? (INNER | outer_join_type)? JOIN table_ref_aux query_partition_clause? (
join_on_part
| join_using_part
)*
| (CROSS | OUTER) APPLY table_ref_aux
;
join_on_part
: ON condition
;
join_using_part
: USING paren_column_list
;
outer_join_type
: (FULL | LEFT | RIGHT) OUTER?
;
query_partition_clause
: PARTITION BY (('(' (subquery | expressions_)? ')') | expressions_)
;
flashback_query_clause
: VERSIONS (PERIOD_KEYWORD FOR column_name BETWEEN | BETWEEN (SCN | TIMESTAMP)) expression AND expression
| AS OF ((SCN | TIMESTAMP | SNAPSHOT) expression | PERIOD_KEYWORD FOR column_name expression)
;
pivot_clause
: PIVOT XML? '(' pivot_element (',' pivot_element)* pivot_for_clause pivot_in_clause ')' table_alias?
;
pivot_element
: (numeric_function | aggregate_function_name '(' expression ')') column_alias?
;
pivot_for_clause
: FOR (column_name | paren_column_list)
;
pivot_in_clause
: IN '(' (subquery | ANY (',' ANY)* | pivot_in_clause_element (',' pivot_in_clause_element)*) ')'
;
pivot_in_clause_element
: pivot_in_clause_elements column_alias?
;
pivot_in_clause_elements
: expression
| '(' expressions_? ')'
;
unpivot_clause
: UNPIVOT ((INCLUDE | EXCLUDE) NULLS)? '(' (column_name | paren_column_list) pivot_for_clause unpivot_in_clause ')' table_alias?
;
unpivot_in_clause
: IN '(' unpivot_in_elements (',' unpivot_in_elements)* ')'
;
unpivot_in_elements
: (column_name | paren_column_list) (AS (constant | '(' constant (',' constant)* ')'))?
;
hierarchical_query_clause
: CONNECT BY NOCYCLE? condition start_part?
| start_part CONNECT BY NOCYCLE? condition
;
start_part
: START WITH condition
;
group_by_clause
: GROUP BY group_by_elements (',' group_by_elements)* having_clause?
| having_clause (GROUP BY group_by_elements (',' group_by_elements)*)?
;
group_by_elements
: grouping_sets_clause
| rollup_cube_clause
| expression
;
rollup_cube_clause
: (ROLLUP | CUBE) '(' grouping_sets_elements (',' grouping_sets_elements)* ')'
;
grouping_sets_clause
: GROUPING SETS '(' grouping_sets_elements (',' grouping_sets_elements)* ')'
;
grouping_sets_elements
: rollup_cube_clause
| '(' expressions_? ')'
| expression
;
having_clause
: HAVING condition
;
model_clause
: MODEL cell_reference_options* return_rows_clause? reference_model* main_model
;
cell_reference_options
: (IGNORE | KEEP) NAV
| UNIQUE (DIMENSION | SINGLE REFERENCE)
;
return_rows_clause
: RETURN (UPDATED | ALL) ROWS
;
reference_model
: REFERENCE reference_model_name ON '(' subquery ')' model_column_clauses cell_reference_options*
;
main_model
: (MAIN main_model_name)? model_column_clauses cell_reference_options* model_rules_clause
;
model_column_clauses
: model_column_partition_part? DIMENSION BY model_column_list MEASURES model_column_list
;
model_column_partition_part
: PARTITION BY model_column_list
;
model_column_list
: '(' model_column (',' model_column)* ')'
;
model_column
: (expression | query_block) column_alias?
;
model_rules_clause
: model_rules_part? '(' (model_rules_element (',' model_rules_element)*)? ')'
;
model_rules_part
: RULES (UPDATE | UPSERT ALL?)? ((AUTOMATIC | SEQUENTIAL) ORDER)? model_iterate_clause?
;
model_rules_element
: (UPDATE | UPSERT ALL?)? cell_assignment order_by_clause? '=' expression
;
cell_assignment
: model_expression
;
model_iterate_clause
: ITERATE '(' expression ')' until_part?
;
until_part
: UNTIL '(' condition ')'
;
order_by_clause
: ORDER SIBLINGS? BY order_by_elements (',' order_by_elements)*
;
order_by_elements
: expression (ASC | DESC)? (NULLS (FIRST | LAST))?
;
offset_clause
: OFFSET expression (ROW | ROWS)
;
fetch_clause
: FETCH (FIRST | NEXT) (expression PERCENT_KEYWORD?)? (ROW | ROWS) (ONLY | WITH TIES)
;
for_update_clause
: FOR UPDATE for_update_of_part? for_update_options?
;
for_update_of_part
: OF column_list
;
for_update_options
: SKIP_ LOCKED
| NOWAIT
| WAIT expression
;
update_statement
: UPDATE general_table_ref update_set_clause where_clause? static_returning_clause? error_logging_clause?
;
// Update Specific Clauses
update_set_clause
: SET (
column_based_update_set_clause (',' column_based_update_set_clause)*
| VALUE '(' identifier ')' '=' expression
)
;
column_based_update_set_clause
: column_name '=' expression
| paren_column_list '=' subquery
;
delete_statement
: DELETE FROM? general_table_ref where_clause? static_returning_clause? error_logging_clause?
;
insert_statement
: INSERT (single_table_insert | multi_table_insert)
;
// Insert Specific Clauses
single_table_insert
: insert_into_clause (values_clause static_returning_clause? | select_statement) error_logging_clause?
;
multi_table_insert
: (ALL multi_table_element+ | conditional_insert_clause) select_statement
;
multi_table_element
: insert_into_clause values_clause? error_logging_clause?
;
conditional_insert_clause
: (ALL | FIRST)? conditional_insert_when_part+ conditional_insert_else_part?
;
conditional_insert_when_part
: WHEN condition THEN multi_table_element+
;
conditional_insert_else_part
: ELSE multi_table_element+
;
insert_into_clause
: INTO general_table_ref (FIELDS)? paren_column_list?
;
values_clause
: VALUES (REGULAR_ID | '(' expressions_ ')' | collection_expression)
;
merge_statement
: MERGE INTO tableview_name table_alias? USING selected_tableview ON '(' condition ')' (
merge_update_clause merge_insert_clause?
| merge_insert_clause merge_update_clause?
)? error_logging_clause?
;
// Merge Specific Clauses
merge_update_clause
: WHEN MATCHED THEN UPDATE SET merge_element (',' merge_element)* where_clause? merge_update_delete_part?
;
merge_element
: column_name '=' expression
;
merge_update_delete_part
: DELETE where_clause
;
merge_insert_clause
: WHEN NOT MATCHED THEN INSERT paren_column_list? values_clause where_clause?
;
selected_tableview
: ( tableview_name | '(' select_statement ')' | table_collection_expression | '(' table_collection_expression ')') table_alias?
;
lock_table_statement
: LOCK TABLE lock_table_element (',' lock_table_element)* IN lock_mode MODE wait_nowait_part?
;
wait_nowait_part
: WAIT expression
| NOWAIT
;
// Lock Specific Clauses
lock_table_element
: tableview_name partition_extension_clause?
;
lock_mode
: ROW SHARE
| ROW EXCLUSIVE
| SHARE UPDATE?
| SHARE ROW EXCLUSIVE
| EXCLUSIVE
;
// Common DDL Clauses
general_table_ref
: (dml_table_expression_clause | ONLY '(' dml_table_expression_clause ')') table_alias?
;
static_returning_clause
: (RETURNING | RETURN) expressions_ into_clause
;
error_logging_clause
: LOG ERRORS error_logging_into_part? expression? error_logging_reject_part?
;
error_logging_into_part
: INTO tableview_name
;
error_logging_reject_part
: REJECT LIMIT (UNLIMITED | expression)
;
dml_table_expression_clause
: table_collection_expression
| '(' select_statement subquery_restriction_clause? ')'
| tableview_name hierarchies_clause? sample_clause?
| json_table_clause (AS identifier)?
| LATERAL '(' subquery subquery_restriction_clause? ')'
// Deprecated Oracle 10/11 RELATIONAL alias for casting object-types to relational tables
| {this.isVersion11()}? (RELATIONAL '(' tableview_name NOT XMLTYPE ')')
;
table_collection_expression
: (TABLE | THE) ('(' subquery ')' | '(' expression ')' outer_join_sign?)
;
subquery_restriction_clause
: WITH (READ ONLY | CHECK OPTION (CONSTRAINT constraint_name)?)
;
sample_clause
: SAMPLE BLOCK? '(' expression (',' expression)? ')' seed_part?
;
seed_part
: SEED '(' expression ')'
;
// Expression & Condition
condition
: expression
| JSON_EQUAL '(' expressions_ ')'
;
expressions_
: expression (',' expression)*
;
expression
: cursor_expression
| logical_expression
;
cursor_expression
: CURSOR '(' subquery ')'
;
logical_expression
: unary_logical_expression
| logical_expression AND logical_expression
| logical_expression OR logical_expression
;
unary_logical_expression
: NOT? multiset_expression unary_logical_operation?
;
unary_logical_operation
: IS NOT? logical_operation
;
logical_operation
: (
NULL_
| NAN_
| PRESENT
| INFINITE
| A_LETTER SET
| EMPTY_
| OF TYPE? '(' ONLY? type_spec (',' type_spec)* ')'
| JSON (FORMAT JSON)? (STRICT | LAX)? ((WITH | WITHOUT) UNIQUE KEYS)?
)
;
multiset_expression
: relational_expression (multiset_type = NOT? (MEMBER | SUBMULTISET) OF? concatenation)?
| multiset_expression MULTISET multiset_operator = (EXCEPT | INTERSECT | UNION) (
ALL
| DISTINCT
)? relational_expression
;
relational_expression
: relational_expression relational_operator relational_expression
| relational_expression NOT? IN in_elements
| compound_expression
;
compound_expression
: concatenation (
NOT? (
IN in_elements
| BETWEEN between_elements
| like_type = (LIKE | LIKEC | LIKE2 | LIKE4) concatenation (ESCAPE concatenation)?
)
)?
;
relational_operator
: '='
| (NOT_EQUAL_OP | '<' '>' | '!' '=' | '^' '=')
| ('<' | '>') '='?
;
in_elements
: '(' subquery ')'
| '(' concatenation (',' concatenation)* ')'
| constant
| bind_variable
| general_element
;
between_elements
: concatenation AND concatenation
;
concatenation
: model_expression (AT (LOCAL | TIME ZONE concatenation) | interval_expression)? (
ON OVERFLOW_ (TRUNCATE | ERROR)
)?
| concatenation op = DOUBLE_ASTERISK concatenation
| concatenation op = (ASTERISK | SOLIDUS | MOD) concatenation
| concatenation op = (PLUS_SIGN | MINUS_SIGN) concatenation
| concatenation BAR BAR concatenation
| concatenation COLLATE column_collation_name
;
interval_expression
: DAY ('(' concatenation ')')? TO SECOND ('(' concatenation ')')?
| YEAR ('(' concatenation ')')? TO MONTH
| concatenation (SECOND | DAY | MONTH | YEAR)
;
model_expression
: unary_expression ('[' model_expression_element ']')?
;
model_expression_element
: (ANY | expression) (',' (ANY | expression))*
| single_column_for_loop (',' single_column_for_loop)*
| multi_column_for_loop
;
single_column_for_loop
: FOR column_name (
IN '(' expressions_? ')'
| (LIKE expression)? FROM fromExpr = expression TO toExpr = expression action_type = (
INCREMENT
| DECREMENT
) action_expr = expression
)
;
multi_column_for_loop
: FOR paren_column_list IN '(' (subquery | '(' expressions_? ')') ')'
;
unary_expression
: ('-' | '+') unary_expression
| PRIOR unary_expression
| CONNECT_BY_ROOT unary_expression
| /*TODO {input.LT(1).getText().equalsIgnoreCase("new") && !input.LT(2).getText().equals(".")}?*/ NEW unary_expression
| DISTINCT unary_expression
| ALL unary_expression
| /*TODO{(input.LA(1) == CASE || input.LA(2) == CASE)}?*/ case_expression
| unary_expression '.' (
(COUNT | FIRST | LAST | LIMIT)
| (EXISTS | NEXT | PRIOR) '(' index += expression ')'
)
| quantified_expression
| standard_function
| atom
| implicit_cursor_expression
;
// https://docs.oracle.com/en/database/oracle/oracle-database/21/lnpls/plsql-optimization-and-tuning.html#GUID-DAF46F06-EF3F-4B1A-A518-5238B80C69FA
implicit_cursor_expression
: SQL (
PERCENT_BULK_ROWCOUNT '(' index = expression ')'
| PERCENT_BULK_EXCEPTIONS ('.' COUNT | '(' expression ')' '.' (ERROR_INDEX | ERROR_CODE))
)
;
collection_expression
: collation_name '(' expression ')' ('.' general_element_part)*
;
// CASE statement
case_statement
: searched_case_statement
| simple_case_statement
;
simple_case_statement
: label_declaration? ck1 = CASE expression case_when_part_statement+ case_else_part_statement? END CASE? label_name?
;
searched_case_statement
: label_declaration? ck1 = CASE case_when_part_statement+ case_else_part_statement? END CASE? label_name?
;
case_when_part_statement
: WHEN expression THEN seq_of_statements
;
case_else_part_statement
: ELSE seq_of_statements
;
// CASE expression
case_expression
: searched_case_expression
| simple_case_expression
;
simple_case_expression
: ck1 = CASE expression case_when_part_expression+ case_else_part_expression? END CASE?
;
searched_case_expression
: ck1 = CASE case_when_part_expression+ case_else_part_expression? END CASE?
;
case_when_part_expression
: WHEN expression THEN expression
;
case_else_part_expression
: ELSE expression
;
atom
: bind_variable
| constant
| inquiry_directive
| general_element outer_join_sign?
| '(' subquery ')' subquery_operation_part*
| '(' expressions_ ')'
;
quantified_expression
: (SOME | EXISTS | ALL | ANY) (
'(' select_only_statement ')'
| '(' expression (',' expression)* ')'
)
;
string_function
: SUBSTR '(' expression ',' expression (',' expression)? ')'
| TO_CHAR '(' (table_element | standard_function | expression) (',' quoted_string)? (
',' quoted_string
)? ')'
| DECODE '(' expressions_ ')'
| CHR '(' concatenation USING NCHAR_CS ')'
| NVL '(' expression ',' expression ')'
| TRIM '(' ((LEADING | TRAILING | BOTH)? expression? FROM)? concatenation ')'
| TO_DATE '(' (table_element | standard_function | expression) (
DEFAULT concatenation ON CONVERSION ERROR
)? (',' quoted_string (',' quoted_string)?)? ')'
;
standard_function
: string_function
| numeric_function_wrapper
| json_function
| other_function
;
//see as https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/JSON_ARRAY.html#GUID-46CDB3AF-5795-455B-85A8-764528CEC43B
json_function
: JSON_ARRAY '(' json_array_element (',' json_array_element)* json_on_null_clause? json_return_clause? STRICT? ')'
| JSON_ARRAYAGG '(' expression (FORMAT JSON)? order_by_clause? json_on_null_clause? json_return_clause? STRICT? ')'
| JSON_OBJECT '(' json_object_content ')'
| JSON_OBJECTAGG '(' KEY? expression VALUE expression ((NULL_ | ABSENT) ON NULL_)? (
RETURNING (VARCHAR2 ('(' UNSIGNED_INTEGER ( BYTE | CHAR)? ')')? | CLOB | BLOB)
)? STRICT? (WITH UNIQUE KEYS)? ')'
| JSON_QUERY '(' expression (FORMAT JSON)? ',' CHAR_STRING json_query_returning_clause json_query_wrapper_clause? json_query_on_error_clause?
json_query_on_empty_clause? ')'
| JSON_SERIALIZE '(' CHAR_STRING (RETURNING json_query_return_type)? PRETTY? ASCII? TRUNCATE? (
(NULL_ | ERROR | EMPTY_ (ARRAY | OBJECT)) ON ERROR
)? ')'
| JSON_TRANSFORM '(' expression ',' json_transform_op (',' json_transform_op)* ')'
| JSON_VALUE '(' expression (FORMAT JSON)? (
',' CHAR_STRING? json_value_return_clause? ((ERROR | NULL_ | DEFAULT literal)? ON ERROR)? (
(ERROR | NULL_ | DEFAULT literal)? ON EMPTY_
)? json_value_on_mismatch_clause? ')'
)?
;
json_object_content
: (json_object_entry (',' json_object_entry)* | '*') json_on_null_clause? json_return_clause? STRICT? (
WITH UNIQUE KEYS
)?
;
json_object_entry
: (KEY? expression (VALUE | IS)? expression | expression ':' expression | identifier) (
FORMAT JSON
)?
;
json_table_clause
: JSON_TABLE '(' expression (FORMAT JSON)? (',' CHAR_STRING)? ((ERROR | NULL_) ON ERROR)? (
(EMPTY_ | NULL_) ON EMPTY_
)? json_column_clause? ')'
;
json_array_element
: (expression | CHAR_STRING | NULL_ | UNSIGNED_INTEGER | json_function) (FORMAT JSON)?
;
json_on_null_clause
: (NULL_ | ABSENT) ON NULL_
;
json_return_clause
: RETURNING (VARCHAR2 ('(' UNSIGNED_INTEGER ( BYTE | CHAR)? ')')? | CLOB | BLOB)
;
json_transform_op
: REMOVE CHAR_STRING ((IGNORE | ERROR)? ON MISSING)?
| INSERT CHAR_STRING '=' CHAR_STRING ((REPLACE | IGNORE | ERROR) ON EXISTING)? (
(NULL_ | IGNORE | ERROR | REMOVE)? ON NULL_
)?
| REPLACE CHAR_STRING '=' CHAR_STRING ((CREATE | IGNORE | ERROR) ON MISSING)? (
(NULL_ | IGNORE | ERROR)? ON NULL_
)?
| expression (FORMAT JSON)?
| APPEND CHAR_STRING '=' CHAR_STRING ((CREATE | IGNORE | ERROR) ON MISSING)? (
(NULL_ | IGNORE | ERROR)? ON NULL_
)?
| SET CHAR_STRING '=' expression (FORMAT JSON)? ((REPLACE | IGNORE | ERROR) ON EXISTING)? (
(CREATE | IGNORE | ERROR) ON MISSING
)? ((NULL_ | IGNORE | ERROR)? ON NULL_)?
;
json_column_clause
: COLUMNS '(' json_column_definition (',' json_column_definition)* ')'
;
json_column_definition
: expression json_value_return_type? (EXISTS? PATH CHAR_STRING | TRUNCATE (PATH CHAR_STRING)?)? json_query_on_error_clause?
json_query_on_empty_clause?
| expression json_query_return_type? TRUNCATE? FORMAT JSON json_query_wrapper_clause? PATH CHAR_STRING
| NESTED PATH? expression ('[' ASTERISK ']')? json_column_clause
| expression FOR ORDINALITY
;
json_query_returning_clause
: (RETURNING json_query_return_type)? PRETTY? ASCII?
;
json_query_return_type
: VARCHAR2 ('(' UNSIGNED_INTEGER ( BYTE | CHAR)? ')')?
| CLOB
| BLOB
;
json_query_wrapper_clause
: (WITHOUT ARRAY? WRAPPER)
| (WITH (UNCONDITIONAL | CONDITIONAL)? ARRAY? WRAPPER)
;
json_query_on_error_clause
: (ERROR | NULL_ | EMPTY_ | EMPTY_ ARRAY | EMPTY_ OBJECT)? ON ERROR
;
json_query_on_empty_clause
: (ERROR | NULL_ | EMPTY_ | EMPTY_ ARRAY | EMPTY_ OBJECT)? ON EMPTY_
;
json_value_return_clause
: RETURNING json_value_return_type? ASCII?
;
json_value_return_type
: VARCHAR2 ('(' UNSIGNED_INTEGER ( BYTE | CHAR)? ')')? TRUNCATE?
| CLOB
| DATE
| NUMBER ('(' INTEGER (',' INTEGER)? ')')?
| TIMESTAMP (WITH TIMEZONE)?
| SDO_GEOMETRY
| expression (USING CASESENSITIVE MAPPING)?
;
json_value_on_mismatch_clause
: (IGNORE | ERROR | NULL_) ON MISMATCH ('(' MISSING DATA | EXTRA DATA | TYPE ERROR ')')?
;
literal
: CHAR_STRING
| string_function
| numeric
| numeric_negative
| MAXVALUE
;
numeric_function_wrapper
: numeric_function (single_column_for_loop | multi_column_for_loop)?
;
numeric_function
: SUM '(' (DISTINCT | ALL)? expression ')'
| COUNT '(' (ASTERISK | ((DISTINCT | UNIQUE | ALL)? concatenation)?) ')' over_clause?
| ROUND '(' expression (',' UNSIGNED_INTEGER)? ')'
| AVG '(' (DISTINCT | ALL)? expression ')'
| MAX '(' (DISTINCT | ALL)? expression ')'
| LEAST '(' expressions_ ')'
| GREATEST '(' expressions_ ')'
;
listagg_overflow_clause
: ON OVERFLOW_ (ERROR | TRUNCATE) CHAR_STRING? ((WITH | WITHOUT) COUNT)?
;
other_function
: over_clause_keyword function_argument_analytic over_clause?
| /*TODO stantard_function_enabling_using*/ regular_id function_argument_modeling using_clause?
| COUNT '(' (ASTERISK | (DISTINCT | UNIQUE | ALL)? concatenation) ')' over_clause?
| (CAST | XMLCAST) '(' (MULTISET '(' subquery ')' | concatenation) AS type_spec (
DEFAULT concatenation ON CONVERSION ERROR
)? (',' quoted_string (',' quoted_string)?)? ')'
| COALESCE '(' table_element (',' (numeric | quoted_string))? ')'
| COLLECT '(' (DISTINCT | UNIQUE)? concatenation collect_order_by_part? ')'
| within_or_over_clause_keyword function_argument within_or_over_part+
// Modified to allow expressions as delimiter to LISTAGG
| LISTAGG '(' (ALL | DISTINCT | UNIQUE)? argument (',' expression)? listagg_overflow_clause? ')' (
WITHIN GROUP '(' order_by_clause ')'
)? over_clause?
| cursor_name (PERCENT_ISOPEN | PERCENT_FOUND | PERCENT_NOTFOUND | PERCENT_ROWCOUNT)
| DECOMPOSE '(' concatenation (CANONICAL | COMPATIBILITY)? ')'
| EXTRACT '(' regular_id FROM concatenation ')'
| (FIRST_VALUE | LAST_VALUE) function_argument_analytic respect_or_ignore_nulls? over_clause
| (LEAD | LAG) function_argument_analytic respect_or_ignore_nulls? over_clause
| standard_prediction_function_keyword '(' expressions_ cost_matrix_clause? using_clause? ')'
| (TO_BINARY_DOUBLE | TO_BINARY_FLOAT | TO_NUMBER | TO_TIMESTAMP | TO_TIMESTAMP_TZ) '(' concatenation (
DEFAULT concatenation ON CONVERSION ERROR
)? (',' quoted_string (',' quoted_string)?)? ')'
| (TO_DSINTERVAL | TO_YMINTERVAL) '(' concatenation (DEFAULT concatenation ON CONVERSION ERROR)? ')'
| TRANSLATE '(' expression (USING (CHAR_CS | NCHAR_CS))? (',' expression)* ')'
| TREAT '(' expression AS REF? type_spec ')' ('.' general_element_part)*
| TRIM '(' ((LEADING | TRAILING | BOTH)? quoted_string? FROM)? concatenation ')'
| VALIDATE_CONVERSION '(' concatenation AS type_spec (',' quoted_string (',' quoted_string)?)? ')'
| XMLAGG '(' expression order_by_clause? ')' ('.' general_element_part)*
| (XMLCOLATTVAL | XMLFOREST) '(' xml_multiuse_expression_element (
',' xml_multiuse_expression_element
)* ')' ('.' general_element_part)*
| XMLELEMENT '(' (ENTITYESCAPING | NOENTITYESCAPING)? (NAME | EVALNAME)? expression (
/*TODO{input.LT(2).getText().equalsIgnoreCase("xmlattributes")}?*/ ',' xml_attributes_clause
)? (',' expression column_alias?)* ')' ('.' general_element_part)*
| XMLEXISTS '(' expression xml_passing_clause? ')'
| XMLPARSE '(' (DOCUMENT | CONTENT) concatenation WELLFORMED? ')' ('.' general_element_part)*
| XMLPI '(' (NAME identifier | EVALNAME concatenation) (',' concatenation)? ')' (
'.' general_element_part
)*
| XMLQUERY '(' concatenation xml_passing_clause? RETURNING CONTENT (NULL_ ON EMPTY_)? ')' (
'.' general_element_part
)*
| XMLROOT '(' concatenation (',' xmlroot_param_version_part)? (
',' xmlroot_param_standalone_part
)? ')' ('.' general_element_part)*
| XMLSERIALIZE '(' (DOCUMENT | CONTENT) concatenation (AS type_spec)? xmlserialize_param_enconding_part? xmlserialize_param_version_part?
xmlserialize_param_ident_part? ((HIDE | SHOW) DEFAULTS)? ')' ('.' general_element_part)?
| TIME CHAR_STRING
| xmltable
;
over_clause_keyword
: AVG
| CORR
| LAG_DIFF
| LAG_DIFF_PERCENT
| MAX
| MEDIAN
| MIN
| NTH_VALUE
| NTILE
| RATIO_TO_REPORT
| ROW_NUMBER
| SUM
| VARIANCE
| REGR_
| STDDEV
| VAR_
| VAR_POP
| COVAR_
| WM_CONCAT
;
within_or_over_clause_keyword
: CUME_DIST
| DENSE_RANK
| PERCENT_RANK
| PERCENTILE_CONT
| PERCENTILE_DISC
| RANK
;
standard_prediction_function_keyword
: PREDICTION
| PREDICTION_BOUNDS
| PREDICTION_COST
| PREDICTION_DETAILS
| PREDICTION_PROBABILITY
| PREDICTION_SET
;
over_clause
: OVER '(' (
query_partition_clause? (order_by_clause windowing_clause?)?
| HIERARCHY th = id_expression OFFSET numeric (ACROSS ANCESTOR AT LEVEL id_expression)?
) ')'
;
windowing_clause
: windowing_type (BETWEEN windowing_elements AND windowing_elements | windowing_elements)
;
windowing_type
: ROWS
| RANGE
;
windowing_elements
: UNBOUNDED PRECEDING
| CURRENT ROW
| concatenation (PRECEDING | FOLLOWING)
;
using_clause
: USING (ASTERISK | using_element (',' using_element)*)
;
using_element
: IN expression
| IN OUT assignable_element
| OUT assignable_element
| expression
;
// Elemento assegnabile: usato per OUT/IN OUT
assignable_element
: general_element
| bind_variable
;
collect_order_by_part
: ORDER BY concatenation (',' concatenation)*
;
within_or_over_part
: WITHIN GROUP '(' order_by_clause ')'
| over_clause
;
string_delimiter
: CHAR_STRING
| string_function
| string_delimiter BAR BAR string_delimiter
| '(' string_delimiter ')'
| id_expression
;
cost_matrix_clause
: COST (
MODEL AUTO?
| '(' cost_class_name (',' cost_class_name)* ')' VALUES '(' expressions_? ')'
)
;
xml_passing_clause
: PASSING (BY VALUE)? expression column_alias? (',' expression column_alias?)*
;
xml_attributes_clause
: XMLATTRIBUTES '(' (ENTITYESCAPING | NOENTITYESCAPING)? (SCHEMACHECK | NOSCHEMACHECK)? xml_multiuse_expression_element (
',' xml_multiuse_expression_element
)* ')'
;
xml_namespaces_clause
: XMLNAMESPACES '(' (concatenation column_alias)? (',' concatenation column_alias)* xml_general_default_part? ')'
;
xml_table_column
: xml_column_name (FOR ORDINALITY | type_spec (PATH concatenation)? xml_general_default_part?)
;
xml_general_default_part
: DEFAULT concatenation
;
xml_multiuse_expression_element
: expression
( (AS? id_expression)
| (AS EVALNAME expression)
)?
;
xmlroot_param_version_part
: VERSION (NO VALUE | expression)
;
xmlroot_param_standalone_part
: STANDALONE (YES | NO VALUE?)
;
xmlserialize_param_enconding_part
: ENCODING concatenation
;
xmlserialize_param_version_part
: VERSION concatenation
;
xmlserialize_param_ident_part
: NO INDENT
| INDENT (SIZE '=' concatenation)?
;
// Annotations
annotations_clause
: ANNOTATIONS '(' annotations_list ')'
;
annotations_list
: (
ADD (IF NOT EXISTS | OR REPLACE)?
| DROP (IF EXISTS)?
| REPLACE
)? annotation (',' annotations_list)*
;
annotation
: identifier CHAR_STRING?
;
// SqlPlus
sql_plus_command
: EXIT
| PROMPT_MESSAGE
| SHOW (ERR | ERRORS)
| whenever_command
| timing_command
| start_command
| set_command
| clear_command
;
start_command
: START_CMD id_expression PERIOD (SQL | FILE_EXT)
;
whenever_command
: WHENEVER (SQLERROR | OSERROR) (
EXIT (SUCCESS | FAILURE | WARNING | variable_name | numeric) (COMMIT | ROLLBACK)?
| CONTINUE (COMMIT | ROLLBACK | NONE)?
)
;
set_command
: SET (
(regular_id (ON | OFF))+
| (regular_id (CHAR_STRING | ON | OFF | /*EXACT_NUM_LIT*/ numeric | regular_id))
)
;
timing_command
: TIMING (START timing_text = id_expression* | SHOW | STOP)?
;
clear_command
: CLEAR (COLUMN? regular_id) | ALL
;
// Common
partition_extension_clause
: (SUBPARTITION | PARTITION) FOR? '(' expressions_? ')'
;
column_alias
: AS? (identifier | quoted_string)
| AS
;
table_alias
: identifier
| quoted_string
;
where_clause
: WHERE (CURRENT OF cursor_name | condition)
;
into_clause
: (BULK COLLECT)? INTO (general_element | bind_variable) (
',' (general_element | bind_variable)
)*
;
// Common Named Elements
xml_column_name
: identifier
| quoted_string
;
cost_class_name
: identifier
;
attribute_name
: identifier
;
savepoint_name
: identifier
;
rollback_segment_name
: identifier
;
schema_name
: identifier
;
routine_name
: identifier ('.' id_expression)* ('@' link_name)?
;
package_name
: identifier
;
implementation_type_name
: identifier ('.' id_expression)?
;
parameter_name
: identifier
;
reference_model_name
: identifier
;
main_model_name
: identifier
;
container_tableview_name
: identifier ('.' id_expression)?
;
aggregate_function_name
: identifier ('.' id_expression)*
;
query_name
: identifier
;
grantee_name
: id_expression identified_by?
;
role_name
: id_expression
| CONNECT
;
constraint_name
: identifier ('.' id_expression)* ('@' link_name)?
;
label_name
: id_expression
;
type_name
: id_expression ('.' id_expression)*
;
sequence_name
: id_expression ('.' id_expression)*
;
exception_name
: identifier ('.' id_expression)*
;
function_name
: identifier ('.' id_expression)?
;
procedure_name
: identifier ('.' id_expression)?
;
trigger_name
: identifier ('.' id_expression)?
;
variable_name
: (INTRODUCER char_set_name)? id_expression ('.' id_expression)?
| bind_variable
;
index_name
: identifier ('.' id_expression)?
;
cursor_name
: general_element
| bind_variable
;
record_name
: identifier
| bind_variable
;
link_name
: database ('.' domain)* (AT_SIGN connection_qualifier)?
;
local_link_name
: identifier
;
connection_qualifier
: identifier
;
column_name
: identifier ('.' id_expression)*
;
tableview_name
: identifier ('.' id_expression)? (
AT_SIGN link_name
| /*TODO{!(input.LA(2) == BY)}?*/ partition_extension_clause
)?
| xmltable outer_join_sign?
;
xmltable
: XMLTABLE '(' (xml_namespaces_clause ',')? concatenation xml_passing_clause? (
COLUMNS xml_table_column (',' xml_table_column)*
)? ')' ('.' general_element_part)?
;
char_set_name
: id_expression ('.' id_expression)*
;
synonym_name
: identifier
;
// Represents a valid DB object name in DDL commands which are valid for several DB (or schema) objects.
// For instance, create synonym ... for , or rename to .
// Both are valid for sequences, tables, views, etc.
schema_object_name
: id_expression
;
dir_object_name
: id_expression
;
user_object_name
: id_expression
;
grant_object_name
: tableview_name
| USER user_object_name (',' user_object_name)*
| DIRECTORY dir_object_name
| EDITION schema_object_name
| MINING MODEL schema_object_name
| JAVA (SOURCE | RESOURCE) schema_object_name
| SQL TRANSLATION PROFILE schema_object_name
;
column_list
: column_name (',' column_name)*
;
paren_column_list
: LEFT_PAREN column_list RIGHT_PAREN
;
// PL/SQL Specs
// NOTE: In reality this applies to aggregate functions only
keep_clause
: KEEP '(' DENSE_RANK (FIRST | LAST) (query_partition_clause | order_by_clause) ')' over_clause?
;
function_argument
: '(' (argument (',' argument)*)? ')' keep_clause?
;
function_argument_analytic
: '(' (argument respect_or_ignore_nulls? (',' argument respect_or_ignore_nulls?)*)? ')' keep_clause?
;
function_argument_modeling
: '(' column_name (',' (numeric | NULL_) (',' (numeric | NULL_))?)? USING (
tableview_name '.' ASTERISK
| ASTERISK
| expression column_alias? (',' expression column_alias?)*
) ')' keep_clause?
;
respect_or_ignore_nulls
: (RESPECT | IGNORE) NULLS
;
argument
: (identifier '=' '>')? expression
;
type_spec
: datatype
| REF? type_name (PERCENT_ROWTYPE | PERCENT_TYPE)?
;
datatype
: native_datatype_element precision_part? (WITH LOCAL? TIME ZONE | CHARACTER SET char_set_name)?
| INTERVAL (YEAR | DAY) ('(' expression ')')? TO (MONTH | SECOND) ('(' expression ')')?
;
precision_part
: '(' (numeric | ASTERISK) (',' (numeric | numeric_negative))? (CHAR | BYTE)? ')'
;
native_datatype_element
: BINARY_INTEGER
| PLS_INTEGER
| NATURAL
| BINARY_FLOAT
| BINARY_DOUBLE
| NATURALN
| POSITIVE
| POSITIVEN
| SIGNTYPE
| SIMPLE_INTEGER
| NVARCHAR2
| DEC
| INTEGER
| INT
| NUMERIC
| SMALLINT
| NUMBER
| DECIMAL
| DOUBLE PRECISION?
| FLOAT
| REAL
| NCHAR
| LONG RAW?
| CHAR
| CHARACTER VARYING?
| VARCHAR2
| VARCHAR
| STRING
| RAW
| BOOLEAN
| DATE
| ROWID
| UROWID
| YEAR
| MONTH
| DAY
| HOUR
| MINUTE
| SECOND
| SDO_GEOMETRY
| TIMEZONE_HOUR
| TIMEZONE_MINUTE
| TIMEZONE_REGION
| TIMEZONE_ABBR
| TIMESTAMP
| TIMESTAMP_UNCONSTRAINED
| TIMESTAMP_TZ_UNCONSTRAINED
| TIMESTAMP_LTZ_UNCONSTRAINED
| YMINTERVAL_UNCONSTRAINED
| DSINTERVAL_UNCONSTRAINED
| BFILE
| BLOB
| CLOB
| NCLOB
| MLSLABEL
| XMLTYPE
;
bind_variable
: (BINDVAR | ':' UNSIGNED_INTEGER)
// Pro*C/C++ indicator variables
(INDICATOR? (BINDVAR | ':' UNSIGNED_INTEGER))? ('.' general_element_part)*
;
general_element
: general_element_part
| general_element ('.' general_element_part)+
| '(' general_element ')'
;
general_element_part
: (INTRODUCER char_set_name)? id_expression ('@' link_name)? function_argument*
;
table_element
: (INTRODUCER char_set_name)? id_expression ('.' id_expression)*
;
object_privilege
: ALL PRIVILEGES?
| ALTER
| DEBUG
| DELETE
| EXECUTE
| FLASHBACK
| FLASHBACK ARCHIVE
| INDEX
| INHERIT PRIVILEGES
| INHERIT REMOTE PRIVILEGES
| INSERT
| KEEP SEQUENCE
| MERGE VIEW
| ON COMMIT REFRESH
| QUERY REWRITE
| READ
| REFERENCES
| SELECT
| TRANSLATE SQL
| UNDER
| UPDATE
| USE
| WRITE
;
//Ordered by type rather than alphabetically
system_privilege
: ALL PRIVILEGES
| ADVISOR
| ADMINISTER ANY? SQL TUNING SET
| (ALTER | CREATE | DROP) ANY SQL PROFILE
| ADMINISTER SQL MANAGEMENT OBJECT
| CREATE ANY? CLUSTER
| (ALTER | DROP) ANY CLUSTER
| (CREATE | DROP) ANY CONTEXT
| EXEMPT REDACTION POLICY
| ALTER DATABASE
| (ALTER | CREATE) PUBLIC? DATABASE LINK
| DROP PUBLIC DATABASE LINK
| DEBUG CONNECT SESSION
| DEBUG ANY PROCEDURE
| ANALYZE ANY DICTIONARY
| CREATE ANY? DIMENSION
| (ALTER | DROP) ANY DIMENSION
| (CREATE | DROP) ANY DIRECTORY
| (CREATE | DROP) ANY EDITION
| FLASHBACK (ARCHIVE ADMINISTER | ANY TABLE)
| (ALTER | CREATE | DROP) ANY INDEX
| CREATE ANY? INDEXTYPE
| (ALTER | DROP | EXECUTE) ANY INDEXTYPE
| CREATE (ANY | EXTERNAL)? JOB
| EXECUTE ANY (CLASS | PROGRAM)
| MANAGE SCHEDULER
| ADMINISTER KEY MANAGEMENT
| CREATE ANY? LIBRARY
| (ALTER | DROP | EXECUTE) ANY LIBRARY
| LOGMINING
| CREATE ANY? MATERIALIZED VIEW
| (ALTER | DROP) ANY MATERIALIZED VIEW
| GLOBAL? QUERY REWRITE
| ON COMMIT REFRESH
| CREATE ANY? MINING MODEL
| (ALTER | DROP | SELECT | COMMENT) ANY MINING MODEL
| CREATE ANY? CUBE
| (ALTER | DROP | SELECT | UPDATE) ANY CUBE
| CREATE ANY? MEASURE FOLDER
| (DELETE | DROP | INSERT) ANY MEASURE FOLDER
| CREATE ANY? CUBE DIMENSION
| (ALTER | DELETE | DROP | INSERT | SELECT | UPDATE) ANY CUBE DIMENSION
| CREATE ANY? CUBE BUILD PROCESS
| (DROP | UPDATE) ANY CUBE BUILD PROCESS
| CREATE ANY? OPERATOR
| (ALTER | DROP | EXECUTE) ANY OPERATOR
| (CREATE | ALTER | DROP) ANY OUTLINE
| CREATE PLUGGABLE DATABASE
| SET CONTAINER
| CREATE ANY? PROCEDURE
| (ALTER | DROP | EXECUTE) ANY PROCEDURE
| (CREATE | ALTER | DROP) PROFILE
| CREATE ROLE
| (ALTER | DROP | GRANT) ANY ROLE
| (CREATE | ALTER | DROP) ROLLBACK SEGMENT
| CREATE ANY? SEQUENCE
| (ALTER | DROP | SELECT) ANY SEQUENCE
| (ALTER | CREATE | RESTRICTED) SESSION
| ALTER RESOURCE COST
| CREATE ANY? SQL TRANSLATION PROFILE
| (ALTER | DROP | USE) ANY SQL TRANSLATION PROFILE
| TRANSLATE ANY SQL
| CREATE ANY? SYNONYM
| DROP ANY SYNONYM
| (CREATE | DROP) PUBLIC SYNONYM
| CREATE ANY? TABLE
| (ALTER | BACKUP | COMMENT | DELETE | DROP | INSERT | LOCK | READ | SELECT | UPDATE) ANY TABLE
| (CREATE | ALTER | DROP | MANAGE | UNLIMITED) TABLESPACE
| CREATE ANY? TRIGGER
| (ALTER | DROP) ANY TRIGGER
| ADMINISTER DATABASE TRIGGER
| CREATE ANY? TYPE
| (ALTER | DROP | EXECUTE | UNDER) ANY TYPE
| (CREATE | ALTER | DROP) USER
| CREATE ANY? VIEW
| (DROP | UNDER | MERGE) ANY VIEW
| (ANALYZE | AUDIT) ANY
| BECOME USER
| CHANGE NOTIFICATION
| EXEMPT ACCESS POLICY
| FORCE ANY? TRANSACTION
| GRANT ANY OBJECT? PRIVILEGE
| INHERIT ANY PRIVILEGES
| KEEP DATE TIME
| KEEP SYSGUID
| PURGE DBA_RECYCLEBIN
| RESUMABLE
| SELECT ANY (DICTIONARY | TRANSACTION)
| SYSBACKUP
| SYSDBA
| SYSDG
| SYSKM
| SYSOPER
;
// $>
// $(AntlrCaches(OracleParser._ATN))
/**
* Install the parser caches into the given parser.
*
* This method should be called before parsing any input.
*/
fun installCaches(parser: OracleParser): Unit = parserCaches.get().installCaches(parser)
/**
* Drop the existing parser caches and create a new one.
*
* ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can
* consume a lot of memory depending on the input seen so far.
*
* This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL
* inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.
*/
fun refreshParserCaches() {
parserCaches.set(AntlrCaches(OracleParser._ATN))
}
}
================================================
FILE: superior-oracle-parser/src/main/kotlin/io/github/melin/superior/parser/oracle/OracleSqlAntlr4Visitor.kt
================================================
package io.github.melin.superior.parser.oracle
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.*
import io.github.melin.superior.common.antlr4.ParserUtils.source
import io.github.melin.superior.common.relational.*
import io.github.melin.superior.common.relational.alter.AlterTable
import io.github.melin.superior.common.relational.alter.AlterTableAction
import io.github.melin.superior.common.relational.common.CallProcedure
import io.github.melin.superior.common.relational.common.CommentStatement
import io.github.melin.superior.common.relational.common.ShowStatement
import io.github.melin.superior.common.relational.create.*
import io.github.melin.superior.common.relational.dml.*
import io.github.melin.superior.common.relational.drop.DropDatabase
import io.github.melin.superior.common.relational.drop.DropFunction
import io.github.melin.superior.common.relational.drop.DropProcedure
import io.github.melin.superior.common.relational.drop.DropTable
import io.github.melin.superior.common.relational.table.ColumnRel
import io.github.melin.superior.parser.oracle.antlr4.OracleParser
import io.github.melin.superior.parser.oracle.antlr4.OracleParser.Cursor_declarationContext
import io.github.melin.superior.parser.oracle.antlr4.OracleParser.Function_nameContext
import io.github.melin.superior.parser.oracle.antlr4.OracleParser.Multi_table_elementContext
import io.github.melin.superior.parser.oracle.antlr4.OracleParser.Procedure_nameContext
import io.github.melin.superior.parser.oracle.antlr4.OracleParser.Select_list_elementsContext
import io.github.melin.superior.parser.oracle.antlr4.OracleParser.Seq_of_statementsContext
import io.github.melin.superior.parser.oracle.antlr4.OracleParserBaseVisitor
import org.antlr.v4.runtime.tree.RuleNode
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2020/6/30 9:57 上午 */
class OracleSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) :
OracleParserBaseVisitor() {
private var currentOptType: StatementType = StatementType.UNKOWN
private var limit: Int? = null
private var offset: Int? = null
private var queryStmt: QueryStmt? = null
private var inputTables: ArrayList = arrayListOf()
private var outputTables: ArrayList = arrayListOf()
private var cteTempTables: ArrayList = arrayListOf()
// 多语句解析结果
private var statements: ArrayList = arrayListOf()
// 存储过程和函数中包含的子语句
private var childStatements: ArrayList = arrayListOf()
private val sqls: ArrayList = arrayListOf()
fun getSqlStatements(): List {
return statements
}
fun getSplitSqls(): List {
return sqls
}
override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {
if (currentResult != null) {
if (node is Cursor_declarationContext || node is Seq_of_statementsContext) {
childStatements.add(currentResult)
clean()
}
}
if (node is OracleParser.Unit_statementContext) {
clean()
}
return true
}
override fun visitSql_script(ctx: OracleParser.Sql_scriptContext): Statement? {
ctx.sql_plus_command().forEach {
var sql = source(it)
if (splitSql) {
if (StringUtils.endsWith(sql, ";")) {
sql = StringUtils.substringBeforeLast(sql, ";")
}
sqls.add(sql)
} else {
val startNode = it.start.text
val statement =
if (StringUtils.equalsIgnoreCase("show", startNode)) {
val keyWords: ArrayList = arrayListOf()
CommonUtils.findShowStatementKeyWord(keyWords, it)
ShowStatement(*keyWords.toTypedArray())
} else {
var statement = this.visitSql_plus_command(it)
if (statement == null) {
statement = DefaultStatement(StatementType.UNKOWN)
}
statement
}
statement.setSql(sql)
statements.add(statement)
currentOptType = StatementType.UNKOWN
}
}
ctx.unit_statement().forEach {
var sql = source(it)
if (splitSql) {
if (StringUtils.endsWith(sql, ";")) {
sql = StringUtils.substringBeforeLast(sql, ";")
}
sqls.add(sql)
} else {
val startNode = it.start.text
val statement =
if (StringUtils.equalsIgnoreCase("show", startNode)) {
val keyWords: ArrayList = arrayListOf()
CommonUtils.findShowStatementKeyWord(keyWords, it)
ShowStatement(*keyWords.toTypedArray())
} else {
var statement = this.visitUnit_statement(it)
if (statement == null) {
statement = DefaultStatement(StatementType.UNKOWN)
}
statement
}
statement.setSql(sql)
statements.add(statement)
currentOptType = StatementType.UNKOWN
}
}
return null
}
private fun clean() {
limit = null
offset = null
queryStmt = null
inputTables = arrayListOf()
outputTables = arrayListOf()
cteTempTables = arrayListOf()
}
private fun addOutputTableId(tableId: TableId) {
if (!outputTables.contains(tableId)) {
outputTables.add(tableId)
}
}
override fun visitCreate_database(ctx: OracleParser.Create_databaseContext): Statement {
val databaseName = CommonUtils.cleanQuote(ctx.database_name().text)
return CreateDatabase(databaseName)
}
override fun visitCreate_table(ctx: OracleParser.Create_tableContext): Statement {
currentOptType = StatementType.CREATE_TABLE
val schemaName = if (ctx.schema_name() != null) ctx.schema_name().text else null
val tableName = ctx.table_name().text
val tableId = TableId(schemaName, tableName)
val pks: ArrayList = arrayListOf()
val columnRels =
ctx.relational_table()
.relational_property()
.filter {
val constraint = it.out_of_line_constraint()
if (constraint != null && constraint.PRIMARY() != null) {
constraint.column_name().forEach { pks.add(it.text) }
}
it.column_definition() != null
}
.map {
val colDef = it.column_definition()
val columnName = colDef.column_name().text
val dataType = colDef.datatype().text
val defaultExpr: String? = if (colDef.expression() != null) colDef.expression().text else null
var isPk = if (pks.contains(columnName)) true else false
var nullable = true
if (colDef.inline_constraint() != null) {
colDef.inline_constraint().forEach { constraint ->
if (constraint.NOT() != null) {
nullable = false
}
if (constraint.PRIMARY() != null) {
isPk = true
}
}
}
ColumnRel(columnName, dataType, defaultExpr = defaultExpr, nullable = nullable, primaryKey = isPk)
}
return CreateTable(tableId, TableType.ORACLE, columnRels = columnRels)
}
override fun visitCreate_view(ctx: OracleParser.Create_viewContext): Statement {
currentOptType = StatementType.CREATE_VIEW
val schemaName = if (ctx.schema_name() != null) ctx.schema_name().text else null
val tableName = ctx.v.text
val tableId = TableId(schemaName, tableName)
val replace = if (ctx.REPLACE() != null) true else false
val queryStmt = this.parseSelect_only_statement(ctx.select_only_statement()) as QueryStmt
val createView = CreateView(tableId, queryStmt)
createView.replace = replace
return createView
}
override fun visitCreate_materialized_view(ctx: OracleParser.Create_materialized_viewContext): Statement {
currentOptType = StatementType.CREATE_MATERIALIZED_VIEW
val tableId = parseTableViewName(ctx.tableview_name())
// val ifNotExists = if (ctx.IF_P() != null) true else false
val queryStmt = this.parseSelect_only_statement(ctx.select_only_statement()) as QueryStmt
val createView = CreateMaterializedView(tableId, queryStmt)
super.visitSelect_only_statement(ctx.select_only_statement())
return createView
}
override fun visitCreate_procedure_body(ctx: OracleParser.Create_procedure_bodyContext): Statement {
childStatements = arrayListOf()
super.visitCreate_procedure_body(ctx)
val procedureName = ctx.procedure_name()
val procedureId = parseProcedureName(procedureName)
return CreateProcedure(procedureId, childStatements)
}
override fun visitCreate_function_body(ctx: OracleParser.Create_function_bodyContext): Statement {
childStatements = arrayListOf()
super.visitCreate_function_body(ctx)
val funcName = ctx.function_name()
val functionId = parseFunctionName(funcName)
val function = CreateFunction(functionId, childStatements)
return function
}
override fun visitDrop_database(ctx: OracleParser.Drop_databaseContext): Statement? {
return DropDatabase("")
}
override fun visitDrop_table(ctx: OracleParser.Drop_tableContext): Statement? {
val tableId = parseTableViewName(ctx.tableview_name().get(0))
val ifExists = ctx.EXISTS() != null
val purge = ctx.PURGE() != null
val dropTable = DropTable(tableId, ifExists)
dropTable.purge = purge
return dropTable
}
override fun visitDrop_function(ctx: OracleParser.Drop_functionContext): Statement {
val funcName = ctx.function_name()
val functionId = parseFunctionName(funcName)
return DropFunction(functionId)
}
override fun visitDrop_procedure(ctx: OracleParser.Drop_procedureContext): Statement {
val procedureName = ctx.procedure_name()
val procedureId = parseProcedureName(procedureName)
return DropProcedure(procedureId)
}
override fun visitAnonymous_block(ctx: OracleParser.Anonymous_blockContext?): Statement {
childStatements = arrayListOf()
super.visitAnonymous_block(ctx)
return CreateProcedure(childStatements)
}
override fun visitCall_statement(ctx: OracleParser.Call_statementContext): Statement {
val procedureId = ProcedureId(ctx.routine_name().get(0).text)
val callProcedure = CallProcedure(procedureId)
callProcedure.setSql(source(ctx))
return callProcedure
}
override fun visitAlter_table(ctx: OracleParser.Alter_tableContext): Statement {
val tableId = parseTableViewName(ctx.tableview_name())
return AlterTable(tableId)
}
override fun visitAlter_view(ctx: OracleParser.Alter_viewContext): Statement {
val tableId = parseTableViewName(ctx.tableview_name())
val action = AlterTableAction(AlterActionType.ALTER_VIEW_QUERY)
return AlterTable(tableId, action)
}
override fun visitSelect_statement(ctx: OracleParser.Select_statementContext): Statement? {
currentOptType = StatementType.SELECT
super.visitSelect_statement(ctx)
if (queryStmt == null) {
queryStmt = QueryStmt(inputTables, limit, offset)
}
queryStmt?.setSql(source(ctx))
return queryStmt
}
private fun parseSelect_only_statement(ctx: OracleParser.Select_only_statementContext): Statement? {
currentOptType = StatementType.SELECT
super.visitSelect_only_statement(ctx)
if (queryStmt == null) {
queryStmt = QueryStmt(inputTables, limit, offset)
}
return queryStmt
}
override fun visitDelete_statement(ctx: OracleParser.Delete_statementContext): Statement {
currentOptType = StatementType.DELETE
val tableId = parseTableViewName(ctx.general_table_ref().dml_table_expression_clause().tableview_name())
addOutputTableId(tableId)
super.visitWhere_clause(ctx.where_clause())
return DeleteTable(tableId, inputTables)
}
override fun visitUpdate_statement(ctx: OracleParser.Update_statementContext): Statement {
currentOptType = StatementType.UPDATE
val tableId = parseTableViewName(ctx.general_table_ref().dml_table_expression_clause().tableview_name())
addOutputTableId(tableId)
super.visitWhere_clause(ctx.where_clause())
return UpdateTable(tableId, inputTables)
}
override fun visitInsert_statement(ctx: OracleParser.Insert_statementContext): Statement {
currentOptType = StatementType.INSERT
val insertTable =
if (ctx.single_table_insert() != null) {
val tableInsert = ctx.single_table_insert()
val tableId =
parseTableViewName(
tableInsert
.insert_into_clause()
.general_table_ref()
.dml_table_expression_clause()
.tableview_name()
)
addOutputTableId(tableId)
if (tableInsert.select_statement() != null) {
val queryStmt = this.visitSelect_statement(tableInsert.select_statement()) as QueryStmt
InsertTable(InsertMode.INTO, queryStmt, tableId)
} else {
InsertTable(InsertMode.INTO, QueryStmt(), tableId)
}
} else {
if (ctx.multi_table_insert().conditional_insert_clause() == null) {
val tableInserts = ctx.multi_table_insert().multi_table_element()
addOutputTableId(tableInserts)
} else {
ctx.multi_table_insert().conditional_insert_clause().conditional_insert_when_part().map {
addOutputTableId(it.multi_table_element())
}
val elseElem = ctx.multi_table_insert().conditional_insert_clause().conditional_insert_else_part()
if (elseElem != null) {
addOutputTableId(elseElem.multi_table_element())
}
}
if (ctx.multi_table_insert().select_statement() != null) {
val queryStmt = this.visitSelect_statement(ctx.multi_table_insert().select_statement()) as QueryStmt
InsertTable(InsertMode.INTO, queryStmt, outputTables.first())
} else {
InsertTable(InsertMode.INTO, QueryStmt(), outputTables.first())
}
}
insertTable.outputTables.addAll(outputTables.subList(1, outputTables.size))
//insertTable?.setSql(CommonUtils.subsql(command, ctx))
insertTable?.setSql(source(ctx))
return insertTable
}
override fun visitExecute_immediate(ctx: OracleParser.Execute_immediateContext): Statement? {
var execSql = CommonUtils.cleanQuote(ctx.expression().text)
execSql = StringUtils.replace(execSql, "''", "'")
val statements = OracleSqlHelper.parseMultiStatement(execSql)
childStatements.addAll(statements)
return null
}
private fun parseFunctionName(funcName: Function_nameContext): FunctionId {
return if (funcName.id_expression() != null) {
FunctionId(funcName.identifier().text, funcName.id_expression().text)
} else {
FunctionId(funcName.identifier().text)
}
}
private fun parseProcedureName(procedureName: Procedure_nameContext): ProcedureId {
return if (procedureName.id_expression() != null) {
ProcedureId(procedureName.identifier().text, procedureName.id_expression().text)
} else {
ProcedureId(procedureName.identifier().text)
}
}
private fun addOutputTableId(list: List) {
list.forEach {
val tableId =
parseTableViewName(
it.insert_into_clause().general_table_ref().dml_table_expression_clause().tableview_name()
)
addOutputTableId(tableId)
}
}
override fun visitMerge_statement(ctx: OracleParser.Merge_statementContext): Statement {
currentOptType = StatementType.MERGE
val mergeTableId = parseTableViewName(ctx.tableview_name())
cteTempTables.add(mergeTableId)
val mergeTable = MergeTable(mergeTableId)
mergeTable.inputTables = inputTables
super.visitMerge_statement(ctx)
return mergeTable
}
override fun visitComment_on_column(ctx: OracleParser.Comment_on_columnContext): Statement {
val objValue = ctx.column_name().text
val isNull = false
val text: String = CommonUtils.cleanQuote(ctx.quoted_string().text)
return CommentStatement(text, isNull, "COLUMN", objValue)
}
override fun visitComment_on_table(ctx: OracleParser.Comment_on_tableContext): Statement {
val objValue = ctx.tableview_name().text
val isNull = false
val text: String = CommonUtils.cleanQuote(ctx.quoted_string().text)
return CommentStatement(text, isNull, "TABLE", objValue)
}
override fun visitComment_on_materialized(ctx: OracleParser.Comment_on_materializedContext): Statement {
val objValue = ctx.tableview_name().text
val isNull = false
val text: String = CommonUtils.cleanQuote(ctx.quoted_string().text)
return CommentStatement(text, isNull, "MATERIALIZED VIEW", objValue)
}
override fun visitSubquery_factoring_clause(ctx: OracleParser.Subquery_factoring_clauseContext): Statement? {
cteTempTables.add(TableId(ctx.query_name().text))
return super.visitSubquery_factoring_clause(ctx)
}
override fun visitOffset_clause(ctx: OracleParser.Offset_clauseContext): Statement? {
try {
offset = ctx.expression().text.toInt()
} catch (e: Exception) {}
return super.visitOffset_clause(ctx)
}
override fun visitFetch_clause(ctx: OracleParser.Fetch_clauseContext): Statement? {
try {
limit = ctx.expression().text.toInt()
} catch (e: Exception) {}
return super.visitFetch_clause(ctx)
}
override fun visitCursor_declaration(ctx: OracleParser.Cursor_declarationContext): Statement? {
super.visitCursor_declaration(ctx)
return null
}
override fun visitTableview_name(ctx: OracleParser.Tableview_nameContext): Statement? {
if (
currentOptType == StatementType.SELECT ||
currentOptType == StatementType.CREATE_VIEW ||
currentOptType == StatementType.CREATE_MATERIALIZED_VIEW ||
currentOptType == StatementType.UPDATE ||
currentOptType == StatementType.DELETE ||
currentOptType == StatementType.MERGE ||
currentOptType == StatementType.INSERT ||
currentOptType == StatementType.CREATE_FUNCTION ||
currentOptType == StatementType.CREATE_PROCEDURE
) {
if (ctx.parent is Select_list_elementsContext) {
return null
}
val tableId = parseTableViewName(ctx)
if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {
inputTables.add(tableId)
}
}
return null
}
private fun parseTableViewName(ctx: OracleParser.Tableview_nameContext): TableId {
if (ctx.childCount == 1) {
return TableId(null, null, ctx.getChild(0).text)
} else if (ctx.childCount == 3) {
return TableId(null, ctx.getChild(0).text, ctx.getChild(2).text)
} else {
throw SQLParserException("not suuport tablename")
}
}
}
================================================
FILE: superior-oracle-parser/src/main/kotlin/io/github/melin/superior/parser/oracle/OracleSqlHelper.kt
================================================
package io.github.melin.superior.parser.oracle
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.common.antlr4.ParseErrorListener
import io.github.melin.superior.common.antlr4.ParseException
import io.github.melin.superior.common.antlr4.UpperCaseCharStream
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.parser.oracle.antlr4.OracleLexer
import io.github.melin.superior.parser.oracle.antlr4.OracleParser
import io.github.melin.superior.parser.oracle.antlr4.OracleParserBaseVisitor
import org.antlr.v4.runtime.CharStreams
import org.antlr.v4.runtime.CommonTokenStream
import org.antlr.v4.runtime.atn.PredictionMode
import org.antlr.v4.runtime.misc.ParseCancellationException
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2020/6/30 9:58 上午 */
object OracleSqlHelper {
@JvmStatic
fun sqlKeywords(): List {
val keywords = hashSetOf()
(0 until OracleLexer.VOCABULARY.maxTokenType).forEach { idx ->
val name = OracleLexer.VOCABULARY.getLiteralName(idx)
if (name != null) {
val matchResult = CommonUtils.KEYWORD_REGEX.find(name)
if (matchResult != null) {
keywords.add(matchResult.groupValues.get(1))
}
}
}
return keywords.sorted()
}
@JvmStatic
fun parseStatement(command: String): Statement {
var sql = StringUtils.trim(command)
if (!StringUtils.endsWith(sql, ";")) {
sql += ";"
}
val statements = this.parseMultiStatement(sql)
if (statements.size != 1) {
throw IllegalStateException("only parser one sql, sql count: " + statements.size)
} else {
return statements.get(0)
}
}
@JvmStatic
fun parseMultiStatement(command: String): List {
val trimCmd = StringUtils.trim(command)
val sqlVisitor = OracleSqlAntlr4Visitor(false, trimCmd)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSqlStatements()
}
@JvmStatic
fun splitSql(command: String): List {
var trimCmd = StringUtils.trim(command)
if (!StringUtils.endsWith(trimCmd, ";")) {
trimCmd += ";"
}
val sqlVisitor = OracleSqlAntlr4Visitor(true, trimCmd)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSplitSqls()
}
@JvmStatic
fun checkSqlSyntax(command: String) {
var trimCmd = StringUtils.trim(command)
if (!StringUtils.endsWith(trimCmd, ";")) {
trimCmd += ";"
}
val sqlVisitor = OracleParserBaseVisitor()
innerParseStatement(trimCmd, sqlVisitor)
}
private fun innerParseStatement(command: String, sqlVisitor: OracleParserBaseVisitor) {
val charStream = UpperCaseCharStream(CharStreams.fromString(command))
val lexer = OracleLexer(charStream)
lexer.removeErrorListeners()
lexer.addErrorListener(ParseErrorListener())
val tokenStream = CommonTokenStream(lexer)
val parser = OracleParser(tokenStream)
AbstractSqlParser.installCaches(parser)
parser.removeErrorListeners()
parser.addErrorListener(ParseErrorListener())
// parser.interpreter.predictionMode = PredictionMode.SLL
try {
try {
// first, try parsing with potentially faster SLL mode
sqlVisitor.visit(parser.sql_script())
} catch (e: ParseCancellationException) {
tokenStream.seek(0) // rewind input stream
parser.reset()
// Try Again.
parser.interpreter.predictionMode = PredictionMode.LL
sqlVisitor.visit(parser.sql_script())
}
} catch (e: ParseException) {
if (StringUtils.isNotBlank(e.command)) {
throw e
} else {
throw e.withCommand(command)
}
} finally {
val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)
if (releaseAntlrCache == null || "true".equals(releaseAntlrCache)) {
AbstractSqlParser.refreshParserCaches()
}
}
}
}
================================================
FILE: superior-oracle-parser/src/test/java/io/github/melin/superior/parser/oracle/OracleProcessParserTest.kt
================================================
package io.github.melin.superior.parser.oracle
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.FunctionId
import io.github.melin.superior.common.relational.ProcedureId
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.common.CallProcedure
import io.github.melin.superior.common.relational.create.CreateFunction
import io.github.melin.superior.common.relational.create.CreateProcedure
import io.github.melin.superior.common.relational.drop.DropFunction
import io.github.melin.superior.common.relational.drop.DropProcedure
import org.junit.Assert
import org.junit.Test
class OracleProcessParserTest {
@Test
fun processTest0() {
val sql = """
DECLARE
CURSOR C_ORDERS IS
SELECT CUSTOMER_NAME, PRICE FROM ORDERS;
BEGIN
FOR ORD IN C_ORDERS
LOOP
SELECT CUSTOMER_NAME, PRICE FROM ORDERS_TEST;
SELECT CUSTOMER_NAME, PRICE FROM ORDERS_TEST_1;
dbms_output.put_line(ORD.CUSTOMER_NAME || ORD.PRICE);
END LOOP;
END;
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is CreateProcedure) {
Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)
Assert.assertEquals(4, statement.childStatements.size)
} else {
Assert.fail()
}
}
@Test
fun createFunctionTest() {
val sql = """
CREATE FUNCTION test.get_bal(acc_no IN NUMBER)
RETURN NUMBER
IS acc_bal NUMBER(11,2);
BEGIN
SELECT order_total
INTO acc_bal
FROM orders
WHERE customer_id = acc_no;
RETURN(acc_bal);
END;
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is CreateFunction) {
Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)
Assert.assertEquals(FunctionId("test", "get_bal"), statement.functionId)
Assert.assertEquals(1, statement.childStatements.size)
} else {
Assert.fail()
}
}
@Test
fun createFunctionTest1() {
val sql = """
CREATE FUNCTION get_bal(acc_no IN NUMBER)
RETURN NUMBER
IS acc_bal NUMBER(11,2);
BEGIN
SELECT order_total
INTO acc_bal
FROM orders
WHERE customer_id = acc_no;
RETURN(acc_bal);
END;
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is CreateFunction) {
Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)
Assert.assertEquals(FunctionId( "get_bal"), statement.functionId)
Assert.assertEquals(1, statement.childStatements.size)
} else {
Assert.fail()
}
}
@Test
fun createProcedureTest0() {
val sql = """
CREATE OR REPLACE Procedure UpdateCourse( name_in IN varchar2 )
IS
cnumber number;
cursor c1 is
SELECT course_number
FROM courses_tbl
WHERE course_name = name_in;
BEGIN
open c1;
fetch c1 into cnumber;
if c1%notfound then
cnumber := 9999;
end if;
INSERT INTO student_courses( course_name,course_number )
VALUES ( name_in, cnumber );
commit;
close c1;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END;
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is CreateProcedure) {
Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)
Assert.assertEquals(ProcedureId("UpdateCourse"), statement.procedureId)
Assert.assertEquals(3, statement.childStatements.size)
} else {
Assert.fail()
}
}
@Test
fun dropTest() {
val sql = """
DROP FUNCTION get_bal;
DROP PROCEDURE demos.UpdateCourse;
""".trimIndent()
val statements = OracleSqlHelper.parseMultiStatement(sql)
val dropFunction = statements.get(0)
val dropProcess = statements.get(1)
if (dropFunction is DropFunction) {
Assert.assertEquals("get_bal", dropFunction.functionId.functionName)
} else {
Assert.fail()
}
if (dropProcess is DropProcedure) {
Assert.assertEquals("demos", dropProcess.procedureId.schemaName)
Assert.assertEquals("UpdateCourse", dropProcess.procedureId.procedureName)
} else {
Assert.fail()
}
}
@Test
fun callProcessTest() {
val sql = """
Call UpdateCourse('tes');
begin
UpdateCourse('tes');
end;
""".trimIndent()
val statements = OracleSqlHelper.parseMultiStatement(sql)
val procedure1 = statements.get(0)
val procedure2 = statements.get(1)
if (procedure1 is CallProcedure) {
Assert.assertEquals("UpdateCourse", procedure1.procedureIds.first().procedureName)
} else {
Assert.fail()
}
if (procedure2 is CreateProcedure) {
Assert.assertEquals(1, procedure2.childStatements.size)
} else {
Assert.fail()
}
}
@Test
fun processTest4() {
val sql = """
DECLARE
CURSOR C_ORDERS IS
SELECT CUSTOMER_NAME, PRICE FROM ORDERS;
BEGIN
FOR ORD IN C_ORDERS
LOOP
SELECT CUSTOMER_NAME, PRICE FROM ORDERS_TEST;
SELECT CUSTOMER_NAME, PRICE FROM ORDERS_TEST_1;
dbms_output.put_line(ORD.CUSTOMER_NAME || ORD.PRICE);
END LOOP;
END;
CREATE FUNCTION test.get_bal(acc_no IN NUMBER)
RETURN NUMBER
IS acc_bal NUMBER(11,2);
BEGIN
SELECT order_total
INTO acc_bal
FROM orders
WHERE customer_id = acc_no;
RETURN(acc_bal);
END;
""".trimIndent()
val statements = OracleSqlHelper.parseMultiStatement(sql)
Assert.assertEquals(2, statements.size)
var statement = statements.get(0)
if (statement is CreateProcedure) {
Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)
Assert.assertEquals(4, statement.childStatements.size)
} else {
Assert.fail()
}
statement = statements.get(1)
if (statement is CreateFunction) {
Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)
Assert.assertEquals(1, statement.childStatements.size)
Assert.assertEquals("SELECT order_total \n" +
" INTO acc_bal \n" +
" FROM orders \n" +
" WHERE customer_id = acc_no", statement.childStatements.get(0).getSql())
} else {
Assert.fail()
}
}
@Test
fun processTest5() {
val sql = """
CREATE OR REPLACE PROCEDURE create_and_manipulate_tables AS
BEGIN
EXECUTE IMMEDIATE '
CREATE TABLE schema1.test_table_s1 (
id NUMBER PRIMARY KEY,
name VARCHAR2(100)
)
';
EXECUTE IMMEDIATE 'INSERT INTO schema1.test_table_s1 (id, name) VALUES (1, ''Alice'')';
END;
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is CreateProcedure) {
Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)
Assert.assertEquals(ProcedureId("create_and_manipulate_tables"), statement.procedureId)
Assert.assertEquals(2, statement.childStatements.size)
Assert.assertEquals(StatementType.CREATE_TABLE, statement.childStatements.get(0).statementType)
Assert.assertEquals(StatementType.INSERT, statement.childStatements.get(1).statementType)
Assert.assertEquals("INSERT INTO schema1.test_table_s1 (id, name) VALUES (1, 'Alice')", statement.childStatements.get(1).getSql())
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-oracle-parser/src/test/java/io/github/melin/superior/parser/oracle/OracleSqlParserDdlTest.kt
================================================
package io.github.melin.superior.parser.oracle
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.DefaultStatement
import io.github.melin.superior.common.relational.common.CommentStatement
import io.github.melin.superior.common.relational.create.CreateDatabase
import io.github.melin.superior.common.relational.create.CreateMaterializedView
import io.github.melin.superior.common.relational.create.CreateTable
import io.github.melin.superior.common.relational.create.CreateView
import io.github.melin.superior.common.relational.drop.DropDatabase
import io.github.melin.superior.common.relational.drop.DropTable
import org.junit.Assert
import org.junit.Test
class OracleSqlParserDdlTest {
@Test
fun createDatabaseTest() {
val sql = """
CREATE DATABASE bigdata1 USER SYSTEM IDENTIFIED BY 123213;
DROP DATABASE INCLUDING BACKUPS NOPROMPT
""".trimIndent()
val statements = OracleSqlHelper.parseMultiStatement(sql)
val createDatabse = statements.get(0)
val dropDatabase = statements.get(1)
if (createDatabse is CreateDatabase) {
Assert.assertEquals("bigdata1", createDatabse.databaseName)
} else {
Assert.fail()
}
if (dropDatabase is DropDatabase) {
Assert.assertTrue(true)
Assert.assertEquals(StatementType.DROP_DATABASE, dropDatabase.statementType)
} else {
Assert.fail()
}
}
@Test
fun createTableTest0() {
val sql = """
CREATE TABLE employees(
employee_id number(10) NOT NULL,
employee_name varchar2(50) NOT NULL,
city varchar2(50),
CONSTRAINT employees_pk PRIMARY KEY (employee_id)
)
""".trimIndent()
OracleSqlHelper.splitSql(sql)
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is CreateTable) {
Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)
Assert.assertEquals("employees", statement.tableId.tableName)
Assert.assertEquals(3, statement.columnRels?.size)
Assert.assertTrue(statement.columnRels?.get(0)?.primaryKey!!)
Assert.assertFalse(statement.columnRels?.get(1)?.primaryKey!!)
} else {
Assert.fail()
}
}
@Test
fun createView0() {
val sql = """
CREATE OR REPLACE VIEW comedies AS
SELECT f.*,
country_code_to_name(f.country_code) AS country,
(SELECT avg(r.rating)
FROM user_ratings r
WHERE r.film_id = f.id) AS avg_rating
FROM films f
WHERE f.kind = 'Comedy'
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is CreateView) {
Assert.assertEquals(StatementType.CREATE_VIEW, statement.statementType)
Assert.assertEquals("comedies", statement.tableId.tableName)
Assert.assertEquals(2, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun createMatView0() {
val sql = """
CREATE MATERIALIZED VIEW sales_summary AS
SELECT
seller_no,
invoice_date,
sum(invoice_amt) as sales_amt
FROM invoice
WHERE invoice_date < CURRENT_DATE
GROUP BY
seller_no,
invoice_date;
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is CreateMaterializedView) {
Assert.assertEquals(StatementType.CREATE_MATERIALIZED_VIEW, statement.statementType)
Assert.assertEquals("sales_summary", statement.tableId.tableName)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun commentTest0() {
val sql = """
COMMENT ON COLUMN employees.job_id IS 'abbreviated job title';
COMMENT ON COLUMN employees1.job_id IS 'abbreviated job title'
""".trimIndent()
val statement = OracleSqlHelper.parseMultiStatement(sql)
val st1 = statement.get(0)
val st2 = statement.get(1)
if (st1 is CommentStatement) {
Assert.assertEquals(StatementType.COMMENT, st1.statementType)
Assert.assertEquals("employees.job_id", st1.objValue)
Assert.assertEquals("abbreviated job title", st1.comment)
Assert.assertFalse(st1.isNull)
}
if (st2 is CommentStatement) {
Assert.assertEquals(StatementType.COMMENT, st2.statementType)
Assert.assertEquals("employees1.job_id", st2.objValue)
Assert.assertEquals("abbreviated job title", st2.comment)
Assert.assertFalse(st2.isNull)
}
}
@Test
fun dropTableTest() {
val sql = """
drop table employees purge;
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is DropTable) {
Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)
Assert.assertEquals("employees", statement.tableId.tableName)
Assert.assertTrue(statement.purge)
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-oracle-parser/src/test/java/io/github/melin/superior/parser/oracle/OracleSqlParserDmlTest.kt
================================================
package io.github.melin.superior.parser.oracle
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.dml.*
import org.apache.commons.io.FileUtils
import org.junit.Assert
import org.junit.Test
import java.io.File
class OracleSqlParserDmlTest {
@Test
fun querySqlTest0() {
val sql1 = FileUtils.readFileToString(File("./src/test/resources/insert.sql"), "UTF-8")
val statement = OracleSqlHelper.parseStatement(sql1)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals(27, statement.queryStmt.inputTables.size)
Assert.assertEquals(TableId("dwd", "dwd_d03_contract_det_s"), statement.outputTables.get(0))
} else {
Assert.fail()
}
}
@Test
fun querySqlTest1() {
val sql = """
select 1;
""".trimIndent()
try {
OracleSqlHelper.parseStatement(sql)
Assert.fail()
} catch (e: Exception) {
Assert.assertTrue(true)
}
}
@Test
fun cteSqlTest0() {
val sql = """
WITH
cte1 AS (SELECT a, b FROM table1),
cte2 AS (SELECT c, d FROM table2)
SELECT b, d FROM cte1 JOIN cte2
WHERE cte1.a = cte2.c
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(2, statement.inputTables.size)
Assert.assertEquals(TableId("table1"), statement.inputTables.get(0))
} else {
Assert.fail()
}
}
@Test
fun deleteTest() {
val sql = """
DELETE FROM films
WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is DeleteTable) {
Assert.assertEquals(StatementType.DELETE, statement.statementType)
Assert.assertEquals("films", statement.tableId?.tableName)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun updateTest0() {
val sql = """
UPDATE employees SET sales_count = sales_count + 1 WHERE id =
(SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is UpdateTable) {
Assert.assertEquals(StatementType.UPDATE, statement.statementType)
Assert.assertEquals("employees", statement.tableId?.tableName)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest0() {
val sql = """
INSERT ALL
INTO pivot_dest (id, day, val) VALUES (id, 'mon', mon_val)
INTO pivot_dest (id, day, val) VALUES (id, 'tue', tue_val)
INTO pivot_dest (id, day, val) VALUES (id, 'wed', wed_val)
INTO pivot_dest (id, day, val) VALUES (id, 'thu', thu_val)
INTO pivot_dest (id, day, val) VALUES (id, 'fri', fri_val)
SELECT *
FROM pivot_source;
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("pivot_dest", statement.outputTables.get(0).tableName)
Assert.assertEquals(1, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest1() {
val sql = """
INSERT ALL
INTO dest_tab1 (id, description) VALUES (id, description)
INTO dest_tab2 (id, description) VALUES (id, description)
INTO dest_tab3 (id, description) VALUES (id, description)
SELECT id, description
FROM source_tab;
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("dest_tab1", statement.outputTables.get(0).tableName)
Assert.assertEquals(3, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest2() {
val sql = """
INSERT ALL
WHEN id <= 3 THEN
INTO dest_tab1 (id, description) VALUES (id, description)
WHEN id BETWEEN 4 AND 7 THEN
INTO dest_tab2 (id, description) VALUES (id, description)
WHEN id >= 8 THEN
INTO dest_tab3 (id, description) VALUES (id, description)
SELECT id, description
FROM source_tab;
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("dest_tab1", statement.outputTables.get(0).tableName)
Assert.assertEquals(3, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest3() {
val sql = """
INSERT FIRST
WHEN id <= 3 THEN
INTO dest_tab1 (id, description) VALUES (id, description)
WHEN id <= 5 THEN
INTO dest_tab2 (id, description) VALUES (id, description)
ELSE
INTO dest_tab3 (id, description) VALUES (id, description)
SELECT id, description
FROM source_tab;
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("dest_tab1", statement.outputTables.get(0).tableName)
Assert.assertEquals(3, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest4() {
val sql = """
INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("films", statement.tableId?.tableName)
Assert.assertEquals(1, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun deltaMergeTest() {
val sql = """
MERGE INTO bonuses D
USING (SELECT employee_id, salary, department_id FROM hr.employees
WHERE department_id = 80) S
ON (D.employee_id = S.employee_id)
WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01
DELETE WHERE (S.salary > 8000)
WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus)
VALUES (S.employee_id, S.salary*.01)
WHERE (S.salary <= 8000);
""".trimIndent()
val statement = OracleSqlHelper.parseStatement(sql)
if (statement is MergeTable) {
Assert.assertEquals(StatementType.MERGE, statement.statementType)
Assert.assertEquals("bonuses", statement.targetTable.tableName)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-oracle-parser/src/test/resources/insert.sql
================================================
insert into dwd.dwd_d03_contract_det_s
select to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') stt_date
,to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') end_date
,'01' cont_source_cd -- 合同来源编码: 01-通用核心; 02-商用车
,'通用核心' cont_source_nm -- 合同来源:通用核心/商用车
,cc.pk_contract -- 合同主键
,cc.cont_code -- 合同编码
,cc.cont_name -- 合同名称
,cc.cont_type cont_type_cd -- 合同类型编码
,pt2.param_name cont_type_nm -- 合同类型名称
,cc.cont_status cont_status_cd -- 合同状态编码
,pt1.param_name cont_status_nm -- 合同状态名称
,pt3.param_value economic_style_cd -- 控股类型编码
,replace(replace(pt3.param_name ,'绝对',''),'相对','') economic_style_nm -- 控股类型
,cc.cont_amount -- 合同金额
,cc.lease_date_fact -- 起租日
,cc.cont_end_date -- 到期日
,lc.lease_times lease_times -- 租赁期(月数)
,round(lc.lease_times/12,2) lease_year -- 租赁期(年数)
,case when cc.cont_amount >= 100000000 then '大型'
when cc.cont_amount >= 10000000 and cc.cont_amount < 100000000
then '中型'
else '小型'
end cont_scala -- 合同规模
,case when cc.if_adjust = 0 then '是'
when cc.if_adjust = 1 then '否'
else null
end if_adjust -- 是否调息
,sjtf.fact_cash_loan -- 已投放金额
,sjtf.pay_date -- 首次投放日期
,ba1.name pay_province -- 投放地区省
,ba2.name pay_city -- 投放地区市
,ba3.name pay_area -- 客户所属区
,coalesce(nn.assets_classify, cc.assets_classify, 0) assets_classify_cd -- 五级分类代码
,case coalesce(nn.assets_classify, cc.assets_classify, 0)
when 0 then '正常'
when 1 then '关注'
when 2 then '次级'
when 3 then '可疑'
when 4 then '损失'
else '正常'
end assets_classify_nm -- 五级分类名称
,pi.pk_project_info -- 项目编号
,pi.project_name -- 项目名称
,pi.lease_categry lease_categry_cd -- 租赁类型代码
,case when pi.lease_categry = 0 then '融资租赁'
when pi.lease_categry = 1 then '经营性租赁'
else null
end lease_categry_nm -- 租赁类型名称
,case when pbl.if_group_company = 0 then '是'
else '否'
end if_group_company -- 是否集团客户
,pbl.vesting_group -- 集团客户名称
,lc.lease_method lease_method_cd -- 业务类型代码
,case when lc.lease_method = 0 then '直租'
when lc.lease_method = 1 then '回租'
when lc.lease_method = 4 then '转租赁'
else null
end lease_method_nm -- 业务类型名称
,main_thing.fixed_assets -- 固定资产门类
,main_thing.fixed_assets_lag -- 固定资产门类-大类
,main_thing.fixed_assets_mid -- 固定资产门类--中类
,main_thing.fixed_assets_sml -- 固定资产门类--小类
,main_thing.thing_name -- 租赁物名称
-- 主办人相关信息
,su.user_code main_user_code -- 主办项目经理编号
,su.user_name main_user_name -- 主办项目经理
,su.dept_code main_dept_code -- 主办业务部门编号
,su.dept_name main_dept_name -- 主办业务部门名称
-- 协办人相关信息
,su2.user_code help_user_code -- 协办项目经理编号
,su2.user_name help_user_name -- 协办项目经理
,su2.dept_code help_dept_code -- 协办业务部门编号
,su2.dept_name help_dept_name -- 协办业务部门名称
,coalesce(pa.sponsor_performance, pa.sponsor_performance_sh * 100) sponsor_performance -- 主办分成比例(两位整数)
,coalesce(pa.help_performance, pa.help_performance_one * 100) help_performance -- 协办分成比例(两位整数)
,pn.investment investment_cd -- 城建类分类
,case when coalesce(pn.investment, cu.investment) = 0
then '是'
else '否'
end investment_nm -- 是否城建类
,vc.customer_name -- 承租人名称
,case when vc.identity_type = 4 then vc.identity_no
else null
end identity_no -- 统一社会信用代码
,vc.risk_level risk_level_cd -- 客户洗钱风险评级代码
,case when vc.risk_level = '1001' then '低风险'
when vc.risk_level = '1002' then '较低风险'
when vc.risk_level = '1003' then '中风险'
when vc.risk_level = '1004' then '较高风险'
when vc.risk_level = '1005' then '高风险'
when vc.risk_level = '1006' then '无结果'
when vc.risk_level = '1007' then '查询失败'
else null
end risk_level_nm -- 客户洗钱风险评级名称
,cu.organization_code organization_code -- 组织机构代码
,hy.param_name industry -- 国标行业门类
,hy1.param_name industry_lag -- 国标行业大类
,hy2.param_name industry_mid -- 国标行业中类
,hy3.param_name industry_sml -- 国标行业小类
,coalesce(cc.business_module, dm1.business_mode_nm, '其他') industry_mod -- 业务板块——9大分类
,case when cc.cont_status = 8 or
(cc.cont_status = 2 and '${yyyy-mm-dd}' <= cc.lease_date_fact) or
(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 )
then coalesce(sjtf.fact_cash_loan,0) - coalesce(gather.gather_corpus,0) - coalesce(sfk.inner_deduct_cash,0)
else coalesce(ipc.lease_corpus,0) - coalesce(gather.gather_corpus,0) - coalesce(sfk.inner_deduct_cash,0)
end corpus_balance -- 剩余本金
,coalesce(history.lease_interest,ipc.lease_interest) - coalesce(gather.gather_interest,0) interest_balance -- 剩余利息
,case when yoc.pk_contract is not null then coalesce(lpb.deposit_balance,0)
else 0
end deposit_balance -- 剩余保证金
-- 调整剩余保证金逻辑, 保持和源端取值一样 11.22(剩余风险抵押金 按照逻辑把字段衍生出来)
-- ,coalesce(lpb.deposit_balance,0) deposit_balance -- 剩余保证金
,case when yoc.pk_contract is null then coalesce(lpb.deposit_balance,0)
else 0
end mortgage_balance -- 剩余风险抵押金
,COALESCE(adj.INTERRATE_FACT_AFTER,lc.FINAL_RATE, 0) contract_rate -- 合同利率
,COALESCE(adj.PROJECT_IRR,lc.PROJECT_IRR, 0) * 100.0 PROJECT_IRR -- IRR(现行)
,COALESCE(adj.CONTRACT_XIRR,lc.CONTRACT_XIRR, 0) * 100.0 CONTRACT_XIRR -- XIRR(含税)
-- 增加字段
,case when yoc.pk_contract is null then '是'
else '否'
end is_mortgage -- 是否风险抵押金
,case when cc.cont_status = 8 and coalesce(ipo.overdue_days_zqx, 0) >= 1
then '是'
when cc.cont_status <> 8 and coalesce(ipo.overdue_days, 0) >= 1
then '是'
else '否'
end if_overdue -- 是否逾期
,yq.OVERDUE_DATE overdue_days -- 最大逾期天数(含历史)
,magum.param_name pledge_name -- 担保方式
,case when lc.interrate_type = 0
then '浮动利率' else '固定利率'
end interrate_type -- 利率类型
,ipc.lease_cash1 handling_fee -- 手续费/咨询费
,ipc.lease_cash11 fixed_rent -- 固定租金
,ipc.lease_cash2 deposit_amt -- 保证金金额
,ipc.lease_cash22 margin_bal -- 保证金余额
,ipc.lease_cash3 margin_off_amt -- 保证金冲抵金额
,ipc.lease_cash33 refund_deposit -- 退还保证金
,nn.accrue_cash -- 拨备余额
,vc.customer_code -- 承租人编号
from dwd.dg1_yls_contract_c_c cc -- 合同表
-- 补全9大分类
left join dim.dim_d99_business_mode_cd dm1
on cc.industry3 = dm1.pk_parameter
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between dm1.stt_date and dm1.end_date
-- 合同状态
left join dwd.dg1_yls_parameter_c pt1
on cc.cont_status = pt1.param_value
and pt1.pk_param_type = upper('0001AA1000000001RC3C')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt1.stt_date and pt1.end_date
-- 合同类型
left join dwd.dg1_yls_parameter_c pt2
on cc.cont_type = pt2.param_value
and pt2.pk_param_type = upper('0001AA1000000001VJBS')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt2.stt_date and pt2.end_date
-- 控股类型
left join dwd.dg1_yls_parameter_c pt3
on cc.economic_style1 = pt3.pk_parameter
and pt3.pk_param_type = upper('0001AA10000000041633')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt3.stt_date and pt3.end_date
-- 担保方式
left join dwd.dg1_yls_parameter_c magum
on cc.major_guarantee_method = magum.pk_parameter
and magum.pk_param_type = upper('0001AA1000000002K3MQ')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pt3.stt_date and pt3.end_date
-- 逾期情况
left join (
select ipc.pk_contract
,coalesce(max(case
when ipc.trans_type = upper('0001AA100000000AUBPA') and
ipc.charge_off_status = 2 and
gab.check_date > '${yyyy-mm-dd}' then
to_date(gab.check_date, 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')
when ipc.trans_type = upper('0001AA100000000AUBPA') and
ipc.charge_off_status <> 2 and
ipc.plan_date <= '${yyyy-mm-dd}' then
to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')
end),
0) as overdue_days_zqx
,coalesce(max(case
when ipc.charge_off_status = 2 and
gab.check_date > '${yyyy-mm-dd}' then
to_date(gab.check_date, 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')
when ipc.charge_off_status <> 2 and
ipc.plan_date <= '${yyyy-mm-dd}' then
to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') - to_date(ipc.plan_date, 'yyyy-mm-dd')
end),
0) as overdue_days /*租金逾期天数*/
from dwd.dg1_yls_inout_plan_c_c ipc
left join (select gab.pk_inout_plan
,coalesce(max(gap.trade_date), '${yyyy-mm-dd}') as check_date
from dwd.dg1_yls_gather_account_b_c gab
inner join dwd.dg1_yls_gather_account_c ga
on ga.pk_gather_account = gab.pk_gather_account
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date
inner join dwd.dg1_yls_gather_audit_plan_c gap
on gap.pk_gather_account_b = gab.pk_gather_account_b
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gap.stt_date and gap.end_date
where ga.billstatus = 9
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date
group by gab.pk_inout_plan) gab
on gab.pk_inout_plan = ipc.pk_inout_plan
where ipc.trans_type in (upper('0001AA10000000007NGV'),
upper('0001AA100000000AUBPA'),
upper('0001AA10000000007NH3')) /* 现金流类型 租金 收租(租前息) 首付款*/
and ipc.rent_type = 1 /* 租金表类型 会计表*/
and ipc.plan_date <= '${yyyy-mm-dd}'
and ipc.lease_cash >= 0.01
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
group by ipc.pk_contract
) ipo
on cc.pk_contract = ipo.pk_contract
left join (
select plan.PK_CONTRACT,max(rec.OVERDUE_DATE) OVERDUE_DATE
from dwd.dg1_yls_overdue_record_c rec
join dwd.dg1_yls_inout_plan_c_c plan on plan.PK_INOUT_PLAN = rec.PK_INOUT_PLAN
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between plan.stt_date and plan.end_date
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between rec.stt_date and rec.end_date
group by plan.PK_CONTRACT
) yq on yq.PK_CONTRACT = cc.PK_CONTRACT
-- 实际投放金额
left join (
select ipc.pk_contract -- 主键
,sum(coalesce(lp.real_pay_cash, 0.00)) fact_cash_loan -- 已投放金额
,min(coalesce(ld.real_pay_date, '${yyyy-mm-dd}')) pay_date -- 首次投放日
from dwd.dg1_yls_inout_plan_c_c ipc
left join dwd.dg1_yls_loan_plan_c lp
on ipc.pk_inout_plan = lp.pk_inout_plan
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date
left join dwd.dg1_yls_loan_deal_c ld
on lp.pk_loan_deal = ld.pk_loan_deal
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
and ipc.trans_type in (upper('0001AA10000000005GRC'), upper('0001AA10000000007NGO'), upper('0001AA1000000005AB31'), upper('0001AA1000000005AB32'))
and ipc.rent_type = 1 -- 租金表类型-会计表
and lp.if_account = 0 -- 是否核销为是
and lp.if_approve_cancel = 1 -- 是否审核撤销为否时
and lp.if_cancel = 1 -- 是否核销撤销为否时
and ld.billstatus = 9
and ld.real_pay_date <= '${yyyy-mm-dd}'
group by ipc.pk_contract
) sjtf
on cc.pk_contract = sjtf.pk_contract
-- 首付款
left join (
select ipc.pk_contract
,sum(coalesce(ipc.lease_cash, 0.00)) as inner_deduct_cash
,min(coalesce(ld.real_pay_date, '${yyyy-mm-dd}')) as pay_date
from dwd.dg1_yls_inout_plan_c_c ipc
left join dwd.dg1_yls_loan_plan_c lp
on lp.pk_inout_plan = ipc.pk_inout_plan
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date
left join dwd.dg1_yls_loan_deal_c ld
on ld.pk_loan_deal = lp.pk_loan_deal
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date
where ipc.trans_type = '0001AA10000000007NH3' /* 现金流类型 设备款*/
and ipc.rent_type = 1 /* 租金表类型 会计表*/
and lp.if_inner_deduct = 2 /* 是否内扣为是 */
and lp.if_cancel = 1 /* 是否核销撤销为否时 */
and ld.billstatus = 9
and ld.real_pay_date <= '${yyyy-mm-dd}'
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
group by ipc.pk_contract
) sfk
on cc.pk_contract = sfk.pk_contract
-- 五级分类
left join (
select i1.pk_contract -- 合同PK
,i1.assets_classify -- 五级分类
,i1.accrue_cash
from dwd.dg1_assets_classify_history_c i1 -- yls_assets_classify_history
join (
select ic.pk_contract
,max(ic.pk_assets_classify_history) pk_assets_classify_history
from dwd.dg1_assets_classify_history_c ic
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ic.stt_date and ic.end_date
and (
case when ic.if_new = 0 then ic.period
else coalesce(substr(replace(ic.change_date, '-', ''), 1, 6), ic.period)
end
) <= substr(replace('${yyyy-mm-dd}', '-', ''), 1, 6)
group by ic.pk_contract
) i2
on i1.pk_assets_classify_history = i2.pk_assets_classify_history
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between i1.stt_date and i1.end_date
) nn
on cc.pk_contract = nn.pk_contract
-- 项目信息
left join dwd.dg1_yls_project_info_c pi
on cc.pk_project = pi.pk_project_info
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pi.stt_date and pi.end_date
-- 集团客户
left join (
select distinct source_bill, if_group_company, vesting_group
from dwd.dg1_yls_project_both_lessee_c
where lessee_type = 0
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between stt_date and end_date
) pbl
on pi.pk_project_info = pbl.source_bill
-- 主办/协办信息
left join dwd.dg1_yls_project_approval_c pa
on pi.pk_project_approval = pa.pk_project_approval
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between pa.stt_date and pa.end_date
-- 城建类
left join (
select row_number() over(partition by pk_project_info order by ts) rcnt
,i3.pk_project_info
,i3.investment -- 城建类判断
from dwd.dg1_yls_prj_nodecollect_c i3
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between i3.stt_date and i3.end_date
) pn
on pi.pk_project_info = pn.pk_project_info
and pn.rcnt = 1
-- 用户信息相关
left join dwd.dg1_yls_customer_c vc
on cc.pk_customer_lessee = vc.pk_customer
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between vc.stt_date and vc.end_date
-- 企业客户基本信息
left join dwd.dg1_yls_customer_corp_c cu
on vc.pk_customer = cu.pk_customer
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between cu.stt_date and cu.end_date
-- 投放地区
left join dwd.dg1_bd_areacl_c ba1 on ba1.pk_areacl = cu.PROVINCE
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba1.stt_date and ba1.end_date
left join dwd.dg1_bd_areacl_c ba2 on ba2.pk_areacl = cu.CITY
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba2.stt_date and ba2.end_date
left join dwd.dg1_bd_areacl_c ba3 on ba3.pk_areacl = cu.DISTRICT
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ba3.stt_date and ba3.end_date
-- 行业分类
left join dwd.dg1_yls_parameter_c hy
on cc.industry = hy.pk_parameter
and hy.pk_param_type = upper('0001AA1000000000OY5C')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy.stt_date and hy.end_date
left join dwd.dg1_yls_parameter_c hy1
on cc.industry1 = hy1.pk_parameter
and hy1.pk_param_type = upper('0001AA1000000000OY5C')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy1.stt_date and hy1.end_date
left join dwd.dg1_yls_parameter_c hy2
on cc.industry2 = hy2.pk_parameter
and hy2.pk_param_type = upper('0001AA1000000000OY5C')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy2.stt_date and hy2.end_date
left join dwd.dg1_yls_parameter_c hy3
on cc.industry3 = hy3.pk_parameter
and hy3.pk_param_type = upper('0001AA1000000000OY5C')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between hy3.stt_date and hy3.end_date
-- 剩余保证金计算
left join (
select ipc.pk_contract
,sum(case
when ipc.trans_type = '0001AA10000000007NHR' then
(case when lp.pay_cash > ipc.lease_cash then coalesce(ipc.lease_cash, 0.00)
else coalesce(lp.pay_cash, 0.00)
end) + coalesce(gac.gather_cash, 0)
when ipc.trans_type = '0001AA10000000007NHT' then
-coalesce(gab.gather_cash, 0)
when ipc.trans_type = '0001AA10000000007NI5' then
coalesce(gac.gather_cash, 0)
when ipc.trans_type = '0001AA10000000007NHX' then
-coalesce(lp.pay_cash, 0)
else 0
end) as deposit_balance
from dwd.dg1_yls_inout_plan_c_c ipc
left join (select ipc.pk_inout_plan
,coalesce(ga.charge_off_cash, 0) as gather_cash
from dwd.dg1_yls_inout_plan_c_c ipc
inner join dwd.dg1_yls_gather_account_c ga
on ipc.pk_inout_plan = ga.pk_account_bill
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date
where ga.billstatus = 9 /*单据状态 审核通过*/
and ga.check_date <= '${yyyy-mm-dd}'
and ipc.trans_type = '0001AA10000000007NHT'
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
) gab
on gab.pk_inout_plan = ipc.pk_inout_plan
left join (select ipc.pk_inout_plan
,coalesce(gab.gather_cash, 0) as gather_cash
from dwd.dg1_yls_inout_plan_c_c ipc
inner join dwd.dg1_yls_gather_account_b_c gab
on ipc.pk_inout_plan = gab.pk_inout_plan
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date
inner join dwd.dg1_yls_gather_account_c ga
on ga.pk_gather_account = gab.pk_gather_account
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date
where ga.billstatus = 9 /*单据状态 审核通过*/
and ga.check_date <= '${yyyy-mm-dd}'
and ipc.trans_type in
('0001AA10000000007NHR', '0001AA10000000007NI5')
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
) gac
on gac.pk_inout_plan = ipc.pk_inout_plan
left join (select lp.pk_inout_plan
,(case when coalesce(ld.real_pay_cash, 0.00) = 0
then coalesce(ld.inner_deduct_cash, 0.00)
else coalesce(ld.real_pay_cash, 0.00)
end) as pay_cash
from dwd.dg1_yls_loan_plan_c lp
inner join dwd.dg1_yls_loan_deal_c ld
on ld.pk_loan_deal = lp.pk_loan_deal
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ld.stt_date and ld.end_date
where lp.if_approve_cancel = 1 /* 是否审核撤销为否时 */
and lp.if_cancel = 1 /* 是否核销撤销为否时 */
and ld.billstatus = 9
and ld.real_pay_date <= '${yyyy-mm-dd}'
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lp.stt_date and lp.end_date
) lp
on lp.pk_inout_plan = ipc.pk_inout_plan
where ipc.trans_type in ('0001AA10000000007NHR',
'0001AA10000000007NHT',
'0001AA10000000007NI5',
'0001AA10000000007NHX') /* 现金流类型 收取保证金,保证金冲抵,补足保证金,退还保证金*/
and ipc.rent_type = 1 /* 租金表类型 会计表*/
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
group by ipc.pk_contract
) lpb
on cc.pk_contract = lpb.pk_contract
left join dwd.dg1_yls_old_contract_c yoc
on cc.pk_contract = yoc.pk_contract
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between yoc.stt_date and yoc.end_date
-- 实收数据
left join (
select sum(case when et.event_code in ('10201', '10203', '10216') and gab.trade_date <= '${yyyy-mm-dd}'
then coalesce(gab.gather_cash, 0)
else 0
end) gather_cash
,sum(case when et.event_code in ('10201', '10203') and gab.trade_date <= '${yyyy-mm-dd}'
then coalesce(gab.gather_corpus, 0)
else 0
end) gather_corpus
,sum(case when et.event_code in ('10201', '10216') and gab.trade_date <= '${yyyy-mm-dd}'
then coalesce(gab.gather_interest, 0)
else 0
end) gather_interest
,sum(case when et.event_code in ('10213') and gab.trade_date <= '${yyyy-mm-dd}'
then coalesce(gab.gather_cash, 0)
else 0
end) gather_penal_cash
,sum(case when et.event_code in ('10201', '10203') and gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and
gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')
then coalesce(gab.gather_cash, 0)
else 0
end) gather_cash1
,sum(case when et.event_code in ('10201', '10203') and
gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and
gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')
then coalesce(gab.gather_corpus, 0)
else 0
end) gather_corpus1
,sum(case when et.event_code in ('10201', '10203', '10216') and
gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and
gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')
then coalesce(gab.gather_interest, 0)
else 0
end) gather_interest1
,sum(case when et.event_code in ('10213') and
gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and
gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')
then coalesce(gab.gather_cash, 0)
else 0
end) gather_penal_cash1
,sum(case when gab.trade_date >= concat(substr('${yyyy-mm-dd}', 1, 4), '-01-01') and
gab.trade_date <= concat(substr('${yyyy-mm-dd}', 1, 4), '-12-31')
then
1
else
0
end) cur_year_time
,sum(case when gab.trade_date >= '${yyyy-mm-dd}' and
gab.trade_date <= to_char(add_months(date'${yyyy-mm-dd}', 12), 'yyyy-mm-dd') then
1
else
0
end) future_time
,ipc.pk_contract
from dwd.dg1_yls_gather_account_b_c gab
join dwd.dg1_yls_gather_account_c ga
on ga.pk_gather_account = gab.pk_gather_account
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ga.stt_date and ga.end_date
join dwd.dg1_yls_inout_plan_c_c ipc
on ipc.pk_inout_plan = gab.pk_inout_plan
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
join dwd.dg1_yls_event_type_c et
on et.pk_event_type = ipc.trans_type
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date
where ga.billstatus = 9
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between gab.stt_date and gab.end_date
group by ipc.pk_contract
) gather
on cc.pk_contract = gather.pk_contract
left join dwd.dg1_yls_lease_calculator_c_c lc
on cc.pk_lease_calculator = lc.pk_lease_calculator
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between lc.stt_date and lc.end_date
-- 实时数据
left join (
select sum(case when et.event_code in ('10201','10202','10203','10216') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash, /* 总租金 */
sum(case when et.event_code in ('10401'/*,'10402','10403'*/,'10606') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash1,/* 手续费/咨询费 */
sum(case when et.event_code in ('10405') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash11,/* 固定租金 */
sum(case when et.event_code in ('10301') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash2, /* 保证金收取 */
sum(case when et.event_code in ('10308') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash22, /* 补住保证金 */
sum(case when et.event_code in ('10302') then coalesce(ipc.fact_cash,0) else 0 end) lease_cash3, /* 保证金冲抵 */
sum(case when et.event_code in ('10304') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash33, /* 退还保证金 */
sum(case when et.event_code in ('10201','10203') then coalesce(ipc.lease_cash,0) else 0 end) lease_cash4, /* 收取总租金 */
sum(case when et.event_code in ('10201','10202','10216') then coalesce(ipc.lease_interest,0) else 0 end) lease_interest, /* 收取总利息 */
sum(case when et.event_code in ('10101','10102') and ycc.cont_status = 8 then coalesce(ipc.fact_cash,0)
when et.event_code in ('10201','10203') and ycc.cont_status != 8 then coalesce(ipc.lease_corpus,0) else 0 end) lease_corpus, /* 总本金 */
sum(case when et.event_code in ('10301','10308') then coalesce(ipc.fact_cash,0) else 0 end) fact_cash2, /* 实收:保证金收取、补足 */
sum(case when et.event_code in ('10302','10304') then coalesce(ipc.fact_cash,0) else 0 end) fact_cash3, /* 实际:保证金冲抵、退还保证金 */
ipc.source_bill
from dwd.dg1_yls_inout_plan_c_c ipc
join dwd.dg1_yls_event_type_c et on et.pk_event_type = ipc.trans_type
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date
join dwd.dg1_yls_contract_c_c ycc on ycc.pk_contract = ipc.pk_contract
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ycc.stt_date and ycc.end_date
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ipc.stt_date and ipc.end_date
group by ipc.source_bill
) ipc on lc.pk_lease_calculator = ipc.source_bill
-- 历史数据
left join (
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,
h.lease_cash3,lease_cash22,h.lease_cash33,h.LEASE_INTEREST,
h.fact_cash2,h.fact_cash3
from dwd.dg1_yls_contract_h_c ch
join dwd.dg1_yls_rent_calculator_c rc on rc.PK_CONTRACT = ch.PK_CONTRACT
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between rc.stt_date and rc.end_date
join (
select iph.SOURCE_BILL,
sum(case when et.EVENT_CODE in ('10201','10202','10203','10216') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash, /* 收租总租金 */
sum(case when et.EVENT_CODE in ('10401'/*,'10402','10403'*/,'10405','10606') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash1, /* 手续费/咨询费/固定租金 */
sum(case when et.EVENT_CODE in ('10201','10202','10216') then coalesce(iph.LEASE_INTEREST,0) else 0 end) LEASE_INTEREST, /* 收租总租息 */
sum(case when et.EVENT_CODE in ('10301') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash2, /* 保证金收取 */
sum(case when et.EVENT_CODE in ('10308') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash22, /* 保证金补住 */
sum(case when et.EVENT_CODE in ('10302') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash3, /* 保证金冲抵*/
sum(case when et.EVENT_CODE in ('10304') then coalesce(iph.LEASE_CASH,0) else 0 end) lease_cash33, /* 保证金退还 */
sum(case when et.EVENT_CODE in ('10301','10308') then coalesce(iph.FACT_CASH,0) else 0 end) fact_cash2, /* 实收:保证金收取、补足 */
sum(case when et.EVENT_CODE in ('10302','10304') then coalesce(iph.FACT_CASH,0) else 0 end) fact_cash3 /* 实际:保证金冲抵、退还保证金 */
from dwd.dg1_yls_inout_plan_h_c iph
join dwd.dg1_yls_event_type_c et on et.PK_EVENT_TYPE = iph.TRANS_TYPE
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between et.stt_date and et.end_date
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between iph.stt_date and iph.end_date
group by iph.SOURCE_BILL
) h on h.SOURCE_BILL = rc.PK_RENT_CALCULATOR
where ch.SOURCE_BILL_VERSIONPK in (
select chh.PK_CONTRACT
from dwd.dg1_yls_contract_h_c chh
join (
select max(CHECK_DATE)CHECK_DATE,ch.cont_code
from dwd.dg1_yls_contract_h_c ch
where upper(ch.SOURCE_BILLTYPE) = upper('lease/ContractChange')
and ch.SOURCE_BILL_VERSIONPK is null
and ch.CHECK_DATE > '${yyyy-mm-dd}'
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ch.stt_date and ch.end_date
group by ch.CONT_CODE
)zj_change on zj_change.CHECK_DATE = chh.check_date and zj_change.cont_code = chh.cont_code
and upper(chh.SOURCE_BILLTYPE) = upper('lease/ContractChange')
and chh.SOURCE_BILL_VERSIONPK is null
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between chh.stt_date and chh.end_date
)
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ch.stt_date and ch.end_date
) history
on history.cont_code = cc.cont_code
-- 计划投放数量
left join (
select i5.pk_contract
,count(*) plan_count
from dwd.dg1_yls_inout_plan_c_c i5
where i5.trans_type in ('0001AA10000000005GRC','0001AA10000000007NGO','0001AA1000000005AB31', '0001AA1000000005AB32')
and i5.rent_type = 1
group by i5.pk_contract
) planc
on cc.pk_contract = planc.pk_contract
-- 租赁物信息
left join (
select ypfa1.param_name fixed_assets
,ypfa2.param_name fixed_assets_lag
,ypfa3.param_name fixed_assets_mid
,ypfa4.param_name fixed_assets_sml
,prtc.thing_name
,prtc.source_bill
from dwd.dg1_yls_project_rent_thing_c_c prtc
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
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa1.stt_date and ypfa1.end_date
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
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa2.stt_date and ypfa2.end_date
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
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa3.stt_date and ypfa3.end_date
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
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between ypfa4.stt_date and ypfa4.end_date
where prtc.is_ref_main = 0
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between prtc.stt_date and prtc.end_date
) main_thing
on cc.pk_contract = main_thing.source_bill
-- 主办
left join dwd.dwd_d01_party_c su
on cc.pk_prj_manager = su.cuserid
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between su.stt_date and su.end_date
-- 协办
left join dwd.dwd_d01_party_c su2
on cc.pk_cust_help = su2.cuserid
and to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between su2.stt_date and su2.end_date
left join (
select adj3.cont_code,
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,
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,
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,
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
from(
select adj.cont_code,
adj.response_day,
coalesce(min(case when adj.response_day < adj2.response_day then adj2.response_day end),'${yyyy-mm-dd}') response_day_end,
min(adj.interrate_after) interrate_after, -- /*调息后基准利率*/
min(adj.interrate_fact_after) interrate_fact_after, -- /*调息后实际利率*/
min(adj.project_irr) project_irr, -- /*调息后合同irr*/
min(adj.contract_xirr) contract_xirr -- /*合同收益xirr*/
from (select ch.cont_code,
ch.check_date as response_day,
rc.interrate as interrate_after,
rc.new_final_rate as interrate_fact_after,
rc.new_project_irr as project_irr,
rc.new_contract_xirr as contract_xirr
from dwd.dg1_yls_contract_h_c ch
join dwd.dg1_yls_rent_calculator_c rc on rc.pk_contract = ch.pk_contract
where upper(ch.source_billtype) = upper('lease/contractchange')
and ch.source_bill_versionpk is null
and ch.billstatus = 9
and date'${yyyy-mm-dd}' between ch.stt_date and ch.end_date
and date'${yyyy-mm-dd}' between rc.stt_date and rc.end_date
union all -- /*实际调息*/
select distinct cc.cont_code,aa.response_day,
aa.interrate_after, -- /*调息后基准利率*/
aa.interrate_fact_after, -- /*调息后实际利率*/
aa.project_irr, -- /*调息后合同irr*/
aa.contract_xirr -- /*合同收益xirr*/
from dwd.dg1_yls_adjust_apply_c aa
left join dwd.dg1_yls_contract_c_c cc on cc.pk_contract = aa.pk_contract
and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date
where aa.billstatus = 9
and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date
union all -- /*首次调息时,调息前信息*/
select distinct cc.cont_code,to_char(to_date(aa.response_day, 'yyyy-mm-dd') - 1, 'yyyy-mm-dd') as response_day,
aa.interrate_before as interrate_after, -- /*调息前基准利率*/
aa.interrate_fact_before as interrate_fact_after, -- /*调息前实际利率*/
aa.cont_irr_befor as project_irr, -- /*调息前合同irr*/
aa.contract_xirr_before as contract_xirr -- /*调息前合同收益xirr*/
from dwd.dg1_yls_adjust_apply_c aa
join (select min(a.response_day) as response_day,a.pk_contract
from dwd.dg1_yls_adjust_apply_c a
where a.billstatus = 9
and date'${yyyy-mm-dd}' between a.stt_date and a.end_date
group by a.pk_contract) minday
on minday.pk_contract = aa.pk_contract and minday.response_day = aa.response_day
and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date
left join dwd.dg1_yls_contract_c_c cc
on cc.pk_contract = aa.pk_contract
and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date) adj
left join (
select ch.cont_code,
ch.check_date as response_day,
rc.interrate as interrate_after,
rc.new_final_rate as interrate_fact_after,
rc.new_project_irr as project_irr,
rc.new_contract_xirr as contract_xirr
from dwd.dg1_yls_contract_h_c ch
join dwd.dg1_yls_rent_calculator_c rc on rc.pk_contract = ch.pk_contract
where upper(ch.source_billtype) = upper('lease/contractchange')
and ch.source_bill_versionpk is null
and ch.billstatus = 9
and date'${yyyy-mm-dd}' between ch.stt_date and ch.end_date
and date'${yyyy-mm-dd}' between rc.stt_date and rc.end_date
union all
select distinct cc.cont_code,aa.response_day,
aa.interrate_after, -- /*调息后基准利率*/
aa.interrate_fact_after, -- /*调息后实际利率*/
aa.project_irr, -- /*调息后合同irr*/
aa.contract_xirr -- /*合同收益xirr*/
from dwd.dg1_yls_adjust_apply_c aa
left join dwd.dg1_yls_contract_c_c cc on cc.pk_contract = aa.pk_contract
where aa.billstatus = 9
and date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date
and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date
union all
select distinct cc.cont_code,to_char(to_date(aa.response_day, 'yyyy-mm-dd') - 1, 'yyyy-mm-dd') as response_day,
aa.interrate_before as interrate_after, -- /*调息前基准利率*/
aa.interrate_fact_before as interrate_fact_after, -- /*调息前实际利率*/
aa.cont_irr_befor as project_irr, -- /*调息前合同irr*/
aa.contract_xirr_before as contract_xirr -- /*调息前合同收益xirr*/
from dwd.dg1_yls_adjust_apply_c aa
join (select min(a.response_day) as response_day,a.pk_contract
from dwd.dg1_yls_adjust_apply_c a
where a.billstatus = 9
and date'${yyyy-mm-dd}' between a.stt_date and a.end_date
group by a.pk_contract) minday
on minday.pk_contract = aa.pk_contract and minday.response_day = aa.response_day
left join dwd.dg1_yls_contract_c_c cc
on cc.pk_contract = aa.pk_contract
and date'${yyyy-mm-dd}' between cc.stt_date and cc.end_date
where date'${yyyy-mm-dd}' between aa.stt_date and aa.end_date
) adj2 on adj2.cont_code = adj.cont_code
group by adj.cont_code,adj.response_day
) adj3
group by adj3.cont_code
) adj on adj.cont_code = cc.cont_code
where to_date('${yyyy-mm-dd}', 'yyyy-mm-dd') between cc.stt_date and cc.end_date
-- PK_PARAM_TYPE = '0001AA1000000001RC3C' 合同状态
and cc.cont_status > '1'
and cc.cont_status not in ('5' ,'7')
================================================
FILE: superior-oracle-parser/src/test/resources/log4j2.xml
================================================
================================================
FILE: superior-postgres-parser/pom.xml
================================================
4.0.0
io.github.melin.superior
superior-sql-parser
4.0.23
superior-postgres-parser
superior-postgres-parser
io.github.melin.superior
superior-common-parser
${project.version}
================================================
FILE: superior-postgres-parser/src/main/antlr4/io/github/melin/superior/parser/postgre/antlr4/PostgreSqlLexer.g4
================================================
/*
based on
https://github.com/tunnelvisionlabs/antlr4-grammar-postgresql/blob/master/src/com/tunnelvisionlabs/postgresql/PostgreSqlLexer.g4
*/
/*
* [The "MIT license"]
* Copyright (C) 2014 Sam Harwell, Tunnel Vision Laboratories, LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 1. The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 2. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
* 3. Except as contained in this notice, the name of Tunnel Vision
* Laboratories, LLC. shall not be used in advertising or otherwise to
* promote the sale, use or other dealings in this Software without prior
* written authorization from Tunnel Vision Laboratories, LLC.
*/
lexer grammar PostgreSqlLexer;
/* Reference:
* http://www.postgresql.org/docs/9.3/static/sql-syntax-lexical.html
*/
options {
superClass = PostgreSqlLexerBase;
}
@ header
{
}
@ members
{
/* This field stores the tags which are used to detect the end of a dollar-quoted string literal.
*/
}
//
// SPECIAL CHARACTERS (4.1.4)
//
// Note that Asterisk is a valid operator, but does not have the type Operator due to its syntactic use in locations
// that are not expressions.
Dollar
: '$'
;
OPEN_PAREN
: '('
;
CLOSE_PAREN
: ')'
;
OPEN_BRACKET
: '['
;
CLOSE_BRACKET
: ']'
;
COMMA
: ','
;
SEMI
: ';'
;
COLON
: ':'
;
STAR
: '*'
;
EQUAL
: '='
;
DOT
: '.'
;
//NamedArgument : ':=';
PLUS
: '+'
;
MINUS
: '-'
;
SLASH
: '/'
;
CARET
: '^'
;
LT
: '<'
;
GT
: '>'
;
LESS_LESS
: '<<'
;
GREATER_GREATER
: '>>'
;
COLON_EQUALS
: ':='
;
LESS_EQUALS
: '<='
;
EQUALS_GREATER
: '=>'
;
GREATER_EQUALS
: '>='
;
DOT_DOT
: '..'
;
NOT_EQUALS
: '<>'
;
TYPECAST
: '::'
;
PERCENT
: '%'
;
PARAM
: '$' ([0-9])+
;
//
// OPERATORS (4.1.3)
//
// this rule does not allow + or - at the end of a multi-character operator
Operator
: ((OperatorCharacter | ('+' | '-'
{checkLA('-')}?)+ (OperatorCharacter | '/'
{checkLA('*')}?) | '/'
{checkLA('*')}?)+ | // special handling for the single-character operators + and -
[+-])
//TODO somehow rewrite this part without using Actions
{
HandleLessLessGreaterGreater();
}
;
/* This rule handles operators which end with + or -, and sets the token type to Operator. It is comprised of four
* parts, in order:
*
* 1. A prefix, which does not contain a character from the required set which allows + or - to appear at the end of
* the operator.
* 2. A character from the required set which allows + or - to appear at the end of the operator.
* 3. An optional sub-token which takes the form of an operator which does not include a + or - at the end of the
* sub-token.
* 4. A suffix sequence of + and - characters.
*/
OperatorEndingWithPlusMinus
: (OperatorCharacterNotAllowPlusMinusAtEnd | '-'
{checkLA('-')}? | '/'
{checkLA('*')}?)* OperatorCharacterAllowPlusMinusAtEnd Operator? ('+' | '-'
{checkLA('-')}?)+ -> type (Operator)
;
// Each of the following fragment rules omits the +, -, and / characters, which must always be handled in a special way
// by the operator rules above.
fragment OperatorCharacter
: [*<>=~!@%^&|`?#]
;
// these are the operator characters that don't count towards one ending with + or -
fragment OperatorCharacterNotAllowPlusMinusAtEnd
: [*<>=+]
;
// an operator may end with + or - if it contains one of these characters
fragment OperatorCharacterAllowPlusMinusAtEnd
: [~!@%^&|`?#]
;
//
// KEYWORDS (Appendix C)
//
//
// reserved keywords
//
ALL
: 'ALL'
;
ANALYSE
: 'ANALYSE'
;
ANALYZE
: 'ANALYZE'
;
AND
: 'AND'
;
ANY
: 'ANY'
;
ARRAY
: 'ARRAY'
;
AS
: 'AS'
;
ASC
: 'ASC'
;
ASYMMETRIC
: 'ASYMMETRIC'
;
BOTH
: 'BOTH'
;
CASE
: 'CASE'
;
CAST
: 'CAST'
;
CHECK
: 'CHECK'
;
COLLATE
: 'COLLATE'
;
COLUMN
: 'COLUMN'
;
CONSTRAINT
: 'CONSTRAINT'
;
CREATE
: 'CREATE'
;
CURRENT_CATALOG
: 'CURRENT_CATALOG'
;
CURRENT_DATE
: 'CURRENT_DATE'
;
CURRENT_ROLE
: 'CURRENT_ROLE'
;
CURRENT_TIME
: 'CURRENT_TIME'
;
CURRENT_TIMESTAMP
: 'CURRENT_TIMESTAMP'
;
CURRENT_USER
: 'CURRENT_USER'
;
DEFAULT
: 'DEFAULT'
;
DEFERRABLE
: 'DEFERRABLE'
;
DESC
: 'DESC'
;
DISTINCT
: 'DISTINCT'
;
DO
: 'DO'
;
ELSE
: 'ELSE'
;
EXCEPT
: 'EXCEPT'
;
FALSE_P
: 'FALSE'
;
FETCH
: 'FETCH'
;
FOR
: 'FOR'
;
FOREIGN
: 'FOREIGN'
;
FROM
: 'FROM'
;
GRANT
: 'GRANT'
;
GROUP_P
: 'GROUP'
;
HAVING
: 'HAVING'
;
IN_P
: 'IN'
;
INITIALLY
: 'INITIALLY'
;
INTERSECT
: 'INTERSECT'
;
INTO
: 'INTO'
;
LATERAL_P
: 'LATERAL'
;
LEADING
: 'LEADING'
;
LIMIT
: 'LIMIT'
;
LOCALTIME
: 'LOCALTIME'
;
LOCALTIMESTAMP
: 'LOCALTIMESTAMP'
;
NOT
: 'NOT'
;
NULL_P
: 'NULL'
;
OFFSET
: 'OFFSET'
;
ON
: 'ON'
;
ONLY
: 'ONLY'
;
OR
: 'OR'
;
ORDER
: 'ORDER'
;
PLACING
: 'PLACING'
;
PRIMARY
: 'PRIMARY'
;
REFERENCES
: 'REFERENCES'
;
RETURNING
: 'RETURNING'
;
SELECT
: 'SELECT'
;
SESSION_USER
: 'SESSION_USER'
;
SOME
: 'SOME'
;
SYMMETRIC
: 'SYMMETRIC'
;
TABLE
: 'TABLE'
;
THEN
: 'THEN'
;
TO
: 'TO'
;
TRAILING
: 'TRAILING'
;
TRUE_P
: 'TRUE'
;
UNION
: 'UNION'
;
UNIQUE
: 'UNIQUE'
;
USER
: 'USER'
;
USING
: 'USING'
;
VARIADIC
: 'VARIADIC'
;
WHEN
: 'WHEN'
;
WHERE
: 'WHERE'
;
WINDOW
: 'WINDOW'
;
WITH
: 'WITH'
;
//
// reserved keywords (can be function or type)
//
AUTHORIZATION
: 'AUTHORIZATION'
;
BINARY
: 'BINARY'
;
COLLATION
: 'COLLATION'
;
CONCURRENTLY
: 'CONCURRENTLY'
;
CROSS
: 'CROSS'
;
CURRENT_SCHEMA
: 'CURRENT_SCHEMA'
;
FREEZE
: 'FREEZE'
;
FULL
: 'FULL'
;
ILIKE
: 'ILIKE'
;
INNER_P
: 'INNER'
;
IS
: 'IS'
;
ISNULL
: 'ISNULL'
;
JOIN
: 'JOIN'
;
LEFT
: 'LEFT'
;
LIKE
: 'LIKE'
;
NATURAL
: 'NATURAL'
;
NOTNULL
: 'NOTNULL'
;
OUTER_P
: 'OUTER'
;
OVER
: 'OVER'
;
OVERLAPS
: 'OVERLAPS'
;
RIGHT
: 'RIGHT'
;
SIMILAR
: 'SIMILAR'
;
VERBOSE
: 'VERBOSE'
;
//
// non-reserved keywords
//
ABORT_P
: 'ABORT'
;
ABSOLUTE_P
: 'ABSOLUTE'
;
ACCESS
: 'ACCESS'
;
ACTION
: 'ACTION'
;
ADD_P
: 'ADD'
;
ADMIN
: 'ADMIN'
;
AFTER
: 'AFTER'
;
AGGREGATE
: 'AGGREGATE'
;
ALSO
: 'ALSO'
;
ALTER
: 'ALTER'
;
ALWAYS
: 'ALWAYS'
;
ASSERTION
: 'ASSERTION'
;
ASSIGNMENT
: 'ASSIGNMENT'
;
AT
: 'AT'
;
ATTRIBUTE
: 'ATTRIBUTE'
;
BACKWARD
: 'BACKWARD'
;
BEFORE
: 'BEFORE'
;
BEGIN_P
: 'BEGIN'
;
BY
: 'BY'
;
CACHE
: 'CACHE'
;
CALLED
: 'CALLED'
;
CASCADE
: 'CASCADE'
;
CASCADED
: 'CASCADED'
;
CATALOG
: 'CATALOG'
;
CHAIN
: 'CHAIN'
;
CHARACTERISTICS
: 'CHARACTERISTICS'
;
CHECKPOINT
: 'CHECKPOINT'
;
CLASS
: 'CLASS'
;
CLOSE
: 'CLOSE'
;
CLUSTER
: 'CLUSTER'
;
COMMENT
: 'COMMENT'
;
COMMENTS
: 'COMMENTS'
;
COMMIT
: 'COMMIT'
;
COMMITTED
: 'COMMITTED'
;
CONFIGURATION
: 'CONFIGURATION'
;
CONNECTION
: 'CONNECTION'
;
CONSTRAINTS
: 'CONSTRAINTS'
;
CONTENT_P
: 'CONTENT'
;
CONTINUE_P
: 'CONTINUE'
;
CONVERSION_P
: 'CONVERSION'
;
COPY
: 'COPY'
;
COST
: 'COST'
;
CSV
: 'CSV'
;
CURSOR
: 'CURSOR'
;
CYCLE
: 'CYCLE'
;
DATA_P
: 'DATA'
;
DATABASE
: 'DATABASE'
;
DAY_P
: 'DAY'
;
DEALLOCATE
: 'DEALLOCATE'
;
DECLARE
: 'DECLARE'
;
DEFAULTS
: 'DEFAULTS'
;
DEFERRED
: 'DEFERRED'
;
DEFINER
: 'DEFINER'
;
DELETE_P
: 'DELETE'
;
DELIMITER
: 'DELIMITER'
;
DELIMITERS
: 'DELIMITERS'
;
DICTIONARY
: 'DICTIONARY'
;
DISABLE_P
: 'DISABLE'
;
DISCARD
: 'DISCARD'
;
DOCUMENT_P
: 'DOCUMENT'
;
DOMAIN_P
: 'DOMAIN'
;
DOUBLE_P
: 'DOUBLE'
;
DROP
: 'DROP'
;
EACH
: 'EACH'
;
ENABLE_P
: 'ENABLE'
;
ENCODING
: 'ENCODING'
;
ENCRYPTED
: 'ENCRYPTED'
;
ENUM_P
: 'ENUM'
;
ESCAPE
: 'ESCAPE'
;
EVENT
: 'EVENT'
;
EXCLUDE
: 'EXCLUDE'
;
EXCLUDING
: 'EXCLUDING'
;
EXCLUSIVE
: 'EXCLUSIVE'
;
EXECUTE
: 'EXECUTE'
;
EXPLAIN
: 'EXPLAIN'
;
EXTENSION
: 'EXTENSION'
;
EXTERNAL
: 'EXTERNAL'
;
FAMILY
: 'FAMILY'
;
FIRST_P
: 'FIRST'
;
FOLLOWING
: 'FOLLOWING'
;
FORCE
: 'FORCE'
;
FORWARD
: 'FORWARD'
;
FUNCTION
: 'FUNCTION'
;
FUNCTIONS
: 'FUNCTIONS'
;
GLOBAL
: 'GLOBAL'
;
GRANTED
: 'GRANTED'
;
HANDLER
: 'HANDLER'
;
HEADER_P
: 'HEADER'
;
HOLD
: 'HOLD'
;
HOUR_P
: 'HOUR'
;
IDENTITY_P
: 'IDENTITY'
;
IF_P
: 'IF'
;
IMMEDIATE
: 'IMMEDIATE'
;
IMMUTABLE
: 'IMMUTABLE'
;
IMPLICIT_P
: 'IMPLICIT'
;
INCLUDING
: 'INCLUDING'
;
INCREMENT
: 'INCREMENT'
;
INDEX
: 'INDEX'
;
INDEXES
: 'INDEXES'
;
INHERIT
: 'INHERIT'
;
INHERITS
: 'INHERITS'
;
INLINE_P
: 'INLINE'
;
INSENSITIVE
: 'INSENSITIVE'
;
INSERT
: 'INSERT'
;
INSTEAD
: 'INSTEAD'
;
INVOKER
: 'INVOKER'
;
ISOLATION
: 'ISOLATION'
;
KEY
: 'KEY'
;
LABEL
: 'LABEL'
;
LANGUAGE
: 'LANGUAGE'
;
LARGE_P
: 'LARGE'
;
LAST_P
: 'LAST'
;
//LC_COLLATE : 'LC'_'COLLATE;
//LC_CTYPE : 'LC'_'CTYPE;
LEAKPROOF
: 'LEAKPROOF'
;
SHIPPABLE
: 'SHIPPABLE'
;
FENCED
: 'FENCED'
;
PACKAGE
: 'PACKAGE'
;
LEVEL
: 'LEVEL'
;
LISTEN
: 'LISTEN'
;
LOAD
: 'LOAD'
;
LOCAL
: 'LOCAL'
;
LOCATION
: 'LOCATION'
;
LOCK_P
: 'LOCK'
;
MAPPING
: 'MAPPING'
;
MATCH
: 'MATCH'
;
MATCHED
: 'MATCHED'
;
MATERIALIZED
: 'MATERIALIZED'
;
MAXVALUE
: 'MAXVALUE'
;
MERGE
: 'MERGE'
;
MINUTE_P
: 'MINUTE'
;
MINVALUE
: 'MINVALUE'
;
MODE
: 'MODE'
;
MONTH_P
: 'MONTH'
;
MOVE
: 'MOVE'
;
NAME_P
: 'NAME'
;
NAMES
: 'NAMES'
;
NEXT
: 'NEXT'
;
NO
: 'NO'
;
NOTHING
: 'NOTHING'
;
NOTIFY
: 'NOTIFY'
;
NOWAIT
: 'NOWAIT'
;
NULLS_P
: 'NULLS'
;
OBJECT_P
: 'OBJECT'
;
OF
: 'OF'
;
OFF
: 'OFF'
;
OIDS
: 'OIDS'
;
OPERATOR
: 'OPERATOR'
;
OPTION
: 'OPTION'
;
OPTIONS
: 'OPTIONS'
;
OWNED
: 'OWNED'
;
OWNER
: 'OWNER'
;
PARSER
: 'PARSER'
;
PARTIAL
: 'PARTIAL'
;
PARTITION
: 'PARTITION'
;
PASSING
: 'PASSING'
;
PASSWORD
: 'PASSWORD'
;
PLANS
: 'PLANS'
;
PRECEDING
: 'PRECEDING'
;
PREPARE
: 'PREPARE'
;
PREPARED
: 'PREPARED'
;
PRESERVE
: 'PRESERVE'
;
PRIOR
: 'PRIOR'
;
PRIVILEGES
: 'PRIVILEGES'
;
PROCEDURAL
: 'PROCEDURAL'
;
PROCEDURE
: 'PROCEDURE'
;
PROGRAM
: 'PROGRAM'
;
QUOTE
: 'QUOTE'
;
RANGE
: 'RANGE'
;
READ
: 'READ'
;
REASSIGN
: 'REASSIGN'
;
RECHECK
: 'RECHECK'
;
RECURSIVE
: 'RECURSIVE'
;
REF
: 'REF'
;
REFRESH
: 'REFRESH'
;
REINDEX
: 'REINDEX'
;
RELATIVE_P
: 'RELATIVE'
;
RELEASE
: 'RELEASE'
;
RENAME
: 'RENAME'
;
REPEATABLE
: 'REPEATABLE'
;
REPLACE
: 'REPLACE'
;
REPLICA
: 'REPLICA'
;
RESET
: 'RESET'
;
RESTART
: 'RESTART'
;
RESTRICT
: 'RESTRICT'
;
RETURNS
: 'RETURNS'
;
REVOKE
: 'REVOKE'
;
ROLE
: 'ROLE'
;
ROLLBACK
: 'ROLLBACK'
;
ROWS
: 'ROWS'
;
RULE
: 'RULE'
;
SAVEPOINT
: 'SAVEPOINT'
;
SCHEMA
: 'SCHEMA'
;
SCROLL
: 'SCROLL'
;
SEARCH
: 'SEARCH'
;
SECOND_P
: 'SECOND'
;
SECURITY
: 'SECURITY'
;
SEQUENCE
: 'SEQUENCE'
;
SEQUENCES
: 'SEQUENCES'
;
SERIALIZABLE
: 'SERIALIZABLE'
;
SERVER
: 'SERVER'
;
SESSION
: 'SESSION'
;
SET
: 'SET'
;
SHARE
: 'SHARE'
;
SHOW
: 'SHOW'
;
SIMPLE
: 'SIMPLE'
;
SNAPSHOT
: 'SNAPSHOT'
;
STABLE
: 'STABLE'
;
STANDALONE_P
: 'STANDALONE'
;
START
: 'START'
;
STATEMENT
: 'STATEMENT'
;
STATISTICS
: 'STATISTICS'
;
STDIN
: 'STDIN'
;
STDOUT
: 'STDOUT'
;
STORAGE
: 'STORAGE'
;
STRICT_P
: 'STRICT'
;
STRIP_P
: 'STRIP'
;
SYSID
: 'SYSID'
;
SYSTEM_P
: 'SYSTEM'
;
TABLES
: 'TABLES'
;
TABLESPACE
: 'TABLESPACE'
;
TEMP
: 'TEMP'
;
TEMPLATE
: 'TEMPLATE'
;
TEMPORARY
: 'TEMPORARY'
;
TEXT_P
: 'TEXT'
;
TRANSACTION
: 'TRANSACTION'
;
TRIGGER
: 'TRIGGER'
;
TRUNCATE
: 'TRUNCATE'
;
TRUSTED
: 'TRUSTED'
;
TYPE_P
: 'TYPE'
;
TYPES_P
: 'TYPES'
;
UNBOUNDED
: 'UNBOUNDED'
;
UNCOMMITTED
: 'UNCOMMITTED'
;
UNENCRYPTED
: 'UNENCRYPTED'
;
UNKNOWN
: 'UNKNOWN'
;
UNLISTEN
: 'UNLISTEN'
;
UNLOGGED
: 'UNLOGGED'
;
UNTIL
: 'UNTIL'
;
UPDATE
: 'UPDATE'
;
VACUUM
: 'VACUUM'
;
VALID
: 'VALID'
;
VALIDATE
: 'VALIDATE'
;
VALIDATOR
: 'VALIDATOR'
;
//VALUE : 'VALUE;
VARYING
: 'VARYING'
;
VERSION_P
: 'VERSION'
;
VIEW
: 'VIEW'
;
VOLATILE
: 'VOLATILE'
;
WHITESPACE_P
: 'WHITESPACE'
;
WITHOUT
: 'WITHOUT'
;
WORK
: 'WORK'
;
WRAPPER
: 'WRAPPER'
;
WRITE
: 'WRITE'
;
XML_P
: 'XML'
;
YEAR_P
: 'YEAR'
;
YES_P
: 'YES'
;
ZONE
: 'ZONE'
;
//
// non-reserved keywords (can not be function or type)
//
BETWEEN
: 'BETWEEN'
;
BIGINT
: 'BIGINT'
;
BIT
: 'BIT'
;
BOOLEAN_P
: 'BOOLEAN'
;
CHAR_P
: 'CHAR'
;
CHARACTER
: 'CHARACTER'
;
COALESCE
: 'COALESCE'
;
DEC
: 'DEC'
;
DECIMAL_P
: 'DECIMAL'
;
EXISTS
: 'EXISTS'
;
EXTRACT
: 'EXTRACT'
;
FLOAT_P
: 'FLOAT'
;
GREATEST
: 'GREATEST'
;
INOUT
: 'INOUT'
;
INT_P
: 'INT'
;
INTEGER
: 'INTEGER'
;
INTERVAL
: 'INTERVAL'
;
LEAST
: 'LEAST'
;
NATIONAL
: 'NATIONAL'
;
NCHAR
: 'NCHAR'
;
NONE
: 'NONE'
;
NULLIF
: 'NULLIF'
;
NUMERIC
: 'NUMERIC'
;
OVERLAY
: 'OVERLAY'
;
POSITION
: 'POSITION'
;
PRECISION
: 'PRECISION'
;
REAL
: 'REAL'
;
ROW
: 'ROW'
;
SETOF
: 'SETOF'
;
SMALLINT
: 'SMALLINT'
;
SUBSTRING
: 'SUBSTRING'
;
TIME
: 'TIME'
;
TIMESTAMP
: 'TIMESTAMP'
;
TREAT
: 'TREAT'
;
TRIM
: 'TRIM'
;
VALUES
: 'VALUES'
;
VARCHAR
: 'VARCHAR'
;
XMLATTRIBUTES
: 'XMLATTRIBUTES'
;
XMLCOMMENT
: 'XMLCOMMENT'
;
XMLAGG
: 'XMLAGG'
;
XML_IS_WELL_FORMED
: 'XML_IS_WELL_FORMED'
;
XML_IS_WELL_FORMED_DOCUMENT
: 'XML_IS_WELL_FORMED_DOCUMENT'
;
XML_IS_WELL_FORMED_CONTENT
: 'XML_IS_WELL_FORMED_CONTENT'
;
XPATH
: 'XPATH'
;
XPATH_EXISTS
: 'XPATH_EXISTS'
;
XMLCONCAT
: 'XMLCONCAT'
;
XMLELEMENT
: 'XMLELEMENT'
;
XMLEXISTS
: 'XMLEXISTS'
;
XMLFOREST
: 'XMLFOREST'
;
XMLPARSE
: 'XMLPARSE'
;
XMLPI
: 'XMLPI'
;
XMLROOT
: 'XMLROOT'
;
XMLSERIALIZE
: 'XMLSERIALIZE'
;
//MISSED
CALL
: 'CALL'
;
CURRENT_P
: 'CURRENT'
;
ATTACH
: 'ATTACH'
;
DETACH
: 'DETACH'
;
EXPRESSION
: 'EXPRESSION'
;
GENERATED
: 'GENERATED'
;
LOGGED
: 'LOGGED'
;
STORED
: 'STORED'
;
INCLUDE
: 'INCLUDE'
;
ROUTINE
: 'ROUTINE'
;
TRANSFORM
: 'TRANSFORM'
;
IMPORT_P
: 'IMPORT'
;
POLICY
: 'POLICY'
;
METHOD
: 'METHOD'
;
REFERENCING
: 'REFERENCING'
;
NEW
: 'NEW'
;
OLD
: 'OLD'
;
VALUE_P
: 'VALUE'
;
SUBSCRIPTION
: 'SUBSCRIPTION'
;
PUBLICATION
: 'PUBLICATION'
;
OUT_P
: 'OUT'
;
END_P
: 'END'
;
ROUTINES
: 'ROUTINES'
;
SCHEMAS
: 'SCHEMAS'
;
PROCEDURES
: 'PROCEDURES'
;
INPUT_P
: 'INPUT'
;
SUPPORT
: 'SUPPORT'
;
PARALLEL
: 'PARALLEL'
;
SQL_P
: 'SQL'
;
DEPENDS
: 'DEPENDS'
;
OVERRIDING
: 'OVERRIDING'
;
// support gauss start--------------------------------
AUTOMAPPED
: 'AUTOMAPPED'
;
SAMPLE
: 'SAMPLE'
;
PERCENT_P
: 'PERCENT'
;
STAT
: 'STAT'
;
COLLECT
: 'COLLECT'
;
MULTISET
: 'MULTISET'
;
MINUS_P
: 'MINUS'
;
GROUPCONCAT
: 'GROUP_CONCAT'
;
SEPARATOR
: 'SEPARATOR'
;
IGNORE
: 'IGNORE'
;
OPEN_BRACE
: '{'
;
CLOSE_BRACE
: '}'
;
OVERWRITE
: 'OVERWRITE'
;
DISTRIBUTE
: 'DISTRIBUTE'
;
DISTRIBUTED
: 'DISTRIBUTED'
;
DISTRIBUTION
: 'DISTRIBUTION'
;
REPLICATION
: 'REPLICATION'
;
ROUNDROBIN
: 'ROUNDROBIN'
;
HASH
: 'HASH'
;
RANDOMLY
: 'RANDOMLY'
;
NODE_P
: 'NODE'
;
LIST_P
: 'LIST'
;
LESS
: 'LESS'
;
THAN
: 'THAN'
;
EVERY
: 'EVERY'
;
MOVEMENT
: 'MOVEMENT'
;
TSTag
: 'TSTag'
;
TSTime
: 'TSTime'
;
TSField
: 'TSField'
;
REPLICATED
: 'REPLICATED'
;
// support gauss end --------------------------------
CONFLICT
: 'CONFLICT'
;
SKIP_P
: 'SKIP'
;
LOCKED
: 'LOCKED'
;
TIES
: 'TIES'
;
ROLLUP
: 'ROLLUP'
;
CUBE
: 'CUBE'
;
GROUPING
: 'GROUPING'
;
SETS
: 'SETS'
;
TABLESAMPLE
: 'TABLESAMPLE'
;
ORDINALITY
: 'ORDINALITY'
;
XMLTABLE
: 'XMLTABLE'
;
COLUMNS
: 'COLUMNS'
;
XMLNAMESPACES
: 'XMLNAMESPACES'
;
ROWTYPE
: 'ROWTYPE'
;
NORMALIZED
: 'NORMALIZED'
;
WITHIN
: 'WITHIN'
;
FILTER
: 'FILTER'
;
GROUPS
: 'GROUPS'
;
OTHERS
: 'OTHERS'
;
NFC
: 'NFC'
;
NFD
: 'NFD'
;
NFKC
: 'NFKC'
;
NFKD
: 'NFKD'
;
UESCAPE
: 'UESCAPE'
;
VIEWS
: 'VIEWS'
;
NORMALIZE
: 'NORMALIZE'
;
DUMP
: 'DUMP'
;
PRINT_STRICT_PARAMS
: 'PRINT_STRICT_PARAMS'
;
VARIABLE_CONFLICT
: 'VARIABLE_CONFLICT'
;
ERROR
: 'ERROR'
;
USE_VARIABLE
: 'USE_VARIABLE'
;
USE_COLUMN
: 'USE_COLUMN'
;
ALIAS
: 'ALIAS'
;
CONSTANT
: 'CONSTANT'
;
PERFORM
: 'PERFORM'
;
GET
: 'GET'
;
DIAGNOSTICS
: 'DIAGNOSTICS'
;
STACKED
: 'STACKED'
;
ELSIF
: 'ELSIF'
;
WHILE
: 'WHILE'
;
REVERSE
: 'REVERSE'
;
FOREACH
: 'FOREACH'
;
SLICE
: 'SLICE'
;
EXIT
: 'EXIT'
;
RETURN
: 'RETURN'
;
QUERY
: 'QUERY'
;
RAISE
: 'RAISE'
;
SQLSTATE
: 'SQLSTATE'
;
DEBUG
: 'DEBUG'
;
LOG
: 'LOG'
;
INFO
: 'INFO'
;
NOTICE
: 'NOTICE'
;
WARNING
: 'WARNING'
;
EXCEPTION
: 'EXCEPTION'
;
ASSERT
: 'ASSERT'
;
LOOP
: 'LOOP'
;
OPEN
: 'OPEN'
;
//
// IDENTIFIERS (4.1.1)
//
ABS
: 'ABS'
;
CBRT
: 'CBRT'
;
CEIL
: 'CEIL'
;
CEILING
: 'CEILING'
;
DEGREES
: 'DEGREES'
;
DIV
: 'DIV'
;
EXP
: 'EXP'
;
FACTORIAL
: 'FACTORIAL'
;
FLOOR
: 'FLOOR'
;
GCD
: 'GCD'
;
LCM
: 'LCM'
;
LN
: 'LN'
;
LOG10
: 'LOG10'
;
MIN_SCALE
: 'MIN_SCALE'
;
MOD
: 'MOD'
;
PI
: 'PI'
;
POWER
: 'POWER'
;
RADIANS
: 'RADIANS'
;
ROUND
: 'ROUND'
;
SCALE
: 'SCALE'
;
SIGN
: 'SIGN'
;
SQRT
: 'SQRT'
;
TRIM_SCALE
: 'TRIM_SCALE'
;
TRUNC
: 'TRUNC'
;
WIDTH_BUCKET
: 'WIDTH_BUCKET'
;
RANDOM
: 'RANDOM'
;
SETSEED
: 'SETSEED'
;
ACOS
: 'ACOS'
;
ACOSD
: 'ACOSD'
;
ASIN
: 'ASIN'
;
ASIND
: 'ASIND'
;
ATAN
: 'ATAN'
;
ATAND
: 'ATAND'
;
ATAN2
: 'ATAN2'
;
ATAN2D
: 'ATAN2D'
;
COS
: 'COS'
;
COSD
: 'COSD'
;
COT
: 'COT'
;
COTD
: 'COTD'
;
SIN
: 'SIN'
;
SIND
: 'SIND'
;
TAN
: 'TAN'
;
TAND
: 'TAND'
;
SINH
: 'SINH'
;
COSH
: 'COSH'
;
TANH
: 'TANH'
;
ASINH
: 'ASINH'
;
ACOSH
: 'ACOSH'
;
ATANH
: 'ATANH'
;
BIT_LENGTH
: 'BIT_LENGTH'
;
CHAR_LENGTH
: 'CHAR_LENGTH'
;
CHARACTER_LENGTH
: 'CHARACTER_LENGTH'
;
LOWER
: 'LOWER'
;
OCTET_LENGTH
: 'OCTET_LENGTH'
;
UPPER
: 'UPPER'
;
ASCII
: 'ASCII'
;
BTRIM
: 'BTRIM'
;
CHR
: 'CHR'
;
CONCAT
: 'CONCAT'
;
CONCAT_WS
: 'CONCAT_WS'
;
FORMAT
: 'FORMAT'
;
INITCAP
: 'INITCAP'
;
LENGTH
: 'LENGTH'
;
LPAD
: 'LPAD'
;
LTRIM
: 'LTRIM'
;
MD5
: 'MD5'
;
PARSE_IDENT
: 'PARSE_IDENT'
;
PG_CLIENT_ENCODING
: 'PG_CLIENT_ENCODING'
;
QUOTE_IDENT
: 'QUOTE_IDENT'
;
QUOTE_LITERAL
: 'QUOTE_LITERAL'
;
QUOTE_NULLABLE
: 'QUOTE_NULLABLE'
;
REGEXP_COUNT
: 'REGEXP_COUNT'
;
REGEXP_INSTR
: 'REGEXP_INSTR'
;
REGEXP_LIKE
: 'REGEXP_LIKE'
;
REGEXP_MATCH
: 'REGEXP_MATCH'
;
REGEXP_MATCHES
: 'REGEXP_MATCHES'
;
REGEXP_REPLACE
: 'REGEXP_REPLACE'
;
REGEXP_SPLIT_TO_ARRAY
: 'REGEXP_SPLIT_TO_ARRAY'
;
REGEXP_SPLIT_TO_TABLE
: 'REGEXP_SPLIT_TO_TABLE'
;
REGEXP_SUBSTR
: 'REGEXP_SUBSTR'
;
REPEAT
: 'REPEAT'
;
RPAD
: 'RPAD'
;
RTRIM
: 'RTRIM'
;
SPLIT_PART
: 'SPLIT_PART'
;
STARTS_WITH
: 'STARTS_WITH'
;
STRING_TO_ARRAY
: 'STRING_TO_ARRAY'
;
STRING_TO_TABLE
: 'STRING_TO_TABLE'
;
STRPOS
: 'STRPOS'
;
SUBSTR
: 'SUBSTR'
;
TO_ASCII
: 'TO_ASCII'
;
TO_HEX
: 'TO_HEX'
;
TRANSLATE
: 'TRANSLATE'
;
UNISTR
: 'UNISTR'
;
AGE
: 'AGE'
;
CLOCK_TIMESTAMP
: 'CLOCK_TIMESTAMP'
;
DATE_BIN
: 'DATE_BIN'
;
DATE_PART
: 'DATE_PART'
;
DATE_TRUNC
: 'DATE_TRUNC'
;
ISFINITE
: 'ISFINITE'
;
JUSTIFY_DAYS
: 'JUSTIFY_DAYS'
;
JUSTIFY_HOURS
: 'JUSTIFY_HOURS'
;
JUSTIFY_INTERVAL
: 'JUSTIFY_INTERVAL'
;
MAKE_DATE
: 'MAKE_DATE'
;
MAKE_INTERVAL
: 'MAKE_INTERVAL'
;
MAKE_TIME
: 'MAKE_TIME'
;
MAKE_TIMESTAMP
: 'MAKE_TIMESTAMP'
;
MAKE_TIMESTAMPTZ
: 'MAKE_TIMESTAMPTZ'
;
NOW
: 'NOW'
;
STATEMENT_TIMESTAMP
: 'STATEMENT_TIMESTAMP'
;
TIMEOFDAY
: 'TIMEOFDAY'
;
TRANSACTION_TIMESTAMP
: 'TRANSACTION_TIMESTAMP'
;
TO_TIMESTAMP
: 'TO_TIMESTAMP'
;
TO_CHAR
: 'TO_CHAR'
;
TO_DATE
: 'TO_DATE'
;
TO_NUMBER
: 'TO_NUMBER'
;
Identifier
: IdentifierStartChar IdentifierChar*
;
fragment IdentifierStartChar
: // these are the valid identifier start characters below 0x7F
[a-zA-Z_]
| // these are the valid characters from 0x80 to 0xFF
[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]
| // these are the letters above 0xFF which only need a single UTF-16 code unit
[\u0100-\uD7FF\uE000-\uFFFF]
{charIsLetter()}?
| // letters which require multiple UTF-16 code units
[\uD800-\uDBFF] [\uDC00-\uDFFF]
{
CheckIfUtf32Letter()
}?
;
fragment IdentifierChar
: StrictIdentifierChar
| '$'
;
fragment StrictIdentifierChar
: IdentifierStartChar
| [0-9]
;
/* Quoted Identifiers
*
* These are divided into four separate tokens, allowing distinction of valid quoted identifiers from invalid quoted
* identifiers without sacrificing the ability of the lexer to reliably recover from lexical errors in the input.
*/
QuotedIdentifier
: UnterminatedQuotedIdentifier '"'
;
// This is a quoted identifier which only contains valid characters but is not terminated
UnterminatedQuotedIdentifier
: '"' ('""' | ~ [\u0000"])*
;
// This is a quoted identifier which is terminated but contains a \u0000 character
InvalidQuotedIdentifier
: InvalidUnterminatedQuotedIdentifier '"'
;
// This is a quoted identifier which is unterminated and contains a \u0000 character
InvalidUnterminatedQuotedIdentifier
: '"' ('""' | ~ '"')*
;
/* Unicode Quoted Identifiers
*
* These are divided into four separate tokens, allowing distinction of valid Unicode quoted identifiers from invalid
* Unicode quoted identifiers without sacrificing the ability of the lexer to reliably recover from lexical errors in
* the input. Note that escape sequences are never checked as part of this determination due to the ability of users
* to change the escape character with a UESCAPE clause following the Unicode quoted identifier.
*
* TODO: these rules assume "" is still a valid escape sequence within a Unicode quoted identifier.
*/
UnicodeQuotedIdentifier
: 'U' '&' QuotedIdentifier
;
// This is a Unicode quoted identifier which only contains valid characters but is not terminated
UnterminatedUnicodeQuotedIdentifier
: 'U' '&' UnterminatedQuotedIdentifier
;
// This is a Unicode quoted identifier which is terminated but contains a \u0000 character
InvalidUnicodeQuotedIdentifier
: 'U' '&' InvalidQuotedIdentifier
;
// This is a Unicode quoted identifier which is unterminated and contains a \u0000 character
InvalidUnterminatedUnicodeQuotedIdentifier
: 'U' '&' InvalidUnterminatedQuotedIdentifier
;
//
// CONSTANTS (4.1.2)
//
// String Constants (4.1.2.1)
StringConstant
: UnterminatedStringConstant '\''
;
UnterminatedStringConstant
: '\'' ('\'\'' | ~ '\'')*
;
// String Constants with C-style Escapes (4.1.2.2)
BeginEscapeStringConstant
: 'E' '\'' -> more , pushMode (EscapeStringConstantMode)
;
// String Constants with Unicode Escapes (4.1.2.3)
//
// Note that escape sequences are never checked as part of this token due to the ability of users to change the escape
// character with a UESCAPE clause following the Unicode string constant.
//
// TODO: these rules assume '' is still a valid escape sequence within a Unicode string constant.
UnicodeEscapeStringConstant
: UnterminatedUnicodeEscapeStringConstant '\''
;
UnterminatedUnicodeEscapeStringConstant
: 'U' '&' UnterminatedStringConstant
;
// Dollar-quoted String Constants (4.1.2.4)
BeginDollarStringConstant
: '$' Tag? '$'
{pushTag();} -> pushMode (DollarQuotedStringMode)
;
/* "The tag, if any, of a dollar-quoted string follows the same rules as an
* unquoted identifier, except that it cannot contain a dollar sign."
*/
fragment Tag
: IdentifierStartChar StrictIdentifierChar*
;
// Bit-strings Constants (4.1.2.5)
BinaryStringConstant
: UnterminatedBinaryStringConstant '\''
;
UnterminatedBinaryStringConstant
: 'B' '\'' [01]*
;
InvalidBinaryStringConstant
: InvalidUnterminatedBinaryStringConstant '\''
;
InvalidUnterminatedBinaryStringConstant
: 'B' UnterminatedStringConstant
;
HexadecimalStringConstant
: UnterminatedHexadecimalStringConstant '\''
;
UnterminatedHexadecimalStringConstant
: 'X' '\'' [0-9A-F]*
;
InvalidHexadecimalStringConstant
: InvalidUnterminatedHexadecimalStringConstant '\''
;
InvalidUnterminatedHexadecimalStringConstant
: 'X' UnterminatedStringConstant
;
// Numeric Constants (4.1.2.6)
Integral
: Digits
;
NumericFail
: Digits '..'
{HandleNumericFail();}
;
Numeric
: Digits '.' Digits? /*? replaced with + to solve problem with DOT_DOT .. but this surely must be rewriten */
('E' [+-]? Digits)?
| '.' Digits ('E' [+-]? Digits)?
| Digits 'E' [+-]? Digits
;
fragment Digits
: [0-9]+
;
PLSQLVARIABLENAME
: ':' [A-Z_] [A-Z_0-9$]*
;
PLSQLIDENTIFIER
: ':"' ('\\' . | '""' | ~ ('"' | '\\'))* '"'
;
//
// WHITESPACE (4.1)
//
Whitespace
: [ \t]+ -> channel (HIDDEN)
;
Newline
: ('\r' '\n'? | '\n') -> channel (HIDDEN)
;
//
// COMMENTS (4.1.5)
//
LineComment
: '--' ~ [\r\n]* -> channel (HIDDEN)
;
BlockComment
: ('/*' ('/'* BlockComment | ~ [/*] | '/'+ ~ [/*] | '*'+ ~ [/*])* '*'* '*/') -> channel (HIDDEN)
;
UnterminatedBlockComment
: '/*' ('/'* BlockComment | // these characters are not part of special sequences in a block comment
~ [/*] | // handle / or * characters which are not part of /* or */ and do not appear at the end of the file
('/'+ ~ [/*] | '*'+ ~ [/*]))*
// Handle the case of / or * characters at the end of the file, or a nested unterminated block comment
('/'+ | '*'+ | '/'* UnterminatedBlockComment)?
// Optional assertion to make sure this rule is working as intended
{
UnterminatedBlockCommentDebugAssert();
}
;
//
// META-COMMANDS
//
// http://www.postgresql.org/docs/9.3/static/app-psql.html
MetaCommand
: '\\' (~ [\r\n\\"] | '"' ~ [\r\n"]* '"')* ('"' ~ [\r\n"]*)?
;
EndMetaCommand
: '\\\\'
;
//
// ERROR
//
// Any character which does not match one of the above rules will appear in the token stream as an ErrorCharacter token.
// This ensures the lexer itself will never encounter a syntax error, so all error handling may be performed by the
// parser.
ErrorCharacter
: .
;
mode EscapeStringConstantMode;
EscapeStringConstant
: EscapeStringText '\'' -> mode (AfterEscapeStringConstantMode)
;
UnterminatedEscapeStringConstant
: EscapeStringText
// Handle a final unmatched \ character appearing at the end of the file
'\\'? EOF
;
fragment EscapeStringText
: ('\'\'' | '\\' ( // two-digit hex escapes are still valid when treated as single-digit escapes
'x' [0-9a-fA-F] |
'u' [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] [0-9a-fA-F] |
'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,
// but that doesn't affect the syntax.
~ [xuU]) | ~ ['\\])*
;
InvalidEscapeStringConstant
: InvalidEscapeStringText '\'' -> mode (AfterEscapeStringConstantMode)
;
InvalidUnterminatedEscapeStringConstant
: InvalidEscapeStringText
// Handle a final unmatched \ character appearing at the end of the file
'\\'? EOF
;
fragment InvalidEscapeStringText
: ('\'\'' | '\\' . | ~ ['\\])*
;
mode AfterEscapeStringConstantMode;
AfterEscapeStringConstantMode_Whitespace
: Whitespace -> type (Whitespace) , channel (HIDDEN)
;
AfterEscapeStringConstantMode_Newline
: Newline -> type (Newline) , channel (HIDDEN) , mode (AfterEscapeStringConstantWithNewlineMode)
;
AfterEscapeStringConstantMode_NotContinued
:
{} // intentionally empty
-> skip , popMode
;
mode AfterEscapeStringConstantWithNewlineMode;
AfterEscapeStringConstantWithNewlineMode_Whitespace
: Whitespace -> type (Whitespace) , channel (HIDDEN)
;
AfterEscapeStringConstantWithNewlineMode_Newline
: Newline -> type (Newline) , channel (HIDDEN)
;
AfterEscapeStringConstantWithNewlineMode_Continued
: '\'' -> more , mode (EscapeStringConstantMode)
;
AfterEscapeStringConstantWithNewlineMode_NotContinued
:
{} // intentionally empty
-> skip , popMode
;
mode DollarQuotedStringMode;
DollarText
: ~ '$'+
//| '$'([0-9])+
| // this alternative improves the efficiency of handling $ characters within a dollar-quoted string which are
// not part of the ending tag.
'$' ~ '$'*
;
EndDollarStringConstant
: ('$' Tag? '$')
{isTag()}?
{popTag();} -> popMode
;
================================================
FILE: superior-postgres-parser/src/main/antlr4/io/github/melin/superior/parser/postgre/antlr4/PostgreSqlParser.g4
================================================
parser grammar PostgreSqlParser;
options { tokenVocab = PostgreSqlLexer;
superClass = PostgreSqlParserBase;
}
@header
{
}
@members
{
}
root
: stmtblock EOF
;
plsqlroot
: pl_function
;
stmtblock
: stmtmulti
;
stmtmulti
: (stmt SEMI?)*
;
stmt
: altereventtrigstmt
| altercollationstmt
| alterdatabasestmt
| alterdatabasesetstmt
| alterdefaultprivilegesstmt
| alterdomainstmt
| alterenumstmt
| alterextensionstmt
| alterextensioncontentsstmt
| alterfdwstmt
| alterforeignserverstmt
| alterfunctionstmt
| altergroupstmt
| alterobjectdependsstmt
| alterobjectschemastmt
| alterownerstmt
| alteroperatorstmt
| altertypestmt
| alterpolicystmt
| alterseqstmt
| altersystemstmt
| altertablestmt
| altertblspcstmt
| altercompositetypestmt
| alterpublicationstmt
| alterrolesetstmt
| alterrolestmt
| altersubscriptionstmt
| alterstatsstmt
| altertsconfigurationstmt
| altertsdictionarystmt
| alterusermappingstmt
| analyzestmt
| callstmt
| checkpointstmt
| closeportalstmt
| clusterstmt
| commentstmt
| constraintssetstmt
| copystmt
| createamstmt
| createasstmt
| createassertionstmt
| createcaststmt
| createconversionstmt
| createdomainstmt
| createextensionstmt
| createfdwstmt
| createforeignserverstmt
| createforeigntablestmt
| createfunctionstmt
| creategroupstmt
| creatematviewstmt
| createopclassstmt
| createopfamilystmt
| createpublicationstmt
| alteropfamilystmt
| createpolicystmt
| createplangstmt
| createschemastmt
| createseqstmt
| createstmt
| createsubscriptionstmt
| createstatsstmt
| createtablespacestmt
| createtransformstmt
| createtrigstmt
| createeventtrigstmt
| createrolestmt
| createuserstmt
| createusermappingstmt
| createdbstmt
| deallocatestmt
| declarecursorstmt
| definestmt
| deletestmt
| discardstmt
| dostmt
| dropcaststmt
| dropopclassstmt
| dropopfamilystmt
| dropownedstmt
| dropstmt
| dropsubscriptionstmt
| droptablespacestmt
| droptransformstmt
| droprolestmt
| dropusermappingstmt
| dropdbstmt
| executestmt
| explainstmt
| fetchstmt
| grantstmt
| grantrolestmt
| importforeignschemastmt
| indexstmt
| insertstmt
| mergestmt
| listenstmt
| refreshmatviewstmt
| loadstmt
| lockstmt
| notifystmt
| preparestmt
| reassignownedstmt
| reindexstmt
| removeaggrstmt
| removefuncstmt
| removeoperstmt
| renamestmt
| revokerolestmt
| rulestmt
| seclabelstmt
| selectstmt
| transactionstmt
| truncatestmt
| unlistenstmt
| updatestmt
| vacuumstmt
| variableresetstmt
| variablesetstmt
| variableshowstmt
| viewstmt
| plsqlconsolecommand
;
plsqlconsolecommand
: MetaCommand EndMetaCommand?
;
callstmt
: CALL func_application
;
createrolestmt
: CREATE ROLE roleid opt_with optrolelist
;
opt_with
: WITH
//| WITH_LA
|
;
optrolelist
: createoptroleelem*
;
alteroptrolelist
: alteroptroleelem*
;
alteroptroleelem
: PASSWORD (sconst | NULL_P)
| (ENCRYPTED | UNENCRYPTED) PASSWORD sconst
| INHERIT
| CONNECTION LIMIT signediconst
| VALID UNTIL sconst
| USER role_list
| identifier
;
createoptroleelem
: alteroptroleelem
| SYSID iconst
| ADMIN role_list
| ROLE role_list
| IN_P (ROLE | GROUP_P) role_list
;
createuserstmt
: CREATE USER roleid opt_with optrolelist
;
alterrolestmt
: ALTER (ROLE | USER) rolespec opt_with alteroptrolelist
;
opt_in_database
:
| IN_P DATABASE name
;
alterrolesetstmt
: ALTER (ROLE | USER) ALL? rolespec opt_in_database setresetclause
;
droprolestmt
: DROP (ROLE | USER | GROUP_P) (IF_P EXISTS)? role_list
;
creategroupstmt
: CREATE GROUP_P roleid opt_with optrolelist
;
altergroupstmt
: ALTER GROUP_P rolespec add_drop USER role_list
;
add_drop
: ADD_P
| DROP
;
createschemastmt
: CREATE SCHEMA (IF_P NOT EXISTS)? (optschemaname AUTHORIZATION rolespec | colid) optschemaeltlist
;
optschemaname
: colid
|
;
optschemaeltlist
: schema_stmt*
;
schema_stmt
: createstmt
| indexstmt
| createseqstmt
| createtrigstmt
| grantstmt
| viewstmt
;
variablesetstmt
: SET (LOCAL | SESSION)? set_rest
;
set_rest
: TRANSACTION transaction_mode_list
| SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list
| set_rest_more
;
generic_set
: var_name (TO | EQUAL) var_list
;
set_rest_more
: generic_set
| var_name FROM CURRENT_P
| TIME ZONE zone_value
| CATALOG sconst
| SCHEMA sconst
| NAMES opt_encoding
| ROLE nonreservedword_or_sconst
| SESSION AUTHORIZATION nonreservedword_or_sconst
| XML_P OPTION document_or_content
| TRANSACTION SNAPSHOT sconst
;
var_name
: colid (DOT colid)*
;
var_list
: var_value (COMMA var_value)*
;
var_value
: opt_boolean_or_string
| numericonly
;
iso_level
: READ (UNCOMMITTED | COMMITTED)
| REPEATABLE READ
| SERIALIZABLE
;
opt_boolean_or_string
: TRUE_P
| FALSE_P
| ON
| nonreservedword_or_sconst
;
zone_value
: sconst
| identifier
| constinterval sconst opt_interval
| constinterval OPEN_PAREN iconst CLOSE_PAREN sconst
| numericonly
| DEFAULT
| LOCAL
;
opt_encoding
: sconst
| DEFAULT
|
;
nonreservedword_or_sconst
: nonreservedword
| sconst
;
variableresetstmt
: RESET reset_rest
;
reset_rest
: generic_reset
| TIME ZONE
| TRANSACTION ISOLATION LEVEL
| SESSION AUTHORIZATION
;
generic_reset
: var_name
| ALL
;
setresetclause
: SET set_rest
| variableresetstmt
;
functionsetresetclause
: SET set_rest_more
| variableresetstmt
;
variableshowstmt
: SHOW (var_name | TIME ZONE | TRANSACTION ISOLATION LEVEL | SESSION AUTHORIZATION | ALL)
;
constraintssetstmt
: SET CONSTRAINTS constraints_set_list constraints_set_mode
;
constraints_set_list
: ALL
| qualified_name_list
;
constraints_set_mode
: DEFERRED
| IMMEDIATE
;
checkpointstmt
: CHECKPOINT
;
discardstmt
: DISCARD (ALL | TEMP | TEMPORARY | PLANS | SEQUENCES)
;
altertablestmt
: ALTER TABLE (IF_P EXISTS)? relation_expr (alter_table_cmds | partition_cmd)
| ALTER TABLE ALL IN_P TABLESPACE name (OWNED BY role_list)? SET TABLESPACE name opt_nowait
| ALTER INDEX (IF_P EXISTS)? qualified_name (alter_table_cmds | index_partition_cmd)
| ALTER INDEX ALL IN_P TABLESPACE name (OWNED BY role_list)? SET TABLESPACE name opt_nowait
| ALTER SEQUENCE (IF_P EXISTS)? qualified_name alter_table_cmds
| ALTER VIEW (IF_P EXISTS)? qualified_name alter_table_cmds
| ALTER MATERIALIZED VIEW (IF_P EXISTS)? qualified_name alter_table_cmds
| ALTER MATERIALIZED VIEW ALL IN_P TABLESPACE name (OWNED BY role_list)? SET TABLESPACE name opt_nowait
| ALTER FOREIGN TABLE (IF_P EXISTS)? relation_expr alter_table_cmds
;
alter_table_cmds
: alter_table_cmd (COMMA alter_table_cmd)*
;
partition_cmd
: ATTACH PARTITION qualified_name partitionboundspec
| DETACH PARTITION qualified_name
;
index_partition_cmd
: ATTACH PARTITION qualified_name
;
alter_table_cmd
: ADD_P columnDef
| ADD_P IF_P NOT EXISTS columnDef
| ADD_P COLUMN columnDef
| ADD_P COLUMN IF_P NOT EXISTS columnDef
| ALTER opt_column colid alter_column_default
| ALTER opt_column colid DROP NOT NULL_P
| ALTER opt_column colid SET NOT NULL_P
| ALTER opt_column colid DROP EXPRESSION
| ALTER opt_column colid DROP EXPRESSION IF_P EXISTS
| ALTER opt_column colid SET STATISTICS signediconst
| ALTER opt_column iconst SET STATISTICS signediconst
| ALTER opt_column colid SET reloptions
| ALTER opt_column colid RESET reloptions
| ALTER opt_column colid SET STORAGE colid
| ALTER opt_column colid ADD_P GENERATED generated_when AS IDENTITY_P optparenthesizedseqoptlist
| ALTER opt_column colid alter_identity_column_option_list
| ALTER opt_column colid DROP IDENTITY_P
| ALTER opt_column colid DROP IDENTITY_P IF_P EXISTS
| DROP opt_column IF_P EXISTS colid opt_drop_behavior
| DROP opt_column colid opt_drop_behavior
| ALTER opt_column colid opt_set_data TYPE_P typename opt_collate_clause alter_using
| ALTER opt_column colid alter_generic_options
| ADD_P tableconstraint
| ALTER CONSTRAINT name constraintattributespec
| VALIDATE CONSTRAINT name
| DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior
| DROP CONSTRAINT name opt_drop_behavior
| SET WITHOUT OIDS
| CLUSTER ON name
| SET WITHOUT CLUSTER
| SET LOGGED
| SET UNLOGGED
| ENABLE_P TRIGGER name
| ENABLE_P ALWAYS TRIGGER name
| ENABLE_P REPLICA TRIGGER name
| ENABLE_P TRIGGER ALL
| ENABLE_P TRIGGER USER
| DISABLE_P TRIGGER name
| DISABLE_P TRIGGER ALL
| DISABLE_P TRIGGER USER
| ENABLE_P RULE name
| ENABLE_P ALWAYS RULE name
| ENABLE_P REPLICA RULE name
| DISABLE_P RULE name
| INHERIT qualified_name
| NO INHERIT qualified_name
| OF any_name
| NOT OF
| OWNER TO rolespec
| SET TABLESPACE name
| SET reloptions
| RESET reloptions
| REPLICA IDENTITY_P replica_identity
| ENABLE_P ROW LEVEL SECURITY
| DISABLE_P ROW LEVEL SECURITY
| FORCE ROW LEVEL SECURITY
| NO FORCE ROW LEVEL SECURITY
| alter_generic_options
;
alter_column_default
: SET DEFAULT a_expr
| DROP DEFAULT
;
opt_drop_behavior
: CASCADE
| RESTRICT
|
;
opt_collate_clause
: COLLATE any_name
|
;
alter_using
: USING a_expr
|
;
replica_identity
: NOTHING
| FULL
| DEFAULT
| USING INDEX name
;
reloptions
: OPEN_PAREN reloption_list CLOSE_PAREN
;
opt_reloptions
: WITH reloptions
|
;
reloption_list
: reloption_elem (COMMA reloption_elem)*
;
reloption_elem
: collabel (EQUAL def_arg | DOT collabel (EQUAL def_arg)?)?
;
alter_identity_column_option_list
: alter_identity_column_option+
;
alter_identity_column_option
: RESTART (opt_with numericonly)?
| SET (seqoptelem | GENERATED generated_when)
;
partitionboundspec
: FOR VALUES WITH OPEN_PAREN hash_partbound CLOSE_PAREN
| FOR VALUES IN_P OPEN_PAREN expr_list CLOSE_PAREN
| FOR VALUES FROM OPEN_PAREN expr_list CLOSE_PAREN TO OPEN_PAREN expr_list CLOSE_PAREN
| DEFAULT
;
hash_partbound_elem
: nonreservedword iconst
;
hash_partbound
: hash_partbound_elem (COMMA hash_partbound_elem)*
;
altercompositetypestmt
: ALTER TYPE_P any_name alter_type_cmds
;
alter_type_cmds
: alter_type_cmd (COMMA alter_type_cmd)*
;
alter_type_cmd
: ADD_P ATTRIBUTE tablefuncelement opt_drop_behavior
| DROP ATTRIBUTE (IF_P EXISTS)? colid opt_drop_behavior
| ALTER ATTRIBUTE colid opt_set_data TYPE_P typename opt_collate_clause opt_drop_behavior
;
closeportalstmt
: CLOSE (cursor_name | ALL)
;
copystmt
: COPY opt_binary qualified_name opt_column_list copy_from opt_program copy_file_name copy_delimiter opt_with copy_options where_clause
| COPY OPEN_PAREN preparablestmt CLOSE_PAREN TO opt_program copy_file_name opt_with copy_options
;
copy_from
: FROM
| TO
;
opt_program
: PROGRAM
|
;
copy_file_name
: sconst
| STDIN
| STDOUT
;
copy_options
: copy_opt_list
| OPEN_PAREN copy_generic_opt_list CLOSE_PAREN
;
copy_opt_list
: copy_opt_item*
;
copy_opt_item
: BINARY
| FREEZE
| DELIMITER opt_as sconst
| NULL_P opt_as sconst
| CSV
| HEADER_P
| QUOTE opt_as sconst
| ESCAPE opt_as sconst
| FORCE QUOTE columnlist
| FORCE QUOTE STAR
| FORCE NOT NULL_P columnlist
| FORCE NULL_P columnlist
| ENCODING sconst
;
opt_binary
: BINARY
|
;
copy_delimiter
: opt_using DELIMITERS sconst
|
;
opt_using
: USING
|
;
copy_generic_opt_list
: copy_generic_opt_elem (COMMA copy_generic_opt_elem)*
;
copy_generic_opt_elem
: collabel copy_generic_opt_arg
;
copy_generic_opt_arg
: opt_boolean_or_string
| numericonly
| STAR
| OPEN_PAREN copy_generic_opt_arg_list CLOSE_PAREN
|
;
copy_generic_opt_arg_list
: copy_generic_opt_arg_list_item (COMMA copy_generic_opt_arg_list_item)*
;
copy_generic_opt_arg_list_item
: opt_boolean_or_string
;
createstmt
: CREATE opttemp TABLE (IF_P NOT EXISTS)? qualified_name
(
OPEN_PAREN opttableelementlist CLOSE_PAREN optinherit optpartitionspec table_access_method_clause gaussprimayindex optwith oncommitoption opttablespace gaussextension
| OF any_name opttypedtableelementlist optpartitionspec table_access_method_clause optwith oncommitoption opttablespace
| PARTITION OF qualified_name opttypedtableelementlist partitionboundspec optpartitionspec table_access_method_clause optwith oncommitoption opttablespace
)
;
// -------- support gauss
gaussprimayindex
: PRIMARY INDEX OPEN_PAREN colid CLOSE_PAREN
|
;
gaussextension
: distributeby toGroupOrNode tablePartition?
|
;
distributeby
: DISTRIBUTE BY (REPLICATION | ROUNDROBIN | HASH OPEN_PAREN distributebyhashlist CLOSE_PAREN)
| DISTRIBUTED BY OPEN_PAREN distributebyhashlist CLOSE_PAREN
| DISTRIBUTED (RANDOMLY | REPLICATED)
|
;
distributebyhashlist
: distributebyhashitem (COMMA distributebyhashitem)*
;
distributebyhashitem
: collabel
;
toGroupOrNode
: TO GROUP_P collabel
| TO NODE_P OPEN_PAREN collabel (COMMA collabel)* CLOSE_PAREN
|
;
tablePartition
: PARTITION BY partition_list ((ENABLE_P | DISABLE_P) ROW MOVEMENT)?
;
partition_list
: value_partition_stmt
| range_partition_stmt
| list_partition_stmt
| normal_partition_stmt
;
normal_partition_stmt
: OPEN_PAREN list_partition_value CLOSE_PAREN AUTOMAPPED?
;
list_partition_stmt
: LIST_P OPEN_PAREN partition_key CLOSE_PAREN OPEN_PAREN list_partition_items CLOSE_PAREN
;
list_partition_items
: list_partition_item (COMMA list_partition_item)*
;
list_partition_item
: PARTITION partition_name VALUES LESS THAN OPEN_PAREN list_partition_value CLOSE_PAREN table_space_item?
;
list_partition_value
: partition_name (COMMA partition_name)*
| DEFAULT
;
value_partition_stmt
: VALUES OPEN_PAREN partition_key CLOSE_PAREN
;
range_partition_stmt
: RANGE OPEN_PAREN partition_key CLOSE_PAREN OPEN_PAREN (partition_less_than_items | partition_start_end_items) CLOSE_PAREN
;
partition_less_than_items
: partition_less_than_item (COMMA partition_less_than_item)*
;
partition_start_end_items
: partition_start_end_item (COMMA partition_start_end_item)*
;
partition_less_than_item
: PARTITION partition_name VALUES LESS THAN OPEN_PAREN (partition_value | MAXVALUE) CLOSE_PAREN table_space_item?
;
partition_start_end_item
: PARTITION partition_name start_end_item table_space_item?
;
start_end_item
: start_item
| end_item
| start_item end_item (EVERY OPEN_PAREN aexprconst CLOSE_PAREN)?
;
start_item
: START OPEN_PAREN partition_value CLOSE_PAREN
;
end_item
: END_P OPEN_PAREN (partition_value | MAXVALUE) CLOSE_PAREN
;
partition_key
: colid
;
partition_name
: colid
;
partition_value
: a_expr
;
table_space_item
: TABLESPACE table_space_name
;
table_space_name
: qualified_name
;
// -------- support gauss
opttemp
: TEMPORARY
| TEMP
| LOCAL (TEMPORARY | TEMP)
| GLOBAL (TEMPORARY | TEMP)
| UNLOGGED
|
;
opttableelementlist
: tableelementlist
|
;
opttypedtableelementlist
: OPEN_PAREN typedtableelementlist CLOSE_PAREN
|
;
tableelementlist
: tableelement (COMMA tableelement)*
;
typedtableelementlist
: typedtableelement (COMMA typedtableelement)*
;
tableelement
: tableconstraint
| tablelikeclause
| columnDef
;
typedtableelement
: columnOptions
| tableconstraint
;
columnDef
: colid typename create_generic_options colquallist
;
columnOptions
: colid (WITH OPTIONS)? colquallist
;
colquallist
: colconstraint*
;
colconstraint
: CONSTRAINT name colconstraintelem
| colconstraintelem
| constraintattr
| COLLATE any_name
;
colconstraintelem
: NOT NULL_P
| NULL_P
| UNIQUE opt_definition optconstablespace
| PRIMARY KEY opt_definition optconstablespace
| CHECK OPEN_PAREN a_expr CLOSE_PAREN opt_no_inherit
| DEFAULT b_expr
| GENERATED generated_when AS (IDENTITY_P optparenthesizedseqoptlist | OPEN_PAREN a_expr CLOSE_PAREN STORED)
| REFERENCES qualified_name opt_column_list key_match key_actions
;
generated_when
: ALWAYS
| BY DEFAULT
;
constraintattr
: DEFERRABLE
| NOT DEFERRABLE
| INITIALLY (DEFERRED | IMMEDIATE)
;
tablelikeclause
: LIKE qualified_name tablelikeoptionlist
;
tablelikeoptionlist
: ((INCLUDING | EXCLUDING) tablelikeoption)*
;
tablelikeoption
: COMMENTS
| CONSTRAINTS
| DEFAULTS
| IDENTITY_P
| GENERATED
| INDEXES
| STATISTICS
| STORAGE
| ALL
;
tableconstraint
: CONSTRAINT name constraintelem
| constraintelem
;
constraintelem
: CHECK OPEN_PAREN a_expr CLOSE_PAREN constraintattributespec
| UNIQUE (OPEN_PAREN columnlist CLOSE_PAREN opt_c_include opt_definition optconstablespace constraintattributespec | existingindex constraintattributespec)
| PRIMARY KEY (OPEN_PAREN columnlist CLOSE_PAREN opt_c_include opt_definition optconstablespace constraintattributespec | existingindex constraintattributespec)
| EXCLUDE access_method_clause OPEN_PAREN exclusionconstraintlist CLOSE_PAREN opt_c_include opt_definition optconstablespace exclusionwhereclause constraintattributespec
| FOREIGN KEY OPEN_PAREN columnlist CLOSE_PAREN REFERENCES qualified_name opt_column_list key_match key_actions constraintattributespec
;
opt_no_inherit
: NO INHERIT
|
;
opt_column_list
: OPEN_PAREN columnlist CLOSE_PAREN
|
;
columnlist
: columnElem (COMMA columnElem)*
;
columnElem
: colid
;
opt_c_include
: INCLUDE OPEN_PAREN columnlist CLOSE_PAREN
|
;
key_match
: MATCH (FULL | PARTIAL | SIMPLE)
|
;
exclusionconstraintlist
: exclusionconstraintelem (COMMA exclusionconstraintelem)*
;
exclusionconstraintelem
: index_elem WITH (any_operator | OPERATOR OPEN_PAREN any_operator CLOSE_PAREN)
;
exclusionwhereclause
: WHERE OPEN_PAREN a_expr CLOSE_PAREN
|
;
key_actions
: key_update
| key_delete
| key_update key_delete
| key_delete key_update
|
;
key_update
: ON UPDATE key_action
;
key_delete
: ON DELETE_P key_action
;
key_action
: NO ACTION
| RESTRICT
| CASCADE
| SET (NULL_P | DEFAULT)
;
optinherit
: INHERITS OPEN_PAREN qualified_name_list CLOSE_PAREN
|
;
optpartitionspec
: partitionspec
|
;
partitionspec
: PARTITION BY colid OPEN_PAREN part_params CLOSE_PAREN
;
part_params
: part_elem (COMMA part_elem)*
;
part_elem
: colid opt_collate opt_class
| func_expr_windowless opt_collate opt_class
| OPEN_PAREN a_expr CLOSE_PAREN opt_collate opt_class
;
table_access_method_clause
: USING name
|
;
optwith
: WITH reloptions
| WITHOUT OIDS
|
;
oncommitoption
: ON COMMIT (DROP | DELETE_P ROWS | PRESERVE ROWS)
|
;
opttablespace
: TABLESPACE name
|
;
optconstablespace
: USING INDEX TABLESPACE name
|
;
existingindex
: USING INDEX name
;
createstatsstmt
: CREATE STATISTICS (IF_P NOT EXISTS)? any_name opt_name_list ON expr_list FROM from_list
;
alterstatsstmt
: ALTER STATISTICS (IF_P EXISTS)? any_name SET STATISTICS signediconst
;
createasstmt
: CREATE opttemp TABLE (IF_P NOT EXISTS)? create_as_target AS selectstmt opt_with_data
;
create_as_target
: qualified_name opt_column_list table_access_method_clause optwith oncommitoption opttablespace gaussextension
;
opt_with_data
: WITH (DATA_P | NO DATA_P)
|
;
creatematviewstmt
: CREATE optnolog MATERIALIZED VIEW (IF_P NOT EXISTS)? create_mv_target AS selectstmt opt_with_data
;
create_mv_target
: qualified_name opt_column_list table_access_method_clause opt_reloptions opttablespace
;
optnolog
: UNLOGGED
|
;
refreshmatviewstmt
: REFRESH MATERIALIZED VIEW opt_concurrently qualified_name opt_with_data
;
createseqstmt
: CREATE opttemp SEQUENCE (IF_P NOT EXISTS)? qualified_name optseqoptlist
;
alterseqstmt
: ALTER SEQUENCE (IF_P EXISTS)? qualified_name seqoptlist
;
optseqoptlist
: seqoptlist
|
;
optparenthesizedseqoptlist
: OPEN_PAREN seqoptlist CLOSE_PAREN
|
;
seqoptlist
: seqoptelem+
;
seqoptelem
: AS simpletypename
| CACHE numericonly
| CYCLE
| INCREMENT opt_by numericonly
| MAXVALUE numericonly
| MINVALUE numericonly
| NO (MAXVALUE | MINVALUE | CYCLE)
| OWNED BY any_name
| SEQUENCE NAME_P any_name
| START opt_with numericonly
| RESTART opt_with numericonly?
;
opt_by
: BY
|
;
numericonly
: fconst
| PLUS fconst
| MINUS fconst
| signediconst
;
numericonly_list
: numericonly (COMMA numericonly)*
;
createplangstmt
: CREATE opt_or_replace opt_trusted opt_procedural LANGUAGE name (HANDLER handler_name opt_inline_handler opt_validator)?
;
opt_trusted
: TRUSTED
|
;
handler_name
: name attrs?
;
opt_inline_handler
: INLINE_P handler_name
|
;
validator_clause
: VALIDATOR handler_name
| NO VALIDATOR
;
opt_validator
: validator_clause
|
;
opt_procedural
: PROCEDURAL
|
;
createtablespacestmt
: CREATE TABLESPACE name opttablespaceowner LOCATION sconst opt_reloptions
;
opttablespaceowner
: OWNER rolespec
|
;
droptablespacestmt
: DROP TABLESPACE (IF_P EXISTS)? name
;
createextensionstmt
: CREATE EXTENSION (IF_P NOT EXISTS)? name opt_with create_extension_opt_list
;
create_extension_opt_list
: create_extension_opt_item*
;
create_extension_opt_item
: SCHEMA name
| VERSION_P nonreservedword_or_sconst
| FROM nonreservedword_or_sconst
| CASCADE
;
alterextensionstmt
: ALTER EXTENSION name UPDATE alter_extension_opt_list
;
alter_extension_opt_list
: alter_extension_opt_item*
;
alter_extension_opt_item
: TO nonreservedword_or_sconst
;
alterextensioncontentsstmt
: ALTER EXTENSION name add_drop object_type_name name
| ALTER EXTENSION name add_drop object_type_any_name any_name
| ALTER EXTENSION name add_drop AGGREGATE aggregate_with_argtypes
| ALTER EXTENSION name add_drop CAST OPEN_PAREN typename AS typename CLOSE_PAREN
| ALTER EXTENSION name add_drop DOMAIN_P typename
| ALTER EXTENSION name add_drop FUNCTION function_with_argtypes
| ALTER EXTENSION name add_drop OPERATOR operator_with_argtypes
| ALTER EXTENSION name add_drop OPERATOR CLASS any_name USING name
| ALTER EXTENSION name add_drop OPERATOR FAMILY any_name USING name
| ALTER EXTENSION name add_drop PROCEDURE function_with_argtypes
| ALTER EXTENSION name add_drop ROUTINE function_with_argtypes
| ALTER EXTENSION name add_drop TRANSFORM FOR typename LANGUAGE name
| ALTER EXTENSION name add_drop TYPE_P typename
;
createfdwstmt
: CREATE FOREIGN DATA_P WRAPPER name opt_fdw_options create_generic_options
;
fdw_option
: HANDLER handler_name
| NO HANDLER
| VALIDATOR handler_name
| NO VALIDATOR
;
fdw_options
: fdw_option+
;
opt_fdw_options
: fdw_options
|
;
alterfdwstmt
: ALTER FOREIGN DATA_P WRAPPER name opt_fdw_options alter_generic_options
| ALTER FOREIGN DATA_P WRAPPER name fdw_options
;
create_generic_options
: OPTIONS OPEN_PAREN generic_option_list CLOSE_PAREN
|
;
generic_option_list
: generic_option_elem (COMMA generic_option_elem)*
;
alter_generic_options
: OPTIONS OPEN_PAREN alter_generic_option_list CLOSE_PAREN
;
alter_generic_option_list
: alter_generic_option_elem (COMMA alter_generic_option_elem)*
;
alter_generic_option_elem
: generic_option_elem
| SET generic_option_elem
| ADD_P generic_option_elem
| DROP generic_option_name
;
generic_option_elem
: generic_option_name generic_option_arg
;
generic_option_name
: collabel
;
generic_option_arg
: sconst
;
createforeignserverstmt
: CREATE SERVER name opt_type opt_foreign_server_version FOREIGN DATA_P WRAPPER name create_generic_options
| CREATE SERVER IF_P NOT EXISTS name opt_type opt_foreign_server_version FOREIGN DATA_P WRAPPER name create_generic_options
;
opt_type
: TYPE_P sconst
|
;
foreign_server_version
: VERSION_P (sconst | NULL_P)
;
opt_foreign_server_version
: foreign_server_version
|
;
alterforeignserverstmt
: ALTER SERVER name (alter_generic_options | foreign_server_version alter_generic_options?)
;
createforeigntablestmt
: CREATE FOREIGN TABLE qualified_name OPEN_PAREN opttableelementlist CLOSE_PAREN optinherit SERVER name create_generic_options
| CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name OPEN_PAREN opttableelementlist CLOSE_PAREN optinherit SERVER name create_generic_options
| CREATE FOREIGN TABLE qualified_name PARTITION OF qualified_name opttypedtableelementlist partitionboundspec SERVER name create_generic_options
| CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name PARTITION OF qualified_name opttypedtableelementlist partitionboundspec SERVER name create_generic_options
;
importforeignschemastmt
: IMPORT_P FOREIGN SCHEMA name import_qualification FROM SERVER name INTO name create_generic_options
;
import_qualification_type
: LIMIT TO
| EXCEPT
;
import_qualification
: import_qualification_type OPEN_PAREN relation_expr_list CLOSE_PAREN
|
;
createusermappingstmt
: CREATE USER MAPPING FOR auth_ident SERVER name create_generic_options
| CREATE USER MAPPING IF_P NOT EXISTS FOR auth_ident SERVER name create_generic_options
;
auth_ident
: rolespec
| USER
;
dropusermappingstmt
: DROP USER MAPPING FOR auth_ident SERVER name
| DROP USER MAPPING IF_P EXISTS FOR auth_ident SERVER name
;
alterusermappingstmt
: ALTER USER MAPPING FOR auth_ident SERVER name alter_generic_options
;
createpolicystmt
: CREATE POLICY name ON qualified_name rowsecuritydefaultpermissive rowsecuritydefaultforcmd rowsecuritydefaulttorole rowsecurityoptionalexpr rowsecurityoptionalwithcheck
;
alterpolicystmt
: ALTER POLICY name ON qualified_name rowsecurityoptionaltorole rowsecurityoptionalexpr rowsecurityoptionalwithcheck
;
rowsecurityoptionalexpr
: USING OPEN_PAREN a_expr CLOSE_PAREN
|
;
rowsecurityoptionalwithcheck
: WITH CHECK OPEN_PAREN a_expr CLOSE_PAREN
|
;
rowsecuritydefaulttorole
: TO role_list
|
;
rowsecurityoptionaltorole
: TO role_list
|
;
rowsecuritydefaultpermissive
: AS identifier
|
;
rowsecuritydefaultforcmd
: FOR row_security_cmd
|
;
row_security_cmd
: ALL
| SELECT
| INSERT
| UPDATE
| DELETE_P
;
createamstmt
: CREATE ACCESS METHOD name TYPE_P am_type HANDLER handler_name
;
am_type
: INDEX
| TABLE
;
createtrigstmt
: CREATE TRIGGER name triggeractiontime triggerevents ON qualified_name triggerreferencing triggerforspec triggerwhen EXECUTE function_or_procedure func_name OPEN_PAREN triggerfuncargs CLOSE_PAREN
| 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
;
triggeractiontime
: BEFORE
| AFTER
| INSTEAD OF
;
triggerevents
: triggeroneevent (OR triggeroneevent)*
;
triggeroneevent
: INSERT
| DELETE_P
| UPDATE
| UPDATE OF columnlist
| TRUNCATE
;
triggerreferencing
: REFERENCING triggertransitions
|
;
triggertransitions
: triggertransition+
;
triggertransition
: transitionoldornew transitionrowortable opt_as transitionrelname
;
transitionoldornew
: NEW
| OLD
;
transitionrowortable
: TABLE
| ROW
;
transitionrelname
: colid
;
triggerforspec
: FOR triggerforopteach triggerfortype
|
;
triggerforopteach
: EACH
|
;
triggerfortype
: ROW
| STATEMENT
;
triggerwhen
: WHEN OPEN_PAREN a_expr CLOSE_PAREN
|
;
function_or_procedure
: FUNCTION
| PROCEDURE
;
triggerfuncargs
: (triggerfuncarg |) (COMMA triggerfuncarg)*
;
triggerfuncarg
: iconst
| fconst
| sconst
| collabel
;
optconstrfromtable
: FROM qualified_name
|
;
constraintattributespec
: constraintattributeElem*
;
constraintattributeElem
: NOT DEFERRABLE
| DEFERRABLE
| INITIALLY IMMEDIATE
| INITIALLY DEFERRED
| NOT VALID
| NO INHERIT
;
createeventtrigstmt
: CREATE EVENT TRIGGER name ON collabel EXECUTE function_or_procedure func_name OPEN_PAREN CLOSE_PAREN
| CREATE EVENT TRIGGER name ON collabel WHEN event_trigger_when_list EXECUTE function_or_procedure func_name OPEN_PAREN CLOSE_PAREN
;
event_trigger_when_list
: event_trigger_when_item (AND event_trigger_when_item)*
;
event_trigger_when_item
: colid IN_P OPEN_PAREN event_trigger_value_list CLOSE_PAREN
;
event_trigger_value_list
: sconst (COMMA sconst)*
;
altereventtrigstmt
: ALTER EVENT TRIGGER name enable_trigger
;
enable_trigger
: ENABLE_P
| ENABLE_P REPLICA
| ENABLE_P ALWAYS
| DISABLE_P
;
createassertionstmt
: CREATE ASSERTION any_name CHECK OPEN_PAREN a_expr CLOSE_PAREN constraintattributespec
;
definestmt
: CREATE opt_or_replace AGGREGATE func_name aggr_args definition
| CREATE opt_or_replace AGGREGATE func_name old_aggr_definition
| CREATE OPERATOR any_operator definition
| CREATE TYPE_P any_name definition
| CREATE TYPE_P any_name
| CREATE TYPE_P any_name AS OPEN_PAREN opttablefuncelementlist CLOSE_PAREN
| CREATE TYPE_P any_name AS ENUM_P OPEN_PAREN opt_enum_val_list CLOSE_PAREN
| CREATE TYPE_P any_name AS RANGE definition
| CREATE TEXT_P SEARCH PARSER any_name definition
| CREATE TEXT_P SEARCH DICTIONARY any_name definition
| CREATE TEXT_P SEARCH TEMPLATE any_name definition
| CREATE TEXT_P SEARCH CONFIGURATION any_name definition
| CREATE COLLATION any_name definition
| CREATE COLLATION IF_P NOT EXISTS any_name definition
| CREATE COLLATION any_name FROM any_name
| CREATE COLLATION IF_P NOT EXISTS any_name FROM any_name
;
definition
: OPEN_PAREN def_list CLOSE_PAREN
;
def_list
: def_elem (COMMA def_elem)*
;
def_elem
: collabel (EQUAL def_arg)?
;
def_arg
: func_type
| reserved_keyword
| qual_all_op
| numericonly
| sconst
| NONE
;
old_aggr_definition
: OPEN_PAREN old_aggr_list CLOSE_PAREN
;
old_aggr_list
: old_aggr_elem (COMMA old_aggr_elem)*
;
old_aggr_elem
: identifier EQUAL def_arg
;
opt_enum_val_list
: enum_val_list
|
;
enum_val_list
: sconst (COMMA sconst)*
;
alterenumstmt
: ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists sconst
| ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists sconst BEFORE sconst
| ALTER TYPE_P any_name ADD_P VALUE_P opt_if_not_exists sconst AFTER sconst
| ALTER TYPE_P any_name RENAME VALUE_P sconst TO sconst
;
opt_if_not_exists
: IF_P NOT EXISTS
|
;
createopclassstmt
: CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P typename USING name opt_opfamily AS opclass_item_list
;
opclass_item_list
: opclass_item (COMMA opclass_item)*
;
opclass_item
: OPERATOR iconst any_operator opclass_purpose opt_recheck
| OPERATOR iconst operator_with_argtypes opclass_purpose opt_recheck
| FUNCTION iconst function_with_argtypes
| FUNCTION iconst OPEN_PAREN type_list CLOSE_PAREN function_with_argtypes
| STORAGE typename
;
opt_default
: DEFAULT
|
;
opt_opfamily
: FAMILY any_name
|
;
opclass_purpose
: FOR SEARCH
| FOR ORDER BY any_name
|
;
opt_recheck
: RECHECK
|
;
createopfamilystmt
: CREATE OPERATOR FAMILY any_name USING name
;
alteropfamilystmt
: ALTER OPERATOR FAMILY any_name USING name ADD_P opclass_item_list
| ALTER OPERATOR FAMILY any_name USING name DROP opclass_drop_list
;
opclass_drop_list
: opclass_drop (COMMA opclass_drop)*
;
opclass_drop
: OPERATOR iconst OPEN_PAREN type_list CLOSE_PAREN
| FUNCTION iconst OPEN_PAREN type_list CLOSE_PAREN
;
dropopclassstmt
: DROP OPERATOR CLASS any_name USING name opt_drop_behavior
| DROP OPERATOR CLASS IF_P EXISTS any_name USING name opt_drop_behavior
;
dropopfamilystmt
: DROP OPERATOR FAMILY any_name USING name opt_drop_behavior
| DROP OPERATOR FAMILY IF_P EXISTS any_name USING name opt_drop_behavior
;
dropownedstmt
: DROP OWNED BY role_list opt_drop_behavior
;
reassignownedstmt
: REASSIGN OWNED BY role_list TO rolespec
;
dropstmt
: DROP object_type_any_name IF_P EXISTS any_name_list opt_drop_behavior
| DROP object_type_any_name any_name_list opt_drop_behavior
| DROP drop_type_name IF_P EXISTS name_list opt_drop_behavior
| DROP drop_type_name name_list opt_drop_behavior
| DROP object_type_name_on_any_name name ON any_name opt_drop_behavior
| DROP object_type_name_on_any_name IF_P EXISTS name ON any_name opt_drop_behavior
| DROP TYPE_P type_name_list opt_drop_behavior
| DROP TYPE_P IF_P EXISTS type_name_list opt_drop_behavior
| DROP DOMAIN_P type_name_list opt_drop_behavior
| DROP DOMAIN_P IF_P EXISTS type_name_list opt_drop_behavior
| DROP INDEX CONCURRENTLY any_name_list opt_drop_behavior
| DROP INDEX CONCURRENTLY IF_P EXISTS any_name_list opt_drop_behavior
;
object_type_any_name
: TABLE
| SEQUENCE
| VIEW
| MATERIALIZED VIEW
| INDEX
| FOREIGN TABLE
| COLLATION
| CONVERSION_P
| STATISTICS
| TEXT_P SEARCH PARSER
| TEXT_P SEARCH DICTIONARY
| TEXT_P SEARCH TEMPLATE
| TEXT_P SEARCH CONFIGURATION
;
object_type_name
: drop_type_name
| DATABASE
| ROLE
| SUBSCRIPTION
| TABLESPACE
;
drop_type_name
: ACCESS METHOD
| EVENT TRIGGER
| EXTENSION
| FOREIGN DATA_P WRAPPER
| opt_procedural LANGUAGE
| PUBLICATION
| SCHEMA
| SERVER
;
object_type_name_on_any_name
: POLICY
| RULE
| TRIGGER
;
any_name_list
: any_name (COMMA any_name)*
;
any_name
: colid attrs?
;
attrs
:(DOT attr_name)+
;
type_name_list
: typename (COMMA typename)*
;
truncatestmt
: TRUNCATE opt_table relation_expr_list opt_restart_seqs opt_drop_behavior
;
opt_restart_seqs
: CONTINUE_P IDENTITY_P
| RESTART IDENTITY_P
|
;
commentstmt
: COMMENT ON object_type_any_name any_name IS comment_text
| COMMENT ON COLUMN any_name IS comment_text
| COMMENT ON object_type_name name IS comment_text
| COMMENT ON TYPE_P typename IS comment_text
| COMMENT ON DOMAIN_P typename IS comment_text
| COMMENT ON AGGREGATE aggregate_with_argtypes IS comment_text
| COMMENT ON FUNCTION function_with_argtypes IS comment_text
| COMMENT ON OPERATOR operator_with_argtypes IS comment_text
| COMMENT ON CONSTRAINT name ON any_name IS comment_text
| COMMENT ON CONSTRAINT name ON DOMAIN_P any_name IS comment_text
| COMMENT ON object_type_name_on_any_name name ON any_name IS comment_text
| COMMENT ON PROCEDURE function_with_argtypes IS comment_text
| COMMENT ON ROUTINE function_with_argtypes IS comment_text
| COMMENT ON TRANSFORM FOR typename LANGUAGE name IS comment_text
| COMMENT ON OPERATOR CLASS any_name USING name IS comment_text
| COMMENT ON OPERATOR FAMILY any_name USING name IS comment_text
| COMMENT ON LARGE_P OBJECT_P numericonly IS comment_text
| COMMENT ON CAST OPEN_PAREN typename AS typename CLOSE_PAREN IS comment_text
;
comment_text
: sconst
| NULL_P
;
seclabelstmt
: SECURITY LABEL opt_provider ON object_type_any_name any_name IS security_label
| SECURITY LABEL opt_provider ON COLUMN any_name IS security_label
| SECURITY LABEL opt_provider ON object_type_name name IS security_label
| SECURITY LABEL opt_provider ON TYPE_P typename IS security_label
| SECURITY LABEL opt_provider ON DOMAIN_P typename IS security_label
| SECURITY LABEL opt_provider ON AGGREGATE aggregate_with_argtypes IS security_label
| SECURITY LABEL opt_provider ON FUNCTION function_with_argtypes IS security_label
| SECURITY LABEL opt_provider ON LARGE_P OBJECT_P numericonly IS security_label
| SECURITY LABEL opt_provider ON PROCEDURE function_with_argtypes IS security_label
| SECURITY LABEL opt_provider ON ROUTINE function_with_argtypes IS security_label
;
opt_provider
: FOR nonreservedword_or_sconst
|
;
security_label
: sconst
| NULL_P
;
fetchstmt
: FETCH fetch_args
| MOVE fetch_args
;
fetch_args
: cursor_name
| from_in cursor_name
| NEXT opt_from_in cursor_name
| PRIOR opt_from_in cursor_name
| FIRST_P opt_from_in cursor_name
| LAST_P opt_from_in cursor_name
| ABSOLUTE_P signediconst opt_from_in cursor_name
| RELATIVE_P signediconst opt_from_in cursor_name
| signediconst opt_from_in cursor_name
| ALL opt_from_in cursor_name
| FORWARD opt_from_in cursor_name
| FORWARD signediconst opt_from_in cursor_name
| FORWARD ALL opt_from_in cursor_name
| BACKWARD opt_from_in cursor_name
| BACKWARD signediconst opt_from_in cursor_name
| BACKWARD ALL opt_from_in cursor_name
;
from_in
: FROM
| IN_P
;
opt_from_in
: from_in
|
;
grantstmt
: GRANT privileges ON privilege_target TO grantee_list opt_grant_grant_option
;
revokestmt
: REVOKE privileges ON privilege_target FROM grantee_list opt_drop_behavior
| REVOKE GRANT OPTION FOR privileges ON privilege_target FROM grantee_list opt_drop_behavior
;
privileges
: privilege_list
| ALL
| ALL PRIVILEGES
| ALL OPEN_PAREN columnlist CLOSE_PAREN
| ALL PRIVILEGES OPEN_PAREN columnlist CLOSE_PAREN
;
privilege_list
: privilege (COMMA privilege)*
;
privilege
: SELECT opt_column_list
| REFERENCES opt_column_list
| CREATE opt_column_list
| colid opt_column_list
;
privilege_target
: qualified_name_list
| TABLE qualified_name_list
| SEQUENCE qualified_name_list
| FOREIGN DATA_P WRAPPER name_list
| FOREIGN SERVER name_list
| FUNCTION function_with_argtypes_list
| PROCEDURE function_with_argtypes_list
| ROUTINE function_with_argtypes_list
| DATABASE name_list
| DOMAIN_P any_name_list
| LANGUAGE name_list
| LARGE_P OBJECT_P numericonly_list
| SCHEMA name_list
| TABLESPACE name_list
| TYPE_P any_name_list
| ALL TABLES IN_P SCHEMA name_list
| ALL SEQUENCES IN_P SCHEMA name_list
| ALL FUNCTIONS IN_P SCHEMA name_list
| ALL PROCEDURES IN_P SCHEMA name_list
| ALL ROUTINES IN_P SCHEMA name_list
;
grantee_list
: grantee (COMMA grantee)*
;
grantee
: rolespec
| GROUP_P rolespec
;
opt_grant_grant_option
: WITH GRANT OPTION
|
;
grantrolestmt
: GRANT privilege_list TO role_list opt_grant_admin_option opt_granted_by
;
revokerolestmt
: REVOKE privilege_list FROM role_list opt_granted_by opt_drop_behavior
| REVOKE ADMIN OPTION FOR privilege_list FROM role_list opt_granted_by opt_drop_behavior
;
opt_grant_admin_option
: WITH ADMIN OPTION
|
;
opt_granted_by
: GRANTED BY rolespec
|
;
alterdefaultprivilegesstmt
: ALTER DEFAULT PRIVILEGES defacloptionlist defaclaction
;
defacloptionlist
: defacloption*
;
defacloption
: IN_P SCHEMA name_list
| FOR ROLE role_list
| FOR USER role_list
;
defaclaction
: GRANT privileges ON defacl_privilege_target TO grantee_list opt_grant_grant_option
| REVOKE privileges ON defacl_privilege_target FROM grantee_list opt_drop_behavior
| REVOKE GRANT OPTION FOR privileges ON defacl_privilege_target FROM grantee_list opt_drop_behavior
;
defacl_privilege_target
: TABLES
| FUNCTIONS
| ROUTINES
| SEQUENCES
| TYPES_P
| SCHEMAS
;
//create index
indexstmt
: 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
| 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
;
opt_unique
: UNIQUE
|
;
opt_concurrently
: CONCURRENTLY
|
;
opt_index_name
: name
|
;
access_method_clause
: USING name
|
;
index_params
: index_elem (COMMA index_elem)*
;
index_elem_options
: opt_collate opt_class opt_asc_desc opt_nulls_order
| opt_collate any_name reloptions opt_asc_desc opt_nulls_order
;
index_elem
: colid index_elem_options
| func_expr_windowless index_elem_options
| OPEN_PAREN a_expr CLOSE_PAREN index_elem_options
;
opt_include
: INCLUDE OPEN_PAREN index_including_params CLOSE_PAREN
|
;
index_including_params
: index_elem (COMMA index_elem)*
;
opt_collate
: COLLATE any_name
|
;
opt_class
: any_name
|
;
opt_asc_desc
: ASC
| DESC
|
;
//TOD NULLS_LA was used
opt_nulls_order
: NULLS_P FIRST_P
| NULLS_P LAST_P
|
;
createfunctionstmt
: CREATE opt_or_replace (FUNCTION | PROCEDURE) func_name func_args_with_defaults
(
RETURNS (func_return | TABLE OPEN_PAREN table_func_column_list CLOSE_PAREN)
)?
createfunc_opt_list
;
opt_or_replace
: OR REPLACE
|
;
func_args
: OPEN_PAREN func_args_list? CLOSE_PAREN
;
func_args_list
: func_arg (COMMA func_arg)*
;
function_with_argtypes_list
: function_with_argtypes (COMMA function_with_argtypes)*
;
function_with_argtypes
: func_name func_args
| type_func_name_keyword
| colid indirection?
;
func_args_with_defaults
: OPEN_PAREN func_args_with_defaults_list? CLOSE_PAREN
;
func_args_with_defaults_list
: func_arg_with_default (COMMA func_arg_with_default)*
;
func_arg
: arg_class param_name? func_type
| param_name arg_class? func_type
| func_type
;
arg_class
: IN_P OUT_P?
| OUT_P
| INOUT
| VARIADIC
;
param_name
: type_function_name
| builtin_function_name
| LEFT
| RIGHT
;
func_return
: func_type
;
func_type
: typename
| SETOF? (builtin_function_name | type_function_name | LEFT | RIGHT) attrs PERCENT TYPE_P
;
func_arg_with_default
: func_arg ((DEFAULT | EQUAL) a_expr)?
;
aggr_arg
: func_arg
;
aggr_args
: OPEN_PAREN (STAR | aggr_args_list | ORDER BY aggr_args_list | aggr_args_list ORDER BY aggr_args_list) CLOSE_PAREN
;
aggr_args_list
: aggr_arg (COMMA aggr_arg)*
;
aggregate_with_argtypes
: func_name aggr_args
;
aggregate_with_argtypes_list
: aggregate_with_argtypes (COMMA aggregate_with_argtypes)*
;
createfunc_opt_list
: createfunc_opt_item+
{
ParseRoutineBody(_localctx);
}
// | createfunc_opt_list createfunc_opt_item
;
common_func_opt_item
: CALLED ON NULL_P INPUT_P
| RETURNS NULL_P ON NULL_P INPUT_P
| STRICT_P
| IMMUTABLE
| STABLE
| VOLATILE
| EXTERNAL SECURITY DEFINER
| EXTERNAL SECURITY INVOKER
| SECURITY DEFINER
| SECURITY INVOKER
| LEAKPROOF
| NOT LEAKPROOF
| SHIPPABLE
| NOT SHIPPABLE
| FENCED
| NOT FENCED
| PACKAGE
| COST numericonly
| ROWS numericonly
| SUPPORT any_name
| functionsetresetclause
| PARALLEL colid
;
createfunc_opt_item
: AS func_as
| LANGUAGE nonreservedword_or_sconst
| TRANSFORM transform_type_list
| WINDOW
| common_func_opt_item
;
//https://www.postgresql.org/docs/9.1/sql-createfunction.html
// | AS 'definition'
// | AS 'obj_file', 'link_symbol'
func_as locals[ParserRuleContext Definition]
:
/* |AS 'definition'*/
def = sconst
/*| AS 'obj_file', 'link_symbol'*/
| sconst COMMA sconst
;
transform_type_list
:FOR TYPE_P typename (COMMA FOR TYPE_P typename)*
;
opt_definition
: WITH definition
|
;
table_func_column
: param_name func_type
;
table_func_column_list
: table_func_column (COMMA table_func_column)*
;
alterfunctionstmt
: ALTER (FUNCTION | PROCEDURE | ROUTINE) function_with_argtypes alterfunc_opt_list opt_restrict
;
alterfunc_opt_list
: common_func_opt_item+
;
opt_restrict
: RESTRICT
|
;
removefuncstmt
: DROP FUNCTION function_with_argtypes_list opt_drop_behavior
| DROP FUNCTION IF_P EXISTS function_with_argtypes_list opt_drop_behavior
| DROP PROCEDURE function_with_argtypes_list opt_drop_behavior
| DROP PROCEDURE IF_P EXISTS function_with_argtypes_list opt_drop_behavior
| DROP ROUTINE function_with_argtypes_list opt_drop_behavior
| DROP ROUTINE IF_P EXISTS function_with_argtypes_list opt_drop_behavior
;
removeaggrstmt
: DROP AGGREGATE aggregate_with_argtypes_list opt_drop_behavior
| DROP AGGREGATE IF_P EXISTS aggregate_with_argtypes_list opt_drop_behavior
;
removeoperstmt
: DROP OPERATOR operator_with_argtypes_list opt_drop_behavior
| DROP OPERATOR IF_P EXISTS operator_with_argtypes_list opt_drop_behavior
;
oper_argtypes
: OPEN_PAREN typename CLOSE_PAREN
| OPEN_PAREN typename COMMA typename CLOSE_PAREN
| OPEN_PAREN NONE COMMA typename CLOSE_PAREN
| OPEN_PAREN typename COMMA NONE CLOSE_PAREN
;
any_operator
: (colid DOT)* all_op
;
operator_with_argtypes_list
: operator_with_argtypes (COMMA operator_with_argtypes)*
;
operator_with_argtypes
: any_operator oper_argtypes
;
dostmt
: DO dostmt_opt_list
;
dostmt_opt_list
: dostmt_opt_item+
;
dostmt_opt_item
: sconst
| LANGUAGE nonreservedword_or_sconst
;
createcaststmt
: CREATE CAST OPEN_PAREN typename AS typename CLOSE_PAREN WITH FUNCTION function_with_argtypes cast_context
| CREATE CAST OPEN_PAREN typename AS typename CLOSE_PAREN WITHOUT FUNCTION cast_context
| CREATE CAST OPEN_PAREN typename AS typename CLOSE_PAREN WITH INOUT cast_context
;
cast_context
: AS IMPLICIT_P
| AS ASSIGNMENT
|
;
dropcaststmt
: DROP CAST opt_if_exists OPEN_PAREN typename AS typename CLOSE_PAREN opt_drop_behavior
;
opt_if_exists
: IF_P EXISTS
|
;
createtransformstmt
: CREATE opt_or_replace TRANSFORM FOR typename LANGUAGE name OPEN_PAREN transform_element_list CLOSE_PAREN
;
transform_element_list
: FROM SQL_P WITH FUNCTION function_with_argtypes COMMA TO SQL_P WITH FUNCTION function_with_argtypes
| TO SQL_P WITH FUNCTION function_with_argtypes COMMA FROM SQL_P WITH FUNCTION function_with_argtypes
| FROM SQL_P WITH FUNCTION function_with_argtypes
| TO SQL_P WITH FUNCTION function_with_argtypes
;
droptransformstmt
: DROP TRANSFORM opt_if_exists FOR typename LANGUAGE name opt_drop_behavior
;
reindexstmt
: REINDEX reindex_target_type opt_concurrently qualified_name
| REINDEX reindex_target_multitable opt_concurrently name
| REINDEX OPEN_PAREN reindex_option_list CLOSE_PAREN reindex_target_type opt_concurrently qualified_name
| REINDEX OPEN_PAREN reindex_option_list CLOSE_PAREN reindex_target_multitable opt_concurrently name
;
reindex_target_type
: INDEX
| TABLE
| SCHEMA
| DATABASE
| SYSTEM_P
;
reindex_target_multitable
: SCHEMA
| SYSTEM_P
| DATABASE
;
reindex_option_list
: reindex_option_elem (COMMA reindex_option_elem)*
;
reindex_option_elem
: VERBOSE
| TABLESPACE
| CONCURRENTLY
;
altertblspcstmt
: ALTER TABLESPACE name SET reloptions
| ALTER TABLESPACE name RESET reloptions
;
renamestmt
: ALTER AGGREGATE aggregate_with_argtypes RENAME TO name
| ALTER COLLATION any_name RENAME TO name
| ALTER CONVERSION_P any_name RENAME TO name
| ALTER DATABASE name RENAME TO name
| ALTER DOMAIN_P any_name RENAME TO name
| ALTER DOMAIN_P any_name RENAME CONSTRAINT name TO name
| ALTER FOREIGN DATA_P WRAPPER name RENAME TO name
| ALTER FUNCTION function_with_argtypes RENAME TO name
| ALTER GROUP_P roleid RENAME TO roleid
| ALTER opt_procedural LANGUAGE name RENAME TO name
| ALTER OPERATOR CLASS any_name USING name RENAME TO name
| ALTER OPERATOR FAMILY any_name USING name RENAME TO name
| ALTER POLICY name ON qualified_name RENAME TO name
| ALTER POLICY IF_P EXISTS name ON qualified_name RENAME TO name
| ALTER PROCEDURE function_with_argtypes RENAME TO name
| ALTER PUBLICATION name RENAME TO name
| ALTER ROUTINE function_with_argtypes RENAME TO name
| ALTER SCHEMA name RENAME TO name
| ALTER SERVER name RENAME TO name
| ALTER SUBSCRIPTION name RENAME TO name
| ALTER TABLE relation_expr RENAME TO name
| ALTER TABLE IF_P EXISTS relation_expr RENAME TO name
| ALTER SEQUENCE qualified_name RENAME TO name
| ALTER SEQUENCE IF_P EXISTS qualified_name RENAME TO name
| ALTER VIEW qualified_name RENAME TO name
| ALTER VIEW IF_P EXISTS qualified_name RENAME TO name
| ALTER MATERIALIZED VIEW qualified_name RENAME TO name
| ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name RENAME TO name
| ALTER INDEX qualified_name RENAME TO name
| ALTER INDEX IF_P EXISTS qualified_name RENAME TO name
| ALTER FOREIGN TABLE relation_expr RENAME TO name
| ALTER FOREIGN TABLE IF_P EXISTS relation_expr RENAME TO name
| ALTER TABLE relation_expr RENAME opt_column name TO name
| ALTER TABLE IF_P EXISTS relation_expr RENAME opt_column name TO name
| ALTER VIEW qualified_name RENAME opt_column name TO name
| ALTER VIEW IF_P EXISTS qualified_name RENAME opt_column name TO name
| ALTER MATERIALIZED VIEW qualified_name RENAME opt_column name TO name
| ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name RENAME opt_column name TO name
| ALTER TABLE relation_expr RENAME CONSTRAINT name TO name
| ALTER TABLE IF_P EXISTS relation_expr RENAME CONSTRAINT name TO name
| ALTER FOREIGN TABLE relation_expr RENAME opt_column name TO name
| ALTER FOREIGN TABLE IF_P EXISTS relation_expr RENAME opt_column name TO name
| ALTER RULE name ON qualified_name RENAME TO name
| ALTER TRIGGER name ON qualified_name RENAME TO name
| ALTER EVENT TRIGGER name RENAME TO name
| ALTER ROLE roleid RENAME TO roleid
| ALTER USER roleid RENAME TO roleid
| ALTER TABLESPACE name RENAME TO name
| ALTER STATISTICS any_name RENAME TO name
| ALTER TEXT_P SEARCH PARSER any_name RENAME TO name
| ALTER TEXT_P SEARCH DICTIONARY any_name RENAME TO name
| ALTER TEXT_P SEARCH TEMPLATE any_name RENAME TO name
| ALTER TEXT_P SEARCH CONFIGURATION any_name RENAME TO name
| ALTER TYPE_P any_name RENAME TO name
| ALTER TYPE_P any_name RENAME ATTRIBUTE name TO name opt_drop_behavior
;
opt_column
: COLUMN
|
;
opt_set_data
: SET DATA_P
|
;
alterobjectdependsstmt
: ALTER FUNCTION function_with_argtypes opt_no DEPENDS ON EXTENSION name
| ALTER PROCEDURE function_with_argtypes opt_no DEPENDS ON EXTENSION name
| ALTER ROUTINE function_with_argtypes opt_no DEPENDS ON EXTENSION name
| ALTER TRIGGER name ON qualified_name opt_no DEPENDS ON EXTENSION name
| ALTER MATERIALIZED VIEW qualified_name opt_no DEPENDS ON EXTENSION name
| ALTER INDEX qualified_name opt_no DEPENDS ON EXTENSION name
;
opt_no
: NO
|
;
alterobjectschemastmt
: ALTER AGGREGATE aggregate_with_argtypes SET SCHEMA name
| ALTER COLLATION any_name SET SCHEMA name
| ALTER CONVERSION_P any_name SET SCHEMA name
| ALTER DOMAIN_P any_name SET SCHEMA name
| ALTER EXTENSION name SET SCHEMA name
| ALTER FUNCTION function_with_argtypes SET SCHEMA name
| ALTER OPERATOR operator_with_argtypes SET SCHEMA name
| ALTER OPERATOR CLASS any_name USING name SET SCHEMA name
| ALTER OPERATOR FAMILY any_name USING name SET SCHEMA name
| ALTER PROCEDURE function_with_argtypes SET SCHEMA name
| ALTER ROUTINE function_with_argtypes SET SCHEMA name
| ALTER TABLE relation_expr SET SCHEMA name
| ALTER TABLE IF_P EXISTS relation_expr SET SCHEMA name
| ALTER STATISTICS any_name SET SCHEMA name
| ALTER TEXT_P SEARCH PARSER any_name SET SCHEMA name
| ALTER TEXT_P SEARCH DICTIONARY any_name SET SCHEMA name
| ALTER TEXT_P SEARCH TEMPLATE any_name SET SCHEMA name
| ALTER TEXT_P SEARCH CONFIGURATION any_name SET SCHEMA name
| ALTER SEQUENCE qualified_name SET SCHEMA name
| ALTER SEQUENCE IF_P EXISTS qualified_name SET SCHEMA name
| ALTER VIEW qualified_name SET SCHEMA name
| ALTER VIEW IF_P EXISTS qualified_name SET SCHEMA name
| ALTER MATERIALIZED VIEW qualified_name SET SCHEMA name
| ALTER MATERIALIZED VIEW IF_P EXISTS qualified_name SET SCHEMA name
| ALTER FOREIGN TABLE relation_expr SET SCHEMA name
| ALTER FOREIGN TABLE IF_P EXISTS relation_expr SET SCHEMA name
| ALTER TYPE_P any_name SET SCHEMA name
;
alteroperatorstmt
: ALTER OPERATOR operator_with_argtypes SET OPEN_PAREN operator_def_list CLOSE_PAREN
;
operator_def_list
: operator_def_elem (COMMA operator_def_elem)*
;
operator_def_elem
: collabel EQUAL NONE
| collabel EQUAL operator_def_arg
;
operator_def_arg
: func_type
| reserved_keyword
| qual_all_op
| numericonly
| sconst
;
altertypestmt
: ALTER TYPE_P any_name SET OPEN_PAREN operator_def_list CLOSE_PAREN
;
alterownerstmt
: ALTER AGGREGATE aggregate_with_argtypes OWNER TO rolespec
| ALTER COLLATION any_name OWNER TO rolespec
| ALTER CONVERSION_P any_name OWNER TO rolespec
| ALTER DATABASE name OWNER TO rolespec
| ALTER DOMAIN_P any_name OWNER TO rolespec
| ALTER FUNCTION function_with_argtypes OWNER TO rolespec
| ALTER opt_procedural LANGUAGE name OWNER TO rolespec
| ALTER LARGE_P OBJECT_P numericonly OWNER TO rolespec
| ALTER OPERATOR operator_with_argtypes OWNER TO rolespec
| ALTER OPERATOR CLASS any_name USING name OWNER TO rolespec
| ALTER OPERATOR FAMILY any_name USING name OWNER TO rolespec
| ALTER PROCEDURE function_with_argtypes OWNER TO rolespec
| ALTER ROUTINE function_with_argtypes OWNER TO rolespec
| ALTER SCHEMA name OWNER TO rolespec
| ALTER TYPE_P any_name OWNER TO rolespec
| ALTER TABLESPACE name OWNER TO rolespec
| ALTER STATISTICS any_name OWNER TO rolespec
| ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO rolespec
| ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO rolespec
| ALTER FOREIGN DATA_P WRAPPER name OWNER TO rolespec
| ALTER SERVER name OWNER TO rolespec
| ALTER EVENT TRIGGER name OWNER TO rolespec
| ALTER PUBLICATION name OWNER TO rolespec
| ALTER SUBSCRIPTION name OWNER TO rolespec
;
createpublicationstmt
: CREATE PUBLICATION name opt_publication_for_tables opt_definition
;
opt_publication_for_tables
: publication_for_tables
|
;
publication_for_tables
: FOR TABLE relation_expr_list
| FOR ALL TABLES
;
alterpublicationstmt
: ALTER PUBLICATION name SET definition
| ALTER PUBLICATION name ADD_P TABLE relation_expr_list
| ALTER PUBLICATION name SET TABLE relation_expr_list
| ALTER PUBLICATION name DROP TABLE relation_expr_list
;
createsubscriptionstmt
: CREATE SUBSCRIPTION name CONNECTION sconst PUBLICATION publication_name_list opt_definition
;
publication_name_list
: publication_name_item (COMMA publication_name_item)*
;
publication_name_item
: collabel
;
altersubscriptionstmt
: ALTER SUBSCRIPTION name SET definition
| ALTER SUBSCRIPTION name CONNECTION sconst
| ALTER SUBSCRIPTION name REFRESH PUBLICATION opt_definition
| ALTER SUBSCRIPTION name SET PUBLICATION publication_name_list opt_definition
| ALTER SUBSCRIPTION name ENABLE_P
| ALTER SUBSCRIPTION name DISABLE_P
;
dropsubscriptionstmt
: DROP SUBSCRIPTION name opt_drop_behavior
| DROP SUBSCRIPTION IF_P EXISTS name opt_drop_behavior
;
rulestmt
: CREATE opt_or_replace RULE name AS ON event TO qualified_name where_clause DO opt_instead ruleactionlist
;
ruleactionlist
: NOTHING
| ruleactionstmt
| OPEN_PAREN ruleactionmulti CLOSE_PAREN
;
ruleactionmulti
: ruleactionstmtOrEmpty (SEMI ruleactionstmtOrEmpty)*
;
ruleactionstmt
: selectstmt
| insertstmt
| updatestmt
| deletestmt
| notifystmt
;
ruleactionstmtOrEmpty
: ruleactionstmt
|
;
event
: SELECT
| UPDATE
| DELETE_P
| INSERT
;
opt_instead
: INSTEAD
| ALSO
|
;
notifystmt
: NOTIFY colid notify_payload
;
notify_payload
: COMMA sconst
|
;
listenstmt
: LISTEN colid
;
unlistenstmt
: UNLISTEN colid
| UNLISTEN STAR
;
transactionstmt
: ABORT_P opt_transaction opt_transaction_chain
| BEGIN_P opt_transaction transaction_mode_list_or_empty
| START TRANSACTION transaction_mode_list_or_empty
| COMMIT opt_transaction opt_transaction_chain
| END_P opt_transaction opt_transaction_chain
| ROLLBACK opt_transaction opt_transaction_chain
| SAVEPOINT colid
| RELEASE SAVEPOINT colid
| RELEASE colid
| ROLLBACK opt_transaction TO SAVEPOINT colid
| ROLLBACK opt_transaction TO colid
| PREPARE TRANSACTION sconst
| COMMIT PREPARED sconst
| ROLLBACK PREPARED sconst
;
opt_transaction
: WORK
| TRANSACTION
|
;
transaction_mode_item
: ISOLATION LEVEL iso_level
| READ ONLY
| READ WRITE
| DEFERRABLE
| NOT DEFERRABLE
;
transaction_mode_list
: transaction_mode_item (COMMA? transaction_mode_item)*
;
transaction_mode_list_or_empty
: transaction_mode_list
|
;
opt_transaction_chain
: AND NO? CHAIN
|
;
viewstmt
: CREATE (OR REPLACE)? opttemp
(
VIEW qualified_name opt_column_list opt_reloptions
| RECURSIVE VIEW qualified_name OPEN_PAREN columnlist CLOSE_PAREN opt_reloptions
)
AS selectstmt opt_check_option
;
opt_check_option
: WITH (CASCADED | LOCAL)? CHECK OPTION
|
;
loadstmt
: LOAD file_name
;
createdbstmt
: CREATE DATABASE name opt_with createdb_opt_list
;
createdb_opt_list
: createdb_opt_items
|
;
createdb_opt_items
: createdb_opt_item+
;
createdb_opt_item
: createdb_opt_name opt_equal (signediconst | opt_boolean_or_string | DEFAULT)
;
createdb_opt_name
: identifier
| CONNECTION LIMIT
| ENCODING
| LOCATION
| OWNER
| TABLESPACE
| TEMPLATE
;
opt_equal
: EQUAL
|
;
alterdatabasestmt
: ALTER DATABASE name (WITH createdb_opt_list | createdb_opt_list | SET TABLESPACE name)
;
alterdatabasesetstmt
: ALTER DATABASE name setresetclause
;
dropdbstmt
: DROP DATABASE (IF_P EXISTS)? name (opt_with OPEN_PAREN drop_option_list CLOSE_PAREN)?
;
drop_option_list
: drop_option (COMMA drop_option)*
;
drop_option
: FORCE
;
altercollationstmt
: ALTER COLLATION any_name REFRESH VERSION_P
;
altersystemstmt
: ALTER SYSTEM_P (SET | RESET) generic_set
;
createdomainstmt
: CREATE DOMAIN_P any_name opt_as typename colquallist
;
alterdomainstmt
: 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)
;
opt_as
: AS
|
;
altertsdictionarystmt
: ALTER TEXT_P SEARCH DICTIONARY any_name definition
;
altertsconfigurationstmt
: ALTER TEXT_P SEARCH CONFIGURATION any_name ADD_P MAPPING FOR name_list any_with any_name_list
| ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list any_with any_name_list
| ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING REPLACE any_name any_with any_name
| ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list REPLACE any_name any_with any_name
| ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING FOR name_list
| ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING IF_P EXISTS FOR name_list
;
any_with
: WITH
//TODO
// | WITH_LA
;
createconversionstmt
: CREATE opt_default CONVERSION_P any_name FOR sconst TO sconst FROM any_name
;
clusterstmt
: CLUSTER opt_verbose qualified_name cluster_index_specification
| CLUSTER opt_verbose
| CLUSTER opt_verbose name ON qualified_name
;
cluster_index_specification
: USING name
|
;
vacuumstmt
: VACUUM opt_full opt_freeze opt_verbose opt_analyze opt_vacuum_relation_list
| VACUUM OPEN_PAREN vac_analyze_option_list CLOSE_PAREN opt_vacuum_relation_list
;
analyzestmt
: analyze_keyword opt_verbose opt_vacuum_relation_list
| analyze_keyword OPEN_PAREN vac_analyze_option_list CLOSE_PAREN opt_vacuum_relation_list
;
vac_analyze_option_list
: vac_analyze_option_elem (COMMA vac_analyze_option_elem)*
;
analyze_keyword
: ANALYZE
| ANALYSE
;
vac_analyze_option_elem
: vac_analyze_option_name vac_analyze_option_arg
;
vac_analyze_option_name
: nonreservedword
| analyze_keyword
;
vac_analyze_option_arg
: opt_boolean_or_string
| numericonly
|
;
opt_analyze
: analyze_keyword
|
;
opt_verbose
: VERBOSE
|
;
opt_full
: FULL
|
;
opt_freeze
: FREEZE
|
;
opt_name_list
: OPEN_PAREN name_list CLOSE_PAREN
|
;
vacuum_relation
: qualified_name opt_name_list
;
vacuum_relation_list
: vacuum_relation (COMMA vacuum_relation)*
;
opt_vacuum_relation_list
: vacuum_relation_list
|
;
explainstmt
: EXPLAIN explainablestmt
| EXPLAIN analyze_keyword opt_verbose explainablestmt
| EXPLAIN VERBOSE explainablestmt
| EXPLAIN OPEN_PAREN explain_option_list CLOSE_PAREN explainablestmt
;
explainablestmt
: selectstmt
| insertstmt
| updatestmt
| deletestmt
| declarecursorstmt
| createasstmt
| creatematviewstmt
| refreshmatviewstmt
| executestmt
;
explain_option_list
: explain_option_elem (COMMA explain_option_elem)*
;
explain_option_elem
: explain_option_name explain_option_arg
;
explain_option_name
: nonreservedword
| analyze_keyword
;
explain_option_arg
: opt_boolean_or_string
| numericonly
|
;
preparestmt
: PREPARE name prep_type_clause AS preparablestmt
;
prep_type_clause
: OPEN_PAREN type_list CLOSE_PAREN
|
;
preparablestmt
: selectstmt
| insertstmt
| updatestmt
| deletestmt
;
executestmt
: EXECUTE name execute_param_clause
| CREATE opttemp TABLE create_as_target AS EXECUTE name execute_param_clause opt_with_data
| CREATE opttemp TABLE IF_P NOT EXISTS create_as_target AS EXECUTE name execute_param_clause opt_with_data
;
execute_param_clause
: OPEN_PAREN expr_list CLOSE_PAREN
|
;
deallocatestmt
: DEALLOCATE name
| DEALLOCATE PREPARE name
| DEALLOCATE ALL
| DEALLOCATE PREPARE ALL
;
insertstmt
: opt_with_clause INSERT INTO insert_target insert_rest opt_on_conflict returning_clause
;
insert_target
: qualified_name (AS colid)?
;
insert_rest
: selectstmt
| OVERRIDING override_kind VALUE_P selectstmt
| OPEN_PAREN insert_column_list CLOSE_PAREN (OVERRIDING override_kind VALUE_P)? selectstmt
| DEFAULT VALUES
;
override_kind
: USER
| SYSTEM_P
;
insert_column_list
: insert_column_item (COMMA insert_column_item)*
;
insert_column_item
: colid opt_indirection
;
opt_on_conflict
: ON CONFLICT opt_conf_expr DO (UPDATE SET set_clause_list where_clause | NOTHING)
|
;
opt_conf_expr
: OPEN_PAREN index_params CLOSE_PAREN where_clause
| ON CONSTRAINT name
|
;
returning_clause
: RETURNING target_list
|
;
// https://www.postgresql.org/docs/current/sql-merge.html
mergestmt
: MERGE INTO? qualified_name alias_clause? USING (select_with_parens|qualified_name) alias_clause? ON a_expr
(merge_insert_clause merge_update_clause? | merge_update_clause merge_insert_clause?) merge_delete_clause?
;
merge_insert_clause
: WHEN NOT MATCHED (AND a_expr)? THEN? INSERT (OPEN_PAREN insert_column_list CLOSE_PAREN)? values_clause
;
merge_update_clause
: WHEN MATCHED (AND a_expr)? THEN? UPDATE SET set_clause_list
;
merge_delete_clause
: WHEN MATCHED THEN? DELETE_P
;
deletestmt
: opt_with_clause DELETE_P FROM relation_expr_opt_alias using_clause where_or_current_clause returning_clause
;
using_clause
: USING from_list
|
;
lockstmt
: LOCK_P opt_table relation_expr_list opt_lock opt_nowait
;
opt_lock
: IN_P lock_type MODE
|
;
lock_type
: ACCESS (SHARE | EXCLUSIVE)
| ROW (SHARE | EXCLUSIVE)
| SHARE (UPDATE EXCLUSIVE | ROW EXCLUSIVE)?
| EXCLUSIVE
;
opt_nowait
: NOWAIT
|
;
opt_nowait_or_skip
: NOWAIT
| SKIP_P LOCKED
|
;
updatestmt
: opt_with_clause UPDATE relation_expr_opt_alias SET set_clause_list from_clause where_or_current_clause returning_clause
;
set_clause_list
: set_clause (COMMA set_clause)*
;
set_clause
: set_target EQUAL a_expr
| OPEN_PAREN set_target_list CLOSE_PAREN EQUAL a_expr
;
set_target
: colid opt_indirection
;
set_target_list
: set_target (COMMA set_target)*
;
declarecursorstmt
: DECLARE cursor_name cursor_options CURSOR opt_hold FOR selectstmt
;
cursor_name
: name
;
cursor_options
: (NO SCROLL | SCROLL | BINARY | INSENSITIVE)*
;
opt_hold
:
| WITH HOLD
| WITHOUT HOLD
;
/*
TODO: why select_with_parens alternative is needed at all?
i guess it because original byson grammar can choose selectstmt(2)->select_with_parens on only OPEN_PARENT/SELECT kewords at the begining of statement;
(select * from tab);
parse can go through selectstmt( )->select_no_parens(1)->select_clause(2)->select_with_parens(1)->select_no_parens(1)->select_clause(1)->simple_select
instead of selectstmt(1)->select_no_parens(1)->select_clause(2)->select_with_parens(1)->select_no_parens(1)->select_clause(1)->simple_select
all standard tests passed on both variants
*/
selectstmt
: select_no_parens
| select_with_parens
;
select_with_parens
: OPEN_PAREN select_no_parens CLOSE_PAREN
| OPEN_PAREN select_with_parens CLOSE_PAREN
;
select_no_parens
: select_clause opt_sort_clause (for_locking_clause opt_select_limit | select_limit opt_for_locking_clause)?
| with_clause select_clause opt_sort_clause (for_locking_clause opt_select_limit | select_limit opt_for_locking_clause)?
;
select_clause
: simple_select_intersect ((UNION | EXCEPT) all_or_distinct simple_select_intersect)*
;
simple_select_intersect
: simple_select_pramary (INTERSECT all_or_distinct simple_select_pramary)*
;
simple_select_pramary
: ( SELECT (opt_all_clause into_clause opt_target_list | distinct_clause target_list)
into_clause
from_clause
where_clause
group_clause
having_clause
window_clause
)
| values_clause
| TABLE relation_expr
| select_with_parens
;
with_clause
: WITH RECURSIVE? cte_list
;
cte_list
: common_table_expr (COMMA common_table_expr)*
;
common_table_expr
: name opt_name_list AS opt_materialized OPEN_PAREN preparablestmt CLOSE_PAREN
;
opt_materialized
: MATERIALIZED
| NOT MATERIALIZED
|
;
opt_with_clause
: with_clause
|
;
into_clause
: INTO (opt_strict opttempTableName | into_target)
|
;
opt_strict
:
| STRICT_P
;
opttempTableName
: (LOCAL|GLOBAL)? (TEMPORARY | TEMP) opt_table qualified_name
| UNLOGGED opt_table qualified_name
| TABLE qualified_name
| qualified_name
;
opt_table
: TABLE
|
;
all_or_distinct
: ALL
| DISTINCT
|
;
distinct_clause
: DISTINCT (ON OPEN_PAREN expr_list CLOSE_PAREN)?
;
opt_all_clause
: ALL
|
;
opt_sort_clause
: sort_clause
|
;
sort_clause
: ORDER BY sortby_list
;
sortby_list
: sortby (COMMA sortby)*
;
sortby
: a_expr (USING qual_all_op | opt_asc_desc) opt_nulls_order
;
select_limit
: limit_clause offset_clause?
| offset_clause limit_clause?
;
opt_select_limit
: select_limit
|
;
limit_clause
: LIMIT select_limit_value (COMMA select_offset_value)?
| FETCH first_or_next (select_fetch_first_value row_or_rows (ONLY | WITH TIES) | row_or_rows (ONLY | WITH TIES))
;
offset_clause
: OFFSET (select_offset_value | select_fetch_first_value row_or_rows)
;
select_limit_value
: a_expr
| ALL
;
select_offset_value
: a_expr
;
select_fetch_first_value
: c_expr
| PLUS i_or_f_const
| MINUS i_or_f_const
;
i_or_f_const
: iconst
| fconst
;
row_or_rows
: ROW
| ROWS
;
first_or_next
: FIRST_P
| NEXT
;
group_clause
: GROUP_P BY group_by_list
|
;
group_by_list
: group_by_item (COMMA group_by_item)*
;
group_by_item
: empty_grouping_set
| cube_clause
| rollup_clause
| grouping_sets_clause
| a_expr
;
empty_grouping_set
: OPEN_PAREN CLOSE_PAREN
;
rollup_clause
: ROLLUP OPEN_PAREN expr_list CLOSE_PAREN
;
cube_clause
: CUBE OPEN_PAREN expr_list CLOSE_PAREN
;
grouping_sets_clause
: GROUPING SETS OPEN_PAREN group_by_list CLOSE_PAREN
;
having_clause
: HAVING a_expr
|
;
for_locking_clause
: for_locking_items
| FOR READ ONLY
;
opt_for_locking_clause
: for_locking_clause
|
;
for_locking_items
: for_locking_item+
;
for_locking_item
: for_locking_strength locked_rels_list opt_nowait_or_skip
;
for_locking_strength
: FOR ((NO KEY)? UPDATE | KEY? SHARE)
;
locked_rels_list
: OF qualified_name_list
|
;
values_clause
: VALUES OPEN_PAREN expr_list CLOSE_PAREN (COMMA OPEN_PAREN expr_list CLOSE_PAREN)*
;
from_clause
: FROM from_list
|
;
from_list
: non_ansi_join
| table_ref (COMMA table_ref)*
;
non_ansi_join
: table_ref (COMMA table_ref)+
;
table_ref
: (relation_expr opt_alias_clause tablesample_clause?
| func_table func_alias_clause
| xmltable opt_alias_clause
| select_with_parens opt_alias_clause
| LATERAL_P (
xmltable opt_alias_clause
| func_table func_alias_clause
| select_with_parens opt_alias_clause
)
| OPEN_PAREN table_ref (
CROSS JOIN table_ref
| NATURAL join_type? JOIN table_ref
| join_type? JOIN table_ref join_qual
)? CLOSE_PAREN opt_alias_clause
)
(CROSS JOIN table_ref | NATURAL join_type? JOIN table_ref | join_type? JOIN table_ref join_qual)*
;
alias_clause
: AS? colid (OPEN_PAREN name_list CLOSE_PAREN)?
;
opt_alias_clause
: table_alias_clause
|
;
table_alias_clause
: AS? table_alias (OPEN_PAREN name_list CLOSE_PAREN)?
;
func_alias_clause
: alias_clause
| (AS colid? | colid) OPEN_PAREN tablefuncelementlist CLOSE_PAREN
|
;
join_type
: (FULL | LEFT | RIGHT | INNER_P) OUTER_P?
;
join_qual
: USING OPEN_PAREN name_list CLOSE_PAREN
| ON a_expr
;
relation_expr
: qualified_name STAR?
| ONLY (qualified_name | OPEN_PAREN qualified_name CLOSE_PAREN)
;
relation_expr_list
: relation_expr (COMMA relation_expr)*
;
relation_expr_opt_alias
: relation_expr (AS? colid)?
;
tablesample_clause
: TABLESAMPLE func_name OPEN_PAREN expr_list CLOSE_PAREN opt_repeatable_clause
;
opt_repeatable_clause
: REPEATABLE OPEN_PAREN a_expr CLOSE_PAREN
|
;
func_table
: func_expr_windowless opt_ordinality
| ROWS FROM OPEN_PAREN rowsfrom_list CLOSE_PAREN opt_ordinality
;
rowsfrom_item
: func_expr_windowless opt_col_def_list
;
rowsfrom_list
: rowsfrom_item (COMMA rowsfrom_item)*
;
opt_col_def_list
: AS OPEN_PAREN tablefuncelementlist CLOSE_PAREN
|
;
//TODO WITH_LA was used
opt_ordinality
: WITH ORDINALITY
|
;
where_clause
: WHERE a_expr
|
;
where_or_current_clause
: WHERE (CURRENT_P OF cursor_name | a_expr)
|
;
opttablefuncelementlist
: tablefuncelementlist
|
;
tablefuncelementlist
: tablefuncelement (COMMA tablefuncelement)*
;
tablefuncelement
: colid typename opt_collate_clause
;
xmltable
: 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
;
xmltable_column_list
: xmltable_column_el (COMMA xmltable_column_el)*
;
xmltable_column_el
: colid (typename xmltable_column_option_list? | FOR ORDINALITY)
;
xmltable_column_option_list
: xmltable_column_option_el+
;
xmltable_column_option_el
: DEFAULT a_expr
| identifier a_expr
| NOT NULL_P
| NULL_P
;
xml_namespace_list
: xml_namespace_el (COMMA xml_namespace_el)*
;
xml_namespace_el
: b_expr AS collabel
| DEFAULT b_expr
;
typename
: SETOF? simpletypename (opt_array_bounds | ARRAY (OPEN_BRACKET iconst CLOSE_BRACKET)?)
| qualified_name PERCENT (ROWTYPE | TYPE_P)
;
opt_array_bounds
: (OPEN_BRACKET iconst? CLOSE_BRACKET)*
;
simpletypename
: generictype
| numeric
| bit
| character
| constdatetime
| constinterval (opt_interval | OPEN_PAREN iconst CLOSE_PAREN)
;
consttypename
: numeric
| constbit
| constcharacter
| constdatetime
;
generictype
: (builtin_function_name | type_function_name | LEFT | RIGHT) attrs? opt_type_modifiers
;
opt_type_modifiers
: OPEN_PAREN expr_list CLOSE_PAREN
|
;
numeric
: INT_P
| INTEGER
| SMALLINT
| BIGINT
| REAL
| FLOAT_P opt_float
| DOUBLE_P PRECISION
| DECIMAL_P opt_type_modifiers
| DEC opt_type_modifiers
| NUMERIC opt_type_modifiers
| BOOLEAN_P
;
opt_float
: OPEN_PAREN iconst CLOSE_PAREN
|
;
//todo: merge alts
bit
: bitwithlength
| bitwithoutlength
;
constbit
: bitwithlength
| bitwithoutlength
;
bitwithlength
: BIT opt_varying OPEN_PAREN expr_list CLOSE_PAREN
;
bitwithoutlength
: BIT opt_varying
;
character
: character_c (OPEN_PAREN iconst CLOSE_PAREN)?
;
constcharacter
: character_c (OPEN_PAREN iconst CLOSE_PAREN)?
;
character_c
: (CHARACTER | CHAR_P | NCHAR) opt_varying
| VARCHAR
| NATIONAL (CHARACTER | CHAR_P) opt_varying
;
opt_varying
: VARYING
|
;
constdatetime
: (TIMESTAMP | TIME) (OPEN_PAREN iconst CLOSE_PAREN)? opt_timezone
;
constinterval
: INTERVAL
;
//TODO with_la was used
opt_timezone
: WITH TIME ZONE
| WITHOUT TIME ZONE
|
;
opt_interval
: YEAR_P
| MONTH_P
| DAY_P
| HOUR_P
| MINUTE_P
| interval_second
| YEAR_P TO MONTH_P
| DAY_P TO (HOUR_P | MINUTE_P | interval_second)
| HOUR_P TO (MINUTE_P | interval_second)
| MINUTE_P TO interval_second
|
;
interval_second
: SECOND_P (OPEN_PAREN iconst CLOSE_PAREN)?
;
opt_escape
: ESCAPE a_expr
|
;
//precendence accroding to Table 4.2. Operator Precedence (highest to lowest)
//https://www.postgresql.org/docs/12/sql-syntax-lexical.html#SQL-PRECEDENCE
/*
original version of a_expr, for info
a_expr: c_expr
//:: left PostgreSQL-style typecast
| a_expr TYPECAST typename -- 1
| a_expr COLLATE any_name -- 2
| a_expr AT TIME ZONE a_expr-- 3
//right unary plus, unary minus
| (PLUS| MINUS) a_expr -- 4
//left exponentiation
| a_expr CARET a_expr -- 5
//left multiplication, division, modulo
| a_expr (STAR | SLASH | PERCENT) a_expr -- 6
//left addition, subtraction
| a_expr (PLUS | MINUS) a_expr -- 7
//left all other native and user-defined operators
| a_expr qual_op a_expr -- 8
| qual_op a_expr -- 9
//range containment, set membership, string matching BETWEEN IN LIKE ILIKE SIMILAR
| a_expr NOT? (LIKE|ILIKE|SIMILAR TO|(BETWEEN SYMMETRIC?)) a_expr opt_escape -- 10
//< > = <= >= <> comparison operators
| a_expr (LT | GT | EQUAL | LESS_EQUALS | GREATER_EQUALS | NOT_EQUALS) a_expr -- 11
//IS ISNULL NOTNULL IS TRUE, IS FALSE, IS NULL, IS DISTINCT FROM, etc
| a_expr 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
) -- 12
| a_expr (ISNULL|NOTNULL) -- 13
| row OVERLAPS row -- 14
//NOT right logical negation
| NOT a_expr -- 15
//AND left logical conjunction
| a_expr AND a_expr -- 16
//OR left logical disjunction
| a_expr OR a_expr -- 17
| a_expr (LESS_LESS|GREATER_GREATER) a_expr -- 18
| a_expr qual_op -- 19
| a_expr NOT? IN_P in_expr -- 20
| a_expr subquery_Op sub_type (select_with_parens|OPEN_PAREN a_expr CLOSE_PAREN) -- 21
| UNIQUE select_with_parens -- 22
| DEFAULT -- 23
;
*/
a_expr
: a_expr_qual
;
/*23*/
/*moved to c_expr*/
/*22*/
/*moved to c_expr*/
/*19*/
a_expr_qual
: a_expr_lessless qual_op?
;
/*18*/
a_expr_lessless
: a_expr_or ((LESS_LESS | GREATER_GREATER) a_expr_or)*
;
/*17*/
a_expr_or
: a_expr_and (OR a_expr_and)*
;
/*16*/
a_expr_and
: a_expr_between (AND a_expr_between)*
;
/*21*/
a_expr_between
: a_expr_in (NOT? BETWEEN SYMMETRIC? a_expr_in AND a_expr_in)?
;
/*20*/
a_expr_in
: a_expr_unary_not (NOT? IN_P in_expr)?
;
/*15*/
a_expr_unary_not
: NOT? a_expr_isnull
;
/*14*/
/*moved to c_expr*/
/*13*/
a_expr_isnull
: a_expr_is_not (ISNULL | NOTNULL)?
;
/*12*/
a_expr_is_not
: 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))?
;
/*11*/
a_expr_compare
: 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*/
)?
;
/*10*/
a_expr_like
: a_expr_qual_op (NOT? (LIKE | ILIKE | SIMILAR TO) a_expr_qual_op opt_escape)?
;
/* 8*/
a_expr_qual_op
: a_expr_unary_qualop (qual_op a_expr_unary_qualop)*
;
/* 9*/
a_expr_unary_qualop
: qual_op? a_expr_add
;
/* 7*/
a_expr_add
: a_expr_mul ((MINUS | PLUS) a_expr_mul)*
;
/* 6*/
a_expr_mul
: a_expr_caret ((STAR | SLASH | PERCENT) a_expr_caret)*
;
/* 5*/
a_expr_caret
: a_expr_unary_sign (CARET a_expr)?
;
/* 4*/
a_expr_unary_sign
: (MINUS | PLUS)? a_expr_at_time_zone /* */
;
/* 3*/
a_expr_at_time_zone
: a_expr_collate (AT TIME ZONE a_expr)?
;
/* 2*/
a_expr_collate
: a_expr_typecast (COLLATE any_name)?
;
/* 1*/
a_expr_typecast
: c_expr (TYPECAST typename)*
;
b_expr
: c_expr
| b_expr TYPECAST typename
//right unary plus, unary minus
| (PLUS | MINUS) b_expr
//^ left exponentiation
| b_expr CARET b_expr
//* / % left multiplication, division, modulo
| b_expr (STAR | SLASH | PERCENT) b_expr
//+ - left addition, subtraction
| b_expr (PLUS | MINUS) b_expr
//(any other operator) left all other native and user-defined operators
| b_expr qual_op b_expr
//< > = <= >= <> comparison operators
| b_expr (LT | GT | EQUAL | LESS_EQUALS | GREATER_EQUALS | NOT_EQUALS) b_expr
| qual_op b_expr
| b_expr qual_op
//S ISNULL NOTNULL IS TRUE, IS FALSE, IS NULL, IS DISTINCT FROM, etc
| b_expr IS NOT? (DISTINCT FROM b_expr | OF OPEN_PAREN type_list CLOSE_PAREN | DOCUMENT_P)
;
c_expr
: EXISTS select_with_parens # c_expr_exists
| ARRAY (select_with_parens | array_expr) # c_expr_expr
| PARAM opt_indirection # c_expr_expr
| GROUPING OPEN_PAREN expr_list CLOSE_PAREN # c_expr_expr
| /*22*/
UNIQUE select_with_parens # c_expr_expr
| columnref # c_expr_expr
| aexprconst # c_expr_expr
| plsqlvariablename # c_expr_expr
| OPEN_PAREN a_expr_in_parens = a_expr CLOSE_PAREN opt_indirection # c_expr_expr
| case_expr # c_expr_case
| func_expr # c_expr_expr
| select_with_parens indirection? # c_expr_expr
| explicit_row # c_expr_expr
| implicit_row # c_expr_expr
| row OVERLAPS row /* 14*/
# c_expr_expr
;
plsqlvariablename
: PLSQLVARIABLENAME
;
func_application
: 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
;
func_expr
: func_application within_group_clause filter_clause over_clause
| func_expr_common_subexpr
;
func_expr_windowless
: func_application
| func_expr_common_subexpr
;
func_expr_common_subexpr
: COLLATION FOR OPEN_PAREN a_expr CLOSE_PAREN
| CURRENT_DATE
| CURRENT_TIME (OPEN_PAREN iconst CLOSE_PAREN)?
| CURRENT_TIMESTAMP (OPEN_PAREN iconst CLOSE_PAREN)?
| LOCALTIME (OPEN_PAREN iconst CLOSE_PAREN)?
| LOCALTIMESTAMP (OPEN_PAREN iconst CLOSE_PAREN)?
| CURRENT_ROLE
| CURRENT_USER
| SESSION_USER
| USER
| CURRENT_CATALOG
| CURRENT_SCHEMA
| CAST OPEN_PAREN a_expr AS typename CLOSE_PAREN
| EXTRACT OPEN_PAREN extract_list CLOSE_PAREN
| NORMALIZE OPEN_PAREN a_expr (COMMA unicode_normal_form)? CLOSE_PAREN
| OVERLAY OPEN_PAREN overlay_list CLOSE_PAREN
| POSITION OPEN_PAREN position_list CLOSE_PAREN
| SUBSTRING OPEN_PAREN substr_list CLOSE_PAREN
| TREAT OPEN_PAREN a_expr AS typename CLOSE_PAREN
| TRIM OPEN_PAREN (BOTH | LEADING | TRAILING)? trim_list CLOSE_PAREN
| NULLIF OPEN_PAREN a_expr COMMA a_expr CLOSE_PAREN
| COALESCE OPEN_PAREN expr_list CLOSE_PAREN
| GREATEST OPEN_PAREN expr_list CLOSE_PAREN
| LEAST OPEN_PAREN expr_list CLOSE_PAREN
| XMLCONCAT OPEN_PAREN expr_list CLOSE_PAREN
| XMLELEMENT OPEN_PAREN NAME_P collabel (COMMA (xml_attributes | expr_list))? CLOSE_PAREN
| XMLEXISTS OPEN_PAREN c_expr xmlexists_argument CLOSE_PAREN
| XMLFOREST OPEN_PAREN xml_attribute_list CLOSE_PAREN
| XMLPARSE OPEN_PAREN document_or_content a_expr xml_whitespace_option CLOSE_PAREN
| XMLPI OPEN_PAREN NAME_P collabel (COMMA a_expr)? CLOSE_PAREN
| XMLROOT OPEN_PAREN XML_P a_expr COMMA xml_root_version opt_xml_root_standalone CLOSE_PAREN
| XMLSERIALIZE OPEN_PAREN document_or_content a_expr AS simpletypename CLOSE_PAREN
;
xml_root_version
: VERSION_P a_expr
| VERSION_P NO VALUE_P
;
opt_xml_root_standalone
: COMMA STANDALONE_P YES_P
| COMMA STANDALONE_P NO
| COMMA STANDALONE_P NO VALUE_P
|
;
xml_attributes
: XMLATTRIBUTES OPEN_PAREN xml_attribute_list CLOSE_PAREN
;
xml_attribute_list
: xml_attribute_el (COMMA xml_attribute_el)*
;
xml_attribute_el
: a_expr (AS collabel)?
;
document_or_content
: DOCUMENT_P
| CONTENT_P
;
xml_whitespace_option
: PRESERVE WHITESPACE_P
| STRIP_P WHITESPACE_P
|
;
xmlexists_argument
: PASSING c_expr
| PASSING c_expr xml_passing_mech
| PASSING xml_passing_mech c_expr
| PASSING xml_passing_mech c_expr xml_passing_mech
;
xml_passing_mech
: BY (REF | VALUE_P)
;
within_group_clause
: WITHIN GROUP_P OPEN_PAREN sort_clause CLOSE_PAREN
|
;
filter_clause
: FILTER OPEN_PAREN WHERE a_expr CLOSE_PAREN
|
;
window_clause
: WINDOW window_definition_list
|
;
window_definition_list
: window_definition (COMMA window_definition)*
;
window_definition
: colid AS window_specification
;
over_clause
: OVER (window_specification | colid)
|
;
window_specification
: OPEN_PAREN opt_existing_window_name opt_partition_clause opt_sort_clause opt_frame_clause CLOSE_PAREN
;
opt_existing_window_name
: colid
|
;
opt_partition_clause
: PARTITION BY expr_list
|
;
opt_frame_clause
: RANGE frame_extent opt_window_exclusion_clause
| ROWS frame_extent opt_window_exclusion_clause
| GROUPS frame_extent opt_window_exclusion_clause
|
;
frame_extent
: frame_bound
| BETWEEN frame_bound AND frame_bound
;
frame_bound
: UNBOUNDED (PRECEDING | FOLLOWING)
| CURRENT_P ROW
| a_expr (PRECEDING | FOLLOWING)
;
opt_window_exclusion_clause
: EXCLUDE (CURRENT_P ROW | GROUP_P | TIES | NO OTHERS)
|
;
row
: ROW OPEN_PAREN expr_list? CLOSE_PAREN
| OPEN_PAREN expr_list COMMA a_expr CLOSE_PAREN
;
explicit_row
: ROW OPEN_PAREN expr_list? CLOSE_PAREN
;
/*
TODO:
for some reason v1
implicit_row: OPEN_PAREN expr_list COMMA a_expr CLOSE_PAREN;
works better than v2
implicit_row: OPEN_PAREN expr_list CLOSE_PAREN;
while looks like they are almost the same, except v2 requieres at least 2 items in list
while v1 allows single item in list
*/
implicit_row
: OPEN_PAREN expr_list COMMA a_expr CLOSE_PAREN
;
sub_type
: ANY
| SOME
| ALL
;
all_op
: Operator
| mathop
;
mathop
: PLUS
| MINUS
| STAR
| SLASH
| PERCENT
| CARET
| LT
| GT
| EQUAL
| LESS_EQUALS
| GREATER_EQUALS
| NOT_EQUALS
;
qual_op
: Operator
| OPERATOR OPEN_PAREN any_operator CLOSE_PAREN
;
qual_all_op
: all_op
| OPERATOR OPEN_PAREN any_operator CLOSE_PAREN
;
subquery_Op
: all_op
| OPERATOR OPEN_PAREN any_operator CLOSE_PAREN
| LIKE
| NOT LIKE
| ILIKE
| NOT ILIKE
;
expr_list
: a_expr (COMMA a_expr)*
;
func_arg_list
: func_arg_expr (COMMA func_arg_expr)*
;
func_arg_expr
: a_expr
| param_name (COLON_EQUALS | EQUALS_GREATER) a_expr
;
type_list
: typename (COMMA typename)*
;
array_expr
: OPEN_BRACKET (expr_list | array_expr_list)? CLOSE_BRACKET
;
array_expr_list
: array_expr (COMMA array_expr)*
;
extract_list
: extract_arg FROM a_expr
|
;
extract_arg
: identifier
| YEAR_P
| MONTH_P
| DAY_P
| HOUR_P
| MINUTE_P
| SECOND_P
| sconst
;
unicode_normal_form
: NFC
| NFD
| NFKC
| NFKD
;
overlay_list
: a_expr PLACING a_expr FROM a_expr (FOR a_expr)?
;
position_list
: b_expr IN_P b_expr
|
;
substr_list
: a_expr FROM a_expr FOR a_expr
| a_expr FOR a_expr FROM a_expr
| a_expr FROM a_expr
| a_expr FOR a_expr
| a_expr SIMILAR a_expr ESCAPE a_expr
| expr_list
;
trim_list
: a_expr FROM expr_list
| FROM expr_list
| expr_list
;
in_expr
: select_with_parens # in_expr_select
| OPEN_PAREN expr_list CLOSE_PAREN # in_expr_list
;
case_expr
: CASE case_arg when_clause_list case_default END_P
;
when_clause_list
: when_clause+
;
when_clause
: WHEN a_expr THEN a_expr
;
case_default
: ELSE a_expr
|
;
case_arg
: a_expr
|
;
columnref
: colid indirection?
;
indirection_el
: DOT (attr_name | STAR)
| OPEN_BRACKET (a_expr | opt_slice_bound COLON opt_slice_bound) CLOSE_BRACKET
;
opt_slice_bound
: a_expr
|
;
indirection
: indirection_el+
;
opt_indirection
: indirection_el*
;
opt_target_list
: target_list
|
;
target_list
: target_el (COMMA target_el)*
;
target_el
: a_expr (AS collabel | identifier |) # target_label
| STAR # target_star
;
qualified_name_list
: qualified_name (COMMA qualified_name)*
;
qualified_name
: colid indirection?
;
name_list
: name (COMMA name)*
;
name
: colid
;
attr_name
: collabel
;
file_name
: sconst
;
func_name
: builtin_function_name
| type_function_name
| colid indirection
| LEFT
| RIGHT
;
aexprconst
: iconst
| fconst
| sconst
| bconst
| xconst
| func_name (sconst | OPEN_PAREN func_arg_list opt_sort_clause CLOSE_PAREN sconst)
| consttypename sconst
| constinterval (sconst opt_interval | OPEN_PAREN iconst CLOSE_PAREN sconst)
| TRUE_P
| FALSE_P
| NULL_P
;
xconst
: HexadecimalStringConstant
;
bconst
: BinaryStringConstant
;
fconst
: Numeric
;
iconst
: Integral
;
sconst
: anysconst opt_uescape
;
anysconst
: StringConstant
| UnicodeEscapeStringConstant
| BeginDollarStringConstant DollarText* EndDollarStringConstant
| EscapeStringConstant
;
opt_uescape
: UESCAPE anysconst
|
;
signediconst
: iconst
| PLUS iconst
| MINUS iconst
;
roleid
: rolespec
;
rolespec
: nonreservedword
| CURRENT_USER
| SESSION_USER
;
role_list
: rolespec (COMMA rolespec)*
;
colid
: identifier
| unreserved_keyword
| col_name_keyword
| plsql_unreserved_keyword
| LEFT
| RIGHT
;
table_alias
: identifier
| unreserved_keyword
| col_name_keyword
| plsql_unreserved_keyword
;
type_function_name
: identifier
| unreserved_keyword
| plsql_unreserved_keyword
| type_func_name_keyword
;
nonreservedword
: identifier
| unreserved_keyword
| col_name_keyword
| type_func_name_keyword
;
collabel
: identifier
| plsql_unreserved_keyword
| unreserved_keyword
| col_name_keyword
| type_func_name_keyword
| reserved_keyword
;
identifier
: Identifier opt_uescape
| QuotedIdentifier
| UnicodeQuotedIdentifier
| plsqlvariablename
| plsqlidentifier
| plsql_unreserved_keyword
;
plsqlidentifier
: PLSQLIDENTIFIER
;
unreserved_keyword
: ABORT_P
| ABSOLUTE_P
| ACCESS
| ACTION
| ADD_P
| ADMIN
| AFTER
| AGGREGATE
| ALSO
| ALTER
| ALWAYS
| ASSERTION
| ASSIGNMENT
| AT
| ATTACH
| ATTRIBUTE
| BACKWARD
| BEFORE
| BEGIN_P
| BY
| CACHE
| CALL
| CALLED
| CASCADE
| CASCADED
| CATALOG
| CHAIN
| CHARACTERISTICS
| CHECKPOINT
| CLASS
| CLOSE
| CLUSTER
| COLUMNS
| COMMENT
| COMMENTS
| COMMIT
| COMMITTED
| CONFIGURATION
| CONFLICT
| CONNECTION
| CONSTRAINTS
| CONTENT_P
| CONTINUE_P
| CONVERSION_P
| COPY
| COST
| CSV
| CUBE
| CURRENT_P
| CURSOR
| CYCLE
| DATA_P
| DATABASE
| DAY_P
| DEALLOCATE
| DECLARE
| DEFAULTS
| DEFERRED
| DEFINER
| DELETE_P
| DELIMITER
| DELIMITERS
| DEPENDS
| DETACH
| DICTIONARY
| DISABLE_P
| DISCARD
| DOCUMENT_P
| DOMAIN_P
| DOUBLE_P
| DROP
| EACH
| ENABLE_P
| ENCODING
| ENCRYPTED
| ENUM_P
| ESCAPE
| EVENT
| EXCLUDE
| EXCLUDING
| EXCLUSIVE
| EXECUTE
| EXPLAIN
| EXPRESSION
| EXTENSION
| EXTERNAL
| FAMILY
| FILTER
| FIRST_P
| FOLLOWING
| FORCE
| FORWARD
| FUNCTION
| FUNCTIONS
| GENERATED
| GLOBAL
| GRANTED
| GROUPS
| HANDLER
| HEADER_P
| HOLD
| HOUR_P
| IDENTITY_P
| IF_P
| IMMEDIATE
| IMMUTABLE
| IMPLICIT_P
| IMPORT_P
| INCLUDE
| INCLUDING
| INCREMENT
| INDEX
| INDEXES
| INHERIT
| INHERITS
| INLINE_P
| INPUT_P
| INSENSITIVE
| INSERT
| INSTEAD
| INVOKER
| ISOLATION
| KEY
| LABEL
| LANGUAGE
| LARGE_P
| LAST_P
| LEAKPROOF
| SHIPPABLE
| FENCED
| PACKAGE
| LEVEL
| LISTEN
| LOAD
| LOCAL
| LOCATION
| LOCK_P
| LOCKED
| LOGGED
| MAPPING
| MATCH
| MATERIALIZED
| MAXVALUE
| METHOD
| MINUTE_P
| MINVALUE
| MODE
| MONTH_P
| MOVE
| NAME_P
| NAMES
| NEW
| NEXT
| NFC
| NFD
| NFKC
| NFKD
| NO
| NORMALIZED
| NOTHING
| NOTIFY
| NOWAIT
| NULLS_P
| OBJECT_P
| OF
| OFF
| OIDS
| OLD
| OPERATOR
| OPTION
| OPTIONS
| ORDINALITY
| OTHERS
| OVER
| OVERRIDING
| OWNED
| OWNER
| PARALLEL
| PARSER
| PARTIAL
| PARTITION
| PASSING
| PASSWORD
| PLANS
| POLICY
| PRECEDING
| PREPARE
| PREPARED
| PRESERVE
| PRIOR
| PRIVILEGES
| PROCEDURAL
| PROCEDURE
| PROCEDURES
| PROGRAM
| PUBLICATION
| QUOTE
| RANGE
| READ
| REASSIGN
| RECHECK
| RECURSIVE
| REF
| REFERENCING
| REFRESH
| REINDEX
| RELATIVE_P
| RELEASE
| RENAME
| REPEATABLE
| REPLICA
| RESET
| RESTART
| RESTRICT
| RETURNS
| REVOKE
| ROLE
| ROLLBACK
| ROLLUP
| ROUTINE
| ROUTINES
| ROWS
| RULE
| SAVEPOINT
| SCHEMA
| SCHEMAS
| SCROLL
| SEARCH
| SECOND_P
| SECURITY
| SEQUENCE
| SEQUENCES
| SERIALIZABLE
| SERVER
| SESSION
| SET
| SETS
| SHARE
| SHOW
| SIMPLE
| SKIP_P
| SNAPSHOT
| SQL_P
| STABLE
| STANDALONE_P
| START
| STATEMENT
| STATISTICS
| STDIN
| STDOUT
| STORAGE
| STORED
| STRICT_P
| STRIP_P
| SUBSCRIPTION
| SUPPORT
| SYSID
| SYSTEM_P
| TABLES
| TABLESPACE
| TEMP
| TEMPLATE
| TEMPORARY
| TEXT_P
| TIES
| TRANSACTION
| TRANSFORM
| TRIGGER
| TRUNCATE
| TRUSTED
| TYPE_P
| TYPES_P
| UESCAPE
| UNBOUNDED
| UNCOMMITTED
| UNENCRYPTED
| UNKNOWN
| UNLISTEN
| UNLOGGED
| UNTIL
| UPDATE
| VACUUM
| VALID
| VALIDATE
| VALIDATOR
| VALUE_P
| VARYING
| VERSION_P
| VIEW
| VIEWS
| VOLATILE
| WHITESPACE_P
| WITHIN
| WITHOUT
| WORK
| WRAPPER
| WRITE
| XML_P
| YEAR_P
| YES_P
| ZONE
;
col_name_keyword
: BETWEEN
| BIGINT
| bit
| BOOLEAN_P
| CHAR_P
| character
| COALESCE
| DEC
| DECIMAL_P
| EXISTS
| EXTRACT
| FLOAT_P
| GREATEST
| GROUPING
| INOUT
| INT_P
| INTEGER
| INTERVAL
| LEAST
| NATIONAL
| NCHAR
| NONE
| NORMALIZE
| NULLIF
| numeric
| OUT_P
| OVERLAY
| POSITION
| PRECISION
| REAL
| ROW
| SETOF
| SMALLINT
| SUBSTRING
| TIME
| TIMESTAMP
| TREAT
| TRIM
| VALUES
| VARCHAR
| XMLATTRIBUTES
| XMLCONCAT
| XMLELEMENT
| XMLEXISTS
| XMLFOREST
| XMLNAMESPACES
| XMLPARSE
| XMLPI
| XMLROOT
| XMLSERIALIZE
| XMLTABLE
| builtin_function_name
;
type_func_name_keyword
: AUTHORIZATION
| BINARY
| COLLATION
| CONCURRENTLY
| CROSS
| CURRENT_SCHEMA
| FREEZE
| FULL
| ILIKE
| INNER_P
| IS
| ISNULL
| JOIN
| LIKE
| NATURAL
| NOTNULL
| OUTER_P
| OVERLAPS
| SIMILAR
| TABLESAMPLE
| VERBOSE
;
reserved_keyword
: ALL
| ANALYSE
| ANALYZE
| AND
| ANY
| ARRAY
| AS
| ASC
| ASYMMETRIC
| BOTH
| CASE
| CAST
| CHECK
| COLLATE
| COLUMN
| CONSTRAINT
| CREATE
| CURRENT_CATALOG
| CURRENT_DATE
| CURRENT_ROLE
| CURRENT_TIME
| CURRENT_TIMESTAMP
| CURRENT_USER
// | DEFAULT
| DEFERRABLE
| DESC
| DISTINCT
| DO
| ELSE
| END_P
| EXCEPT
| FALSE_P
| FETCH
| FOR
| FOREIGN
| FROM
| GRANT
| GROUP_P
| HAVING
| IN_P
| INITIALLY
| INTERSECT
/*
from pl_gram.y, line ~2982
* Fortunately, INTO is a fully reserved word in the main grammar, so
* at least we need not worry about it appearing as an identifier.
*/
// | INTO
| LATERAL_P
| LEADING
| LIMIT
| LOCALTIME
| LOCALTIMESTAMP
| NOT
| NULL_P
| OFFSET
| ON
| ONLY
| OR
| ORDER
| PLACING
| PRIMARY
| REFERENCES
| RETURNING
| SELECT
| SESSION_USER
| SOME
| SYMMETRIC
| TABLE
| THEN
| TO
| TRAILING
| TRUE_P
| UNION
| UNIQUE
| USER
| USING
| VARIADIC
| WHEN
| WHERE
| WINDOW
| WITH
;
builtin_function_name
: XMLCOMMENT
| XML_IS_WELL_FORMED
| XML_IS_WELL_FORMED_DOCUMENT
| XML_IS_WELL_FORMED_CONTENT
| XMLAGG
| XPATH
| XPATH_EXISTS
| ABS
| CBRT
| CEIL
| CEILING
| DEGREES
| DIV
| EXP
| FACTORIAL
| FLOOR
| GCD
| LCM
| LN
| LOG
| LOG10
| MIN_SCALE
| MOD
| PI
| POWER
| RADIANS
| ROUND
| SCALE
| SIGN
| SQRT
| TRIM_SCALE
| TRUNC
| WIDTH_BUCKET
| RANDOM
| SETSEED
| ACOS
| ACOSD
| ACOSH
| ASIN
| ASIND
| ASINH
| ATAN
| ATAND
| ATANH
| ATAN2
| ATAN2D
| COS
| COSD
| COSH
| COT
| COTD
| SIN
| SIND
| SINH
| TAN
| TAND
| TANH
| BIT_LENGTH
| CHAR_LENGTH
| CHARACTER_LENGTH
| LOWER
| OCTET_LENGTH
| OCTET_LENGTH
| UPPER
| ASCII
| BTRIM
| CHR
| CONCAT
| CONCAT_WS
| FORMAT
| INITCAP
| LENGTH
| LPAD
| LTRIM
| MD5
| PARSE_IDENT
| PG_CLIENT_ENCODING
| QUOTE_IDENT
| QUOTE_LITERAL
| QUOTE_NULLABLE
| REGEXP_COUNT
| REGEXP_INSTR
| REGEXP_LIKE
| REGEXP_MATCH
| REGEXP_MATCHES
| REGEXP_REPLACE
| REGEXP_SPLIT_TO_ARRAY
| REGEXP_SPLIT_TO_TABLE
| REGEXP_SUBSTR
| REPEAT
| REPLACE
| REVERSE
| RPAD
| RTRIM
| SPLIT_PART
| STARTS_WITH
| STRING_TO_ARRAY
| STRING_TO_TABLE
| STRPOS
| SUBSTR
| TO_ASCII
| TO_HEX
| TRANSLATE
| UNISTR
| AGE
| DATE_BIN
| DATE_PART
| DATE_TRUNC
| ISFINITE
| JUSTIFY_DAYS
| JUSTIFY_HOURS
| JUSTIFY_INTERVAL
| MAKE_DATE
| MAKE_INTERVAL
| MAKE_TIME
| MAKE_TIMESTAMP
| MAKE_TIMESTAMPTZ
| CLOCK_TIMESTAMP
| NOW
| STATEMENT_TIMESTAMP
| TIMEOFDAY
| TRANSACTION_TIMESTAMP
| TO_TIMESTAMP
| JUSTIFY_INTERVAL
| JUSTIFY_INTERVAL
| TO_CHAR
| TO_DATE
| TO_NUMBER
;
/************************************************************************************************************************************************************/
/*PL/SQL GRAMMAR */
/*PLSQL grammar */
/************************************************************************************************************************************************************/
pl_function
: comp_options pl_block opt_semi
;
comp_options
: comp_option*
;
comp_option
: sharp OPTION DUMP
| sharp PRINT_STRICT_PARAMS option_value
| sharp VARIABLE_CONFLICT ERROR
| sharp VARIABLE_CONFLICT USE_VARIABLE
| sharp VARIABLE_CONFLICT USE_COLUMN
;
sharp
: Operator
;
option_value
: sconst
| reserved_keyword
| plsql_unreserved_keyword
| unreserved_keyword
;
opt_semi
:
| SEMI
;
// exception_sect means opt_exception_sect in original grammar, don't be confused!
pl_block
: decl_sect BEGIN_P proc_sect exception_sect END_P opt_label
;
decl_sect
: opt_block_label (decl_start decl_stmts?)?
;
decl_start
: DECLARE
;
decl_stmts
: decl_stmt+
;
label_decl
: LESS_LESS any_identifier GREATER_GREATER
;
decl_stmt
: decl_statement
| DECLARE
| label_decl
;
decl_statement
: decl_varname
(
ALIAS FOR decl_aliasitem
| decl_const decl_datatype decl_collate decl_notnull decl_defval
| opt_scrollable CURSOR decl_cursor_args decl_is_for decl_cursor_query
) SEMI
;
opt_scrollable
:
| NO SCROLL
| SCROLL
;
decl_cursor_query
: selectstmt
;
decl_cursor_args
:
| OPEN_PAREN decl_cursor_arglist CLOSE_PAREN
;
decl_cursor_arglist
: decl_cursor_arg (COMMA decl_cursor_arg)*
;
decl_cursor_arg
: decl_varname decl_datatype
;
decl_is_for
: IS
| FOR
;
decl_aliasitem
: PARAM
| colid
;
decl_varname
: any_identifier
;
decl_const
:
| CONSTANT
;
decl_datatype
: typename
; //TODO: $$ = read_datatype(yychar);
decl_collate
:
| COLLATE any_name
;
decl_notnull
:
| NOT NULL_P
;
decl_defval
:
| decl_defkey sql_expression
;
decl_defkey
: assign_operator
| DEFAULT
;
assign_operator
: EQUAL
| COLON_EQUALS
;
proc_sect
: proc_stmt*
;
proc_stmt
: pl_block SEMI
| stmt_return
| stmt_raise
| stmt_assign
| stmt_if
| stmt_case
| stmt_loop
| stmt_while
| stmt_for
| stmt_foreach_a
| stmt_exit
| stmt_assert
| stmt_execsql
| stmt_dynexecute
| stmt_perform
| stmt_call
| stmt_getdiag
| stmt_open
| stmt_fetch
| stmt_move
| stmt_close
| stmt_null
| stmt_commit
| stmt_rollback
| stmt_set
;
stmt_perform
: PERFORM expr_until_semi SEMI
;
stmt_call
: CALL any_identifier OPEN_PAREN opt_expr_list CLOSE_PAREN SEMI
| DO any_identifier OPEN_PAREN opt_expr_list CLOSE_PAREN SEMI
;
opt_expr_list
:
| expr_list
;
stmt_assign
: assign_var assign_operator sql_expression SEMI
;
stmt_getdiag
: GET getdiag_area_opt DIAGNOSTICS getdiag_list SEMI
;
getdiag_area_opt
:
| CURRENT_P
| STACKED
;
getdiag_list
: getdiag_list_item (COMMA getdiag_list_item)*
;
getdiag_list_item
: getdiag_target assign_operator getdiag_item
;
getdiag_item
: colid
;
getdiag_target
: assign_var
;
assign_var
: (any_name | PARAM) (OPEN_BRACKET expr_until_rightbracket CLOSE_BRACKET)*
;
stmt_if
: IF_P expr_until_then THEN proc_sect stmt_elsifs stmt_else END_P IF_P SEMI
;
stmt_elsifs
: (ELSIF a_expr THEN proc_sect)*
;
stmt_else
:
| ELSE proc_sect
;
stmt_case
: CASE opt_expr_until_when case_when_list opt_case_else END_P CASE SEMI
;
opt_expr_until_when
:
| sql_expression
;
case_when_list
: case_when+
;
case_when
: WHEN expr_list THEN proc_sect
;
opt_case_else
:
| ELSE proc_sect
;
stmt_loop
: opt_loop_label loop_body
;
stmt_while
: opt_loop_label WHILE expr_until_loop loop_body
;
stmt_for
: opt_loop_label FOR for_control loop_body
;
//TODO: rewrite using read_sql_expression logic?
for_control
: for_variable IN_P
(
cursor_name opt_cursor_parameters
| selectstmt
| explainstmt
| EXECUTE a_expr opt_for_using_expression
| opt_reverse a_expr DOT_DOT a_expr opt_by_expression
)
;
opt_for_using_expression
:
| USING expr_list
;
opt_cursor_parameters
:
| OPEN_PAREN a_expr (COMMA a_expr)* CLOSE_PAREN
;
opt_reverse
:
| REVERSE
;
opt_by_expression
:
| BY a_expr
;
for_variable
: any_name_list
;
stmt_foreach_a
: opt_loop_label FOREACH for_variable foreach_slice IN_P ARRAY a_expr loop_body
;
foreach_slice
:
| SLICE iconst
;
stmt_exit
: exit_type opt_label opt_exitcond SEMI
;
exit_type
: EXIT
| CONTINUE_P
;
//todo implement RETURN statement according to initial grammar line 1754
stmt_return
: RETURN (NEXT sql_expression | QUERY (EXECUTE a_expr opt_for_using_expression | selectstmt) | opt_return_result) SEMI
;
opt_return_result
:
| sql_expression
;
//https://www.postgresql.org/docs/current/plpgsql-errors-and-messages.html
//RAISE [ level ] 'format' [, expression [, ... ]] [ USING option = expression [, ... ] ];
//RAISE [ level ] condition_name [ USING option = expression [, ... ] ];
//RAISE [ level ] SQLSTATE 'sqlstate' [ USING option = expression [, ... ] ];
//RAISE [ level ] USING option = expression [, ... ];
//RAISE ;
stmt_raise
: RAISE opt_stmt_raise_level sconst opt_raise_list opt_raise_using SEMI
| RAISE opt_stmt_raise_level identifier opt_raise_using SEMI
| RAISE opt_stmt_raise_level SQLSTATE sconst opt_raise_using SEMI
| RAISE opt_stmt_raise_level opt_raise_using SEMI
| RAISE
;
opt_stmt_raise_level
:
|
| DEBUG
| LOG
| INFO
| NOTICE
| WARNING
| EXCEPTION
;
opt_raise_list
:
| (COMMA a_expr)+
;
opt_raise_using
:
| USING opt_raise_using_elem_list
;
opt_raise_using_elem
: identifier EQUAL a_expr
;
opt_raise_using_elem_list
: opt_raise_using_elem (COMMA opt_raise_using_elem)*
;
//todo imnplement
stmt_assert
: ASSERT sql_expression opt_stmt_assert_message SEMI
;
opt_stmt_assert_message
:
| COMMA sql_expression
;
loop_body
: LOOP proc_sect END_P LOOP opt_label SEMI
;
//TODO: looks like all other statements like INSERT/SELECT/UPDATE/DELETE are handled here;
//pls take a look at original grammar
stmt_execsql
: make_execsql_stmt SEMI
/*K_IMPORT
| K_INSERT
| t_word
| t_cword
*/
;
//https://www.postgresql.org/docs/current/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-NORESULT
//EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];
stmt_dynexecute
: EXECUTE a_expr (
/*this is silly, but i have to time to find nice way to code */
opt_execute_into opt_execute_using | opt_execute_using opt_execute_into |) SEMI
;
opt_execute_using
:
| USING opt_execute_using_list
;
opt_execute_using_list
: a_expr (COMMA a_expr)*
;
opt_execute_into
:
| INTO STRICT_P? into_target
;
//https://www.postgresql.org/docs/current/plpgsql-cursors.html#PLPGSQL-CURSOR-OPENING
//OPEN unbound_cursorvar [ [ NO ] SCROLL ] FOR query;
//OPEN unbound_cursorvar [ [ NO ] SCROLL ] FOR EXECUTE query_string
// [ USING expression [, ... ] ];
//OPEN bound_cursorvar [ ( [ argument_name := ] argument_value [, ...] ) ];
stmt_open
: OPEN
(
cursor_variable opt_scroll_option FOR (selectstmt | EXECUTE sql_expression opt_open_using)
| colid (OPEN_PAREN opt_open_bound_list CLOSE_PAREN)?
) SEMI
;
opt_open_bound_list_item
: colid COLON_EQUALS a_expr
| a_expr
;
opt_open_bound_list
: opt_open_bound_list_item (COMMA opt_open_bound_list_item)*
;
opt_open_using
:
| USING expr_list
;
opt_scroll_option
:
| opt_scroll_option_no SCROLL
;
opt_scroll_option_no
:
| NO
;
//https://www.postgresql.org/docs/current/plpgsql-cursors.html#PLPGSQL-CURSOR-OPENING
//FETCH [ direction { FROM | IN } ] cursor INTO target;
stmt_fetch
: FETCH direction = opt_fetch_direction opt_cursor_from cursor_variable INTO into_target SEMI
;
into_target
: expr_list
;
opt_cursor_from
:
| FROM
| IN_P
;
opt_fetch_direction
:
|
| NEXT
| PRIOR
| FIRST_P
| LAST_P
| ABSOLUTE_P a_expr
| RELATIVE_P a_expr
| a_expr
| ALL
| (FORWARD | BACKWARD) (a_expr | ALL)?
;
//https://www.postgresql.org/docs/current/plpgsql-cursors.html#PLPGSQL-CURSOR-OPENING
//MOVE [ direction { FROM | IN } ] cursor;
stmt_move
: MOVE opt_fetch_direction cursor_variable SEMI
;
stmt_close
: CLOSE cursor_variable SEMI
;
stmt_null
: NULL_P SEMI
;
stmt_commit
: COMMIT plsql_opt_transaction_chain SEMI
;
stmt_rollback
: ROLLBACK plsql_opt_transaction_chain SEMI
;
plsql_opt_transaction_chain
: AND NO? CHAIN
|
;
stmt_set
: SET any_name TO DEFAULT SEMI
| RESET (any_name | ALL) SEMI
;
cursor_variable
: colid
| PARAM
;
exception_sect
:
| EXCEPTION proc_exceptions
;
proc_exceptions
: proc_exception+
;
proc_exception
: WHEN proc_conditions THEN proc_sect
;
proc_conditions
: proc_condition (OR proc_condition)*
;
proc_condition
: any_identifier
| SQLSTATE sconst
;
//expr_until_semi:
//;
//expr_until_rightbracket:
//;
//expr_until_loop:
//;
opt_block_label
:
| label_decl
;
opt_loop_label
:
| label_decl
;
opt_label
:
| any_identifier
;
opt_exitcond
: WHEN expr_until_semi
|
;
any_identifier
: colid
| plsql_unreserved_keyword
;
plsql_unreserved_keyword
: ABSOLUTE_P
| ALIAS
| AND
| ARRAY
| ASSERT
| BACKWARD
| CALL
| CHAIN
| CLOSE
| COLLATE
| COLUMN
//| COLUMN_NAME
| COMMIT
| CONSTANT
| CONSTRAINT
//| CONSTRAINT_NAME
| CONTINUE_P
| CURRENT_P
| CURSOR
//| DATATYPE
| DEBUG
| DEFAULT
//| DETAIL
| DIAGNOSTICS
| DO
| DUMP
| ELSIF
//| ERRCODE
| ERROR
| EXCEPTION
| EXIT
| FETCH
| FIRST_P
| FORWARD
| GET
//| HINT
//| IMPORT
| INFO
| INSERT
| IS
| LAST_P
//| MESSAGE
//| MESSAGE_TEXT
| MOVE
| NEXT
| NO
| NOTICE
| OPEN
| OPTION
| PERFORM
//| PG_CONTEXT
//| PG_DATATYPE_NAME
//| PG_EXCEPTION_CONTEXT
//| PG_EXCEPTION_DETAIL
//| PG_EXCEPTION_HINT
| PRINT_STRICT_PARAMS
| PRIOR
| QUERY
| RAISE
| RELATIVE_P
| RESET
| RETURN
//| RETURNED_SQLSTATE
| ROLLBACK
//| ROW_COUNT
| ROWTYPE
| SCHEMA
//| SCHEMA_NAME
| SCROLL
| SET
| SLICE
| SQLSTATE
| STACKED
| TABLE
//| TABLE_NAME
| TYPE_P
| USE_COLUMN
| USE_VARIABLE
| VARIABLE_CONFLICT
| WARNING
| OUTER_P
;
sql_expression
: opt_target_list into_clause from_clause where_clause group_clause having_clause window_clause
;
expr_until_then
: sql_expression
;
expr_until_semi
: sql_expression
;
expr_until_rightbracket
: a_expr
;
expr_until_loop
: a_expr
;
make_execsql_stmt
: stmt opt_returning_clause_into
;
opt_returning_clause_into
: INTO opt_strict into_target
|
;
================================================
FILE: superior-postgres-parser/src/main/java/io/github/melin/superior/parser/postgre/antlr4/LexerDispatchingErrorListener.java
================================================
package io.github.melin.superior.parser.postgre.antlr4;
import java.util.BitSet;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.*;
public class LexerDispatchingErrorListener implements ANTLRErrorListener {
Lexer _parent;
public LexerDispatchingErrorListener(Lexer parent) {
_parent = parent;
}
public void syntaxError(
Recognizer, ?> recognizer,
Object offendingSymbol,
int line,
int charPositionInLine,
String msg,
RecognitionException e) {
ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());
foo.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);
}
public void reportAmbiguity(
Parser recognizer,
DFA dfa,
int startIndex,
int stopIndex,
boolean exact,
BitSet ambigAlts,
ATNConfigSet configs) {
ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());
foo.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs);
}
public void reportAttemptingFullContext(
Parser recognizer, DFA dfa, int startIndex, int stopIndex, BitSet conflictingAlts, ATNConfigSet configs) {
ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());
foo.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs);
}
public void reportContextSensitivity(
Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, ATNConfigSet configs) {
ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());
foo.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs);
}
}
================================================
FILE: superior-postgres-parser/src/main/java/io/github/melin/superior/parser/postgre/antlr4/ParserDispatchingErrorListener.java
================================================
package io.github.melin.superior.parser.postgre.antlr4;
import java.util.BitSet;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.*;
public class ParserDispatchingErrorListener implements ANTLRErrorListener {
Parser _parent;
public ParserDispatchingErrorListener(Parser parent) {
_parent = parent;
}
public void syntaxError(
Recognizer, ?> recognizer,
Object offendingSymbol,
int line,
int charPositionInLine,
String msg,
RecognitionException e) {
ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());
foo.syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e);
}
public void reportAmbiguity(
Parser recognizer,
DFA dfa,
int startIndex,
int stopIndex,
boolean exact,
BitSet ambigAlts,
ATNConfigSet configs) {
ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());
foo.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs);
}
public void reportAttemptingFullContext(
Parser recognizer, DFA dfa, int startIndex, int stopIndex, BitSet conflictingAlts, ATNConfigSet configs) {
ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());
foo.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs);
}
public void reportContextSensitivity(
Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, ATNConfigSet configs) {
ProxyErrorListener foo = new ProxyErrorListener(_parent.getErrorListeners());
foo.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs);
}
}
================================================
FILE: superior-postgres-parser/src/main/java/io/github/melin/superior/parser/postgre/antlr4/PostgreSqlLexerBase.java
================================================
package io.github.melin.superior.parser.postgre.antlr4;
import java.util.ArrayDeque;
import java.util.Deque;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Lexer;
public abstract class PostgreSqlLexerBase extends Lexer {
protected final Deque tags = new ArrayDeque<>();
protected PostgreSqlLexerBase(CharStream input) {
super(input);
}
public void pushTag() {
tags.push(getText());
}
public boolean isTag() {
return getText().equals(tags.peek());
}
public void popTag() {
tags.pop();
}
public boolean checkLA(int c) {
return getInputStream().LA(1) != c;
}
public boolean charIsLetter() {
return Character.isLetter(getInputStream().LA(-1));
}
public void HandleNumericFail() {
getInputStream().seek(getInputStream().index() - 2);
setType(PostgreSqlLexer.Integral);
}
public void HandleLessLessGreaterGreater() {
if (getText() == "<<") setType(PostgreSqlLexer.LESS_LESS);
if (getText() == ">>") setType(PostgreSqlLexer.GREATER_GREATER);
}
public void UnterminatedBlockCommentDebugAssert() {
// Debug.Assert(InputStream.LA(1) == -1 /*EOF*/);
}
public boolean CheckIfUtf32Letter() {
int codePoint = getInputStream().LA(-2) << 8 + getInputStream().LA(-1);
char[] c;
if (codePoint < 0x10000) {
c = new char[] {(char) codePoint};
} else {
codePoint -= 0x10000;
c = new char[] {(char) (codePoint / 0x400 + 0xd800), (char) (codePoint % 0x400 + 0xdc00)};
}
return Character.isLetter(c[0]);
}
}
================================================
FILE: superior-postgres-parser/src/main/java/io/github/melin/superior/parser/postgre/antlr4/PostgreSqlParserBase.java
================================================
package io.github.melin.superior.parser.postgre.antlr4;
import io.github.melin.superior.common.antlr4.UpperCaseCharStream;
import java.util.List;
import org.antlr.v4.runtime.*;
import org.apache.commons.lang3.StringUtils;
public abstract class PostgreSqlParserBase extends Parser {
public PostgreSqlParserBase(TokenStream input) {
super(input);
}
ParserRuleContext GetParsedSqlTree(String script, int line) {
PostgreSqlParser ph = getPostgreSQLParser(script);
ParserRuleContext result = ph.root();
return result;
}
public void ParseRoutineBody(PostgreSqlParser.Createfunc_opt_listContext _localctx) {
String lang = null;
for (PostgreSqlParser.Createfunc_opt_itemContext coi : _localctx.createfunc_opt_item()) {
if (coi.LANGUAGE() != null) {
if (coi.nonreservedword_or_sconst() != null)
if (coi.nonreservedword_or_sconst().nonreservedword() != null)
if (coi.nonreservedword_or_sconst().nonreservedword().identifier() != null)
if (coi.nonreservedword_or_sconst()
.nonreservedword()
.identifier()
.Identifier()
!= null) {
lang = coi.nonreservedword_or_sconst()
.nonreservedword()
.identifier()
.Identifier()
.getText();
break;
}
}
}
if (null == lang) return;
PostgreSqlParser.Createfunc_opt_itemContext func_as = null;
for (PostgreSqlParser.Createfunc_opt_itemContext a : _localctx.createfunc_opt_item()) {
if (a.func_as() != null) {
func_as = a;
break;
}
}
lang = StringUtils.trim(lang);
if (func_as != null) {
String txt = GetRoutineBodyString(func_as.func_as().sconst(0));
PostgreSqlParser ph = getPostgreSQLParser(StringUtils.trim(txt));
switch (lang) {
case "plpgsql":
func_as.func_as().Definition = ph.plsqlroot();
break;
case "sql":
func_as.func_as().Definition = ph.root();
break;
}
}
}
private String TrimQuotes(String s) {
return (s == null || s.isEmpty()) ? s : s.substring(1, s.length() - 1);
}
public String unquote(String s) {
int slength = s.length();
StringBuilder r = new StringBuilder(slength);
int i = 0;
while (i < slength) {
Character c = s.charAt(i);
r.append(c);
if (c == '\'' && i < slength - 1 && (s.charAt(i + 1) == '\'')) i++;
i++;
}
return r.toString();
}
public String GetRoutineBodyString(PostgreSqlParser.SconstContext rule) {
PostgreSqlParser.AnysconstContext anysconst = rule.anysconst();
org.antlr.v4.runtime.tree.TerminalNode StringConstant = anysconst.StringConstant();
if (null != StringConstant) return unquote(TrimQuotes(StringConstant.getText()));
org.antlr.v4.runtime.tree.TerminalNode UnicodeEscapeStringConstant = anysconst.UnicodeEscapeStringConstant();
if (null != UnicodeEscapeStringConstant) return TrimQuotes(UnicodeEscapeStringConstant.getText());
org.antlr.v4.runtime.tree.TerminalNode EscapeStringConstant = anysconst.EscapeStringConstant();
if (null != EscapeStringConstant) return TrimQuotes(EscapeStringConstant.getText());
String result = "";
List dollartext = anysconst.DollarText();
for (org.antlr.v4.runtime.tree.TerminalNode s : dollartext) {
result += s.getText();
}
return result;
}
public PostgreSqlParser getPostgreSQLParser(String script) {
UpperCaseCharStream charStream = new UpperCaseCharStream(CharStreams.fromString(script));
Lexer lexer = new PostgreSqlLexer(charStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
PostgreSqlParser parser = new PostgreSqlParser(tokens);
lexer.removeErrorListeners();
parser.removeErrorListeners();
LexerDispatchingErrorListener listener_lexer = new LexerDispatchingErrorListener(
(Lexer) (((CommonTokenStream) (this.getInputStream())).getTokenSource()));
ParserDispatchingErrorListener listener_parser = new ParserDispatchingErrorListener(this);
lexer.addErrorListener(listener_lexer);
parser.addErrorListener(listener_parser);
return parser;
}
}
================================================
FILE: superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/AbstractSqlParser.kt
================================================
package io.github.melin.superior.parser.postgre
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser
import java.util.concurrent.atomic.AtomicReference
object AbstractSqlParser {
private val parserCaches = AtomicReference(AntlrCaches(PostgreSqlParser._ATN))
/**
* Install the parser caches into the given parser.
*
* This method should be called before parsing any input.
*/
fun installCaches(parser: PostgreSqlParser): Unit = parserCaches.get().installCaches(parser)
/**
* Drop the existing parser caches and create a new one.
*
* ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can
* consume a lot of memory depending on the input seen so far.
*
* This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL
* inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.
*/
fun refreshParserCaches() {
parserCaches.set(AntlrCaches(PostgreSqlParser._ATN))
}
}
================================================
FILE: superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/PostgreSqlAntlr4Visitor.kt
================================================
package io.github.melin.superior.parser.postgre
import com.github.melin.superior.sql.parser.util.CommonUtils
import com.google.common.collect.Lists
import io.github.melin.superior.common.*
import io.github.melin.superior.common.AlterActionType.*
import io.github.melin.superior.common.StatementType.*
import io.github.melin.superior.common.antlr4.ParserUtils.source
import io.github.melin.superior.common.relational.*
import io.github.melin.superior.common.relational.alter.*
import io.github.melin.superior.common.relational.common.CommentStatement
import io.github.melin.superior.common.relational.common.RefreshMaterializedView
import io.github.melin.superior.common.relational.common.ShowStatement
import io.github.melin.superior.common.relational.create.*
import io.github.melin.superior.common.relational.dml.*
import io.github.melin.superior.common.relational.drop.DropDatabase
import io.github.melin.superior.common.relational.drop.DropMaterializedView
import io.github.melin.superior.common.relational.drop.DropTable
import io.github.melin.superior.common.relational.drop.DropView
import io.github.melin.superior.common.relational.table.ColumnRel
import io.github.melin.superior.common.relational.table.TruncateTable
import io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser
import io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser.ColconstraintelemContext
import io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser.Indirection_elContext
import io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser.OpttempTableNameContext
import io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser.PlsqlrootContext
import io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParserBaseVisitor
import io.github.melin.superior.parser.postgre.relational.CreatePartitionTable
import org.antlr.v4.runtime.tree.RuleNode
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2020/6/30 9:57 上午 */
class PostgreSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) :
PostgreSqlParserBaseVisitor() {
private var currentOptType: StatementType = StatementType.UNKOWN
private var limit: Int? = null
private var offset: Int? = null
private var inputTables: ArrayList = arrayListOf()
private var outputTables: ArrayList = arrayListOf()
private var cteTempTables: ArrayList = arrayListOf()
// 多语句解析结果
private var statements: ArrayList = arrayListOf()
// 存储过程和函数中包含的子语句
private var childStatements: ArrayList = arrayListOf()
private val sqls: ArrayList = arrayListOf()
fun getSqlStatements(): List {
return statements
}
fun getSplitSqls(): List {
return sqls
}
override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {
return if (currentResult == null) true else false
}
override fun visitDecl_cursor_query(ctx: PostgreSqlParser.Decl_cursor_queryContext): Statement? {
val statement = visitSelectstmt(ctx.selectstmt())
statement.setSql(source(ctx))
childStatements.add(statement)
return null
}
override fun visitStmtmulti(ctx: PostgreSqlParser.StmtmultiContext): Statement? {
ctx.stmt().forEach {
var sql = source(it)
if (splitSql) {
if (StringUtils.endsWith(sql, ";")) {
sql = StringUtils.substringBeforeLast(sql, ";")
}
sqls.add(sql)
} else {
val startNode = it.start.text
val statement =
if (StringUtils.equalsIgnoreCase("show", startNode)) {
val keyWords: ArrayList = arrayListOf()
CommonUtils.findShowStatementKeyWord(keyWords, it)
ShowStatement(*keyWords.toTypedArray())
} else {
var statement = this.visitStmt(it)
if (statement == null) {
statement = DefaultStatement(StatementType.UNKOWN)
}
statement
}
statement.setSql(sql)
statements.add(statement)
currentOptType = StatementType.UNKOWN
clean()
}
}
return null
}
override fun visitStmt(ctx: PostgreSqlParser.StmtContext): Statement? {
val stmt: Statement? = super.visitStmt(ctx)
if (stmt != null) {
if (currentOptType != CREATE_FUNCTION && currentOptType != CREATE_PROCEDURE) {
stmt.setSql(source(ctx))
childStatements.add(stmt)
}
}
clean()
return stmt
}
private fun clean() {
limit = null
offset = null
inputTables = arrayListOf()
outputTables = arrayListOf()
cteTempTables = arrayListOf()
}
private fun addOutputTableId(tableId: TableId) {
if (!outputTables.contains(tableId)) {
outputTables.add(tableId)
}
}
// -----------------------------------database-------------------------------------------------
override fun visitCreatedbstmt(ctx: PostgreSqlParser.CreatedbstmtContext): Statement {
val databaseName = CommonUtils.cleanQuote(ctx.name().text)
return CreateDatabase(databaseName)
}
override fun visitDropdbstmt(ctx: PostgreSqlParser.DropdbstmtContext): Statement {
val databaseName = CommonUtils.cleanQuote(ctx.name().text)
return DropDatabase(databaseName)
}
// -----------------------------------schema-------------------------------------------------
override fun visitCreateschemastmt(ctx: PostgreSqlParser.CreateschemastmtContext): Statement {
val schemaName = CommonUtils.cleanQuote(ctx.colid().text)
return CreateSchema(schemaName)
}
// -----------------------------------table-------------------------------------------------
override fun visitCreatestmt(ctx: PostgreSqlParser.CreatestmtContext): Statement {
currentOptType = CREATE_TABLE
if (ctx.PARTITION() != null) {
val partitionTableId = parseTableName(ctx.qualified_name(0))
val tableId = parseTableName(ctx.qualified_name(1))
return CreatePartitionTable(tableId, partitionTableId)
}
val tableId = parseTableName(ctx.qualified_name(0))
val columns =
ctx.opttableelementlist()?.tableelementlist()?.tableelement()?.map {
val colDef = it.columnDef()
val colName = colDef.colid().text
val dataType = colDef.typename().text
val columnRel = ColumnRel(colName, dataType)
colDef.colquallist().colconstraint().forEach { colconstraint ->
val child = colconstraint.getChild(0)
if (child is ColconstraintelemContext) {
if (child.NOT() != null) {
columnRel.nullable = false
} else if (child.PRIMARY() != null) {
columnRel.primaryKey = true
}
}
}
columnRel
}
val createTable = CreateTable(tableId, TableType.POSTGRES, columnRels = columns)
if (ctx.opttemp().TEMP() != null || ctx.opttemp().TEMPORARY() != null) {
createTable.temporary = true
}
val partitionspec = ctx.optpartitionspec()?.partitionspec()
val tablePartition = ctx.gaussextension()?.tablePartition()
if (partitionspec != null) {
val partitionType = partitionspec.colid().text.uppercase()
val partitionColumns = partitionspec.part_params().part_elem().map { it.text }
createTable.partitionColumnNames.addAll(partitionColumns)
if ("RANGE" == partitionType) {
createTable.partitionType = PartitionType.RANGE
} else {
createTable.partitionType = PartitionType.LIST
}
} else if (tablePartition != null) {
var partitionType: PartitionType? = null
val partitionColumns = mutableListOf()
val ptSpec = tablePartition.partition_list()
if (ptSpec.list_partition_stmt() != null) {
partitionType = PartitionType.LIST
partitionColumns.add(ptSpec.list_partition_stmt().partition_key().colid().text)
} else if (ptSpec.value_partition_stmt() != null) {
partitionType = PartitionType.VALUES
partitionColumns.add(ptSpec.value_partition_stmt().partition_key().colid().text)
} else if (ptSpec.range_partition_stmt() != null) {
partitionType = PartitionType.RANGE
partitionColumns.add(ptSpec.range_partition_stmt().partition_key().colid().text)
} else if (ptSpec.normal_partition_stmt() != null) {
partitionType = PartitionType.NORMAL
}
createTable.partitionColumnNames.addAll(partitionColumns)
createTable.partitionType = partitionType
}
return createTable
}
override fun visitFunc_as(ctx: PostgreSqlParser.Func_asContext): Statement? {
if (ctx.Definition != null) {
visitPlsqlroot(ctx.Definition as PlsqlrootContext)
}
return super.visitFunc_as(ctx)
}
override fun visitCreatefunctionstmt(ctx: PostgreSqlParser.CreatefunctionstmtContext): Statement {
currentOptType = if (ctx.FUNCTION() != null) CREATE_FUNCTION else CREATE_PROCEDURE
childStatements = arrayListOf()
super.visitCreatefunctionstmt(ctx)
val replace = if (ctx.opt_or_replace().REPLACE() != null) true else false
val funcName = ctx.func_name()
if (ctx.FUNCTION() != null) {
val functionId =
if (funcName.type_function_name() != null) {
FunctionId(funcName.text)
} else {
FunctionId(funcName.colid().text, funcName.indirection().indirection_el()[0].attr_name().text)
}
currentOptType = if (ctx.FUNCTION() != null) CREATE_FUNCTION else CREATE_PROCEDURE
return CreateFunction(functionId, childStatements, replace)
} else {
val procedureId =
if (funcName.type_function_name() != null) {
ProcedureId(funcName.text)
} else {
ProcedureId(funcName.colid().text, funcName.indirection().indirection_el()[0].attr_name().text)
}
currentOptType = if (ctx.FUNCTION() != null) CREATE_FUNCTION else CREATE_PROCEDURE
return CreateProcedure(procedureId, childStatements, replace)
}
}
override fun visitProc_stmt(ctx: PostgreSqlParser.Proc_stmtContext): Statement? {
super.visitProc_stmt(ctx)
return null
}
override fun visitViewstmt(ctx: PostgreSqlParser.ViewstmtContext): Statement {
currentOptType = CREATE_VIEW
val tableId = parseTableName(ctx.qualified_name())
val replace = if (ctx.REPLACE() != null) true else false
val queryStmt = this.visitSelectstmt(ctx.selectstmt()) as QueryStmt
val createView = CreateView(tableId, queryStmt)
createView.replace = replace
if (ctx.opttemp().TEMP() != null || ctx.opttemp().TEMPORARY() != null) {
createView.temporary = true
}
return createView
}
override fun visitCreatematviewstmt(ctx: PostgreSqlParser.CreatematviewstmtContext): Statement {
currentOptType = CREATE_MATERIALIZED_VIEW
val tableId = parseTableName(ctx.create_mv_target().qualified_name())
val ifNotExists = if (ctx.IF_P() != null) true else false
val queryStmt = this.visitSelectstmt(ctx.selectstmt()) as QueryStmt
val createView = CreateMaterializedView(tableId, queryStmt)
createView.ifNotExists = ifNotExists
return createView
}
override fun visitRefreshmatviewstmt(ctx: PostgreSqlParser.RefreshmatviewstmtContext): Statement {
val tableId = parseTableName(ctx.qualified_name())
return RefreshMaterializedView(tableId)
}
override fun visitRenamestmt(ctx: PostgreSqlParser.RenamestmtContext): Statement? {
if (ctx.TABLE() != null) {
val tableId = parseTableName(ctx.qualified_name())
val newTable = ctx.name().get(0).text
val ifexists = ctx.EXISTS() != null
val action = RenameAction(TableId(newTable), ifexists)
return AlterTable(tableId, action)
} else if (ctx.VIEW() != null) {
if (ctx.MATERIALIZED() == null) {
val tableId = parseTableName(ctx.qualified_name())
val newTable = ctx.name().get(0).text
val ifexists = ctx.EXISTS() != null
val action = RenameAction(TableId(newTable), ifexists)
return AlterView(tableId, action)
} else {
val tableId = parseTableName(ctx.qualified_name())
val newTable = ctx.name().get(0).text
val ifexists = ctx.EXISTS() != null
val action = RenameAction(TableId(newTable), ifexists)
return AlterMaterializedView(tableId, action)
}
} else {
return null
}
}
override fun visitSelectstmt(ctx: PostgreSqlParser.SelectstmtContext): Statement {
currentOptType = SELECT
super.visitSelectstmt(ctx)
return QueryStmt(inputTables, limit, offset)
}
override fun visitCreateasstmt(ctx: PostgreSqlParser.CreateasstmtContext): Statement {
currentOptType = CREATE_TABLE_AS_SELECT
val tableId = parseTableName(ctx.create_as_target().qualified_name())
val queryStmt = this.visitSelectstmt(ctx.selectstmt()) as QueryStmt
val createTable = CreateTableAsSelect(tableId, queryStmt)
return createTable
}
override fun visitUpdatestmt(ctx: PostgreSqlParser.UpdatestmtContext): Statement {
currentOptType = UPDATE
val tableId = parseTableName(ctx.relation_expr_opt_alias().relation_expr())
addOutputTableId(tableId)
super.visitWhere_or_current_clause(ctx.where_or_current_clause())
super.visitFrom_clause(ctx.from_clause())
return UpdateTable(tableId, inputTables)
}
override fun visitDeletestmt(ctx: PostgreSqlParser.DeletestmtContext): Statement {
currentOptType = DELETE
val tableId = parseTableName(ctx.relation_expr_opt_alias().relation_expr())
addOutputTableId(tableId)
super.visitWhere_or_current_clause(ctx.where_or_current_clause())
super.visitUsing_clause(ctx.using_clause())
return DeleteTable(tableId, inputTables)
}
override fun visitInsertstmt(ctx: PostgreSqlParser.InsertstmtContext): Statement {
currentOptType = INSERT
if (ctx.opt_with_clause() != null) {
this.visitOpt_with_clause(ctx.opt_with_clause())
}
val tableId = parseTableName(ctx.insert_target().qualified_name())
addOutputTableId(tableId)
val queryStmt = this.visitSelectstmt(ctx.insert_rest().selectstmt()) as QueryStmt
val insertTable = InsertTable(InsertMode.INTO, queryStmt, tableId)
insertTable.outputTables.addAll(outputTables.subList(1, outputTables.size))
insertTable?.setSql(source(ctx))
return insertTable
}
override fun visitMergestmt(ctx: PostgreSqlParser.MergestmtContext): Statement {
currentOptType = MERGE
val mergeTableId = parseTableName(ctx.qualified_name(0))
val mergeTable = MergeTable(mergeTableId)
if (ctx.qualified_name().size == 2) {
val tableId = parseTableName(ctx.qualified_name(1))
inputTables.add(tableId)
} else if (ctx.select_with_parens() != null) {
super.visitSelect_with_parens(ctx.select_with_parens())
}
mergeTable.inputTables = inputTables
return mergeTable
}
override fun visitCte_list(ctx: PostgreSqlParser.Cte_listContext): Statement {
ctx.common_table_expr().forEach { cteTempTables.add(TableId(it.name().text)) }
return super.visitCte_list(ctx)
}
override fun visitQualified_name(ctx: PostgreSqlParser.Qualified_nameContext): Statement? {
if (
currentOptType == SELECT ||
currentOptType == CREATE_VIEW ||
currentOptType == CREATE_MATERIALIZED_VIEW ||
currentOptType == CREATE_TABLE_AS_SELECT ||
currentOptType == UPDATE ||
currentOptType == DELETE ||
currentOptType == MERGE ||
currentOptType == INSERT ||
currentOptType == CREATE_FUNCTION ||
currentOptType == CREATE_PROCEDURE
) {
if (ctx.parent is OpttempTableNameContext) {
return null
}
val tableId = parseTableName(ctx)
if (!inputTables.contains(tableId) && !cteTempTables.contains(tableId)) {
inputTables.add(tableId)
}
return null
} else {
throw SQLParserException("not support")
}
}
// create index
override fun visitIndexstmt(ctx: PostgreSqlParser.IndexstmtContext): Statement {
val tableId = parseTableName(ctx.relation_expr())
val indexName =
if (ctx.opt_index_name() != null) {
ctx.opt_index_name().text
} else {
ctx.name().text
}
val createIndex = CreateIndex(indexName)
return AlterTable(tableId, createIndex)
}
override fun visitDropstmt(ctx: PostgreSqlParser.DropstmtContext): Statement {
if (ctx.object_type_any_name() != null) {
val ifExists = ctx.IF_P() != null
if (ctx.object_type_any_name().INDEX() != null) {
val actions = ctx.any_name_list().any_name().map { indexName -> DropIndex(indexName.text, ifExists) }
val tableId = TableId("")
val alterTable = AlterTable(tableId)
alterTable.ifExists = ifExists
alterTable.addActions(actions)
return alterTable
} else if (ctx.object_type_any_name().TABLE() != null) {
val tableIds = ctx.any_name_list().any_name().map { tableName -> parseTableName(tableName) }
val dropTable = DropTable(tableIds.first(), ifExists)
dropTable.tableIds.addAll(tableIds)
return dropTable
} else if (ctx.object_type_any_name().VIEW() != null) {
val isMaterialized =
if (ctx.object_type_any_name().MATERIALIZED() != null) {
true
} else {
false
}
val tableIds = ctx.any_name_list().any_name().map { tableName -> parseTableName(tableName) }
if (isMaterialized) {
val dropView = DropMaterializedView(tableIds.first(), ifExists)
dropView.tableIds.addAll(tableIds)
return dropView
} else {
val dropView = DropView(tableIds.first(), ifExists)
dropView.tableIds.addAll(tableIds)
return dropView
}
} else if (ctx.object_type_any_name().SEQUENCE() != null) {
val tableIds = ctx.any_name_list().any_name().map { tableName -> parseTableName(tableName) }
val dropSequence =
io.github.melin.superior.common.relational.drop.DropSequence(tableIds.first(), ifExists)
dropSequence.tableIds.addAll(tableIds)
return dropSequence
}
}
throw SQLParserException("not support")
}
override fun visitTruncatestmt(ctx: PostgreSqlParser.TruncatestmtContext): Statement {
val tableIds = ctx.relation_expr_list().relation_expr().map { parseTableName(it) }
return TruncateTable(Lists.newArrayList(tableIds))
}
override fun visitAltertablestmt(ctx: PostgreSqlParser.AltertablestmtContext): Statement? {
if (ctx.TABLE() != null) {
if (ctx.relation_expr() != null) {
val tableId = parseTableName(ctx.relation_expr())
if (ctx.alter_table_cmds() != null) {
val alterTable = AlterTable(tableId)
val cmds = ctx.alter_table_cmds().alter_table_cmd()
for (cmdContext in cmds) {
if (cmdContext.ADD_P() != null && cmdContext.columnDef() != null) {
val columnDef = cmdContext.columnDef()
val columnName = columnDef.colid().text
val dataType = source(columnDef.typename())
val action = AlterColumnAction(ADD_COLUMN, columnName, dataType)
action.ifNotExists = cmdContext.EXISTS() != null
alterTable.actions.add(action)
} else if (cmdContext.alter_column_default() != null) {
val columnDefaultDef = cmdContext.alter_column_default()
val columnName = cmdContext.colid().get(0).text
if (columnDefaultDef.DROP() != null) {
val action = AlterColumnAction(DROP_COLUMN_DRFAULT, columnName)
alterTable.actions.add(action)
} else {
val value = source(columnDefaultDef.a_expr())
val action = AlterColumnAction(SET_COLUMN_DEFAULT, columnName)
action.defaultExpression = CommonUtils.cleanQuote(value)
alterTable.actions.add(action)
}
}
}
return alterTable
} else {
var alterTable: AlterTable? = null
val partitionCmd = ctx.partition_cmd()
if (partitionCmd.ATTACH() != null) {
alterTable = AlterTable(tableId, AlterTableAction(ATTACH_PARTITION))
} else {
alterTable = AlterTable(tableId, AlterTableAction(DETACH_PARTITION))
}
return alterTable
}
return null
}
}
return null
}
override fun visitCommentstmt(ctx: PostgreSqlParser.CommentstmtContext): Statement {
val objType: String? =
if (ctx.object_type_any_name() != null) {
ctx.object_type_any_name().children.map { it.text }.joinToString(" ")
} else if (ctx.object_type_name() != null) {
ctx.object_type_name().children.map { it.text }.joinToString(" ")
} else if (ctx.object_type_name_on_any_name() != null) {
ctx.object_type_name_on_any_name().children.map { it.text }.joinToString(" ")
} else if (ctx.COLUMN() != null) {
ctx.COLUMN().text
} else if (ctx.FUNCTION() != null) {
ctx.FUNCTION().text
} else {
null
}
val objValue = if (ctx.any_name() != null) ctx.any_name().text else null
val isNull = if (ctx.comment_text().NULL_P() != null) true else false
val text: String? =
if (ctx.comment_text().text != null) CommonUtils.cleanQuote(ctx.comment_text().sconst().text) else null
return CommentStatement(text, isNull, objType, objValue)
}
override fun visitStmt_dynexecute(ctx: PostgreSqlParser.Stmt_dynexecuteContext): Statement? {
var execSql = StringUtils.substringAfter(ctx.a_expr().text, "'")
execSql = StringUtils.substringBeforeLast(execSql, "'")
execSql = StringUtils.trim(execSql)
execSql = StringUtils.replace(execSql, "''", "'")
val statements = PostgreSqlHelper.parseMultiStatement(execSql)
childStatements.addAll(statements)
return null
}
override fun visitSelect_limit(ctx: PostgreSqlParser.Select_limitContext): Statement? {
val limitClause = ctx.limit_clause()
val offsetClause = ctx.offset_clause()
if (limitClause != null) {
if (limitClause.LIMIT() != null) {
if (limitClause.select_limit_value().a_expr() != null) {
limit = limitClause.select_limit_value().a_expr().text.toInt()
}
if (limitClause.select_offset_value() != null) {
offset = limitClause.select_offset_value().a_expr().text.toInt()
}
}
if (limitClause.FETCH() != null && limitClause.select_fetch_first_value() != null) {
if (limitClause.select_fetch_first_value().c_expr() != null) {
limit = limitClause.select_fetch_first_value().c_expr().text.toInt()
}
}
}
if (offsetClause != null) {
if (offsetClause.select_offset_value() != null) {
offset = offsetClause.select_offset_value().text.toInt()
}
if (offsetClause.select_fetch_first_value() != null) {
if (offsetClause.select_fetch_first_value().c_expr() != null) {
offset = offsetClause.select_fetch_first_value().c_expr().text.toInt()
}
}
}
return super.visitSelect_limit(ctx)
}
// ----------------------------------------private methods------------------------------------
fun parseTableName(ctx: PostgreSqlParser.Any_nameContext): TableId {
val attrNames = ctx.attrs()?.attr_name()
if (attrNames == null) {
return TableId(null, null, ctx.colid().text)
}
if (attrNames.size == 2) {
return TableId(ctx.colid().text, attrNames.get(0).text, attrNames.get(1).text)
} else if (attrNames.size == 1) {
return TableId(null, ctx.colid().text, attrNames.get(0).text)
}
throw SQLParserException("parse schema qualified name error")
}
fun parseTableName(ctx: PostgreSqlParser.Relation_exprContext): TableId {
return parseTableName(ctx.qualified_name())
}
fun parseTableName(ctx: PostgreSqlParser.Qualified_nameContext): TableId {
if (ctx.childCount == 2) {
val obj = ctx.getChild(1)
if (obj.childCount == 2) {
return TableId(ctx.getChild(0).text, obj.getChild(0).getChild(1).text, obj.getChild(1).getChild(1).text)
} else if (obj.childCount == 1) {
val inEl = obj.getChild(0) as Indirection_elContext
return TableId(ctx.colid().text, inEl.attr_name().text)
}
} else if (ctx.childCount == 1) {
return TableId(ctx.getChild(0).text)
}
throw SQLParserException("parse schema qualified name error")
}
}
================================================
FILE: superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/PostgreSqlHelper.kt
================================================
package io.github.melin.superior.parser.postgre
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.common.antlr4.ParseErrorListener
import io.github.melin.superior.common.antlr4.ParseException
import io.github.melin.superior.common.antlr4.UpperCaseCharStream
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.parser.postgre.antlr4.PostgreSqlLexer
import io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParser
import io.github.melin.superior.parser.postgre.antlr4.PostgreSqlParserBaseVisitor
import org.antlr.v4.runtime.CharStreams
import org.antlr.v4.runtime.CommonTokenStream
import org.antlr.v4.runtime.atn.PredictionMode
import org.antlr.v4.runtime.misc.ParseCancellationException
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2020/6/30 9:58 上午 */
object PostgreSqlHelper {
@JvmStatic
fun sqlKeywords(): List {
val keywords = hashSetOf()
(0 until PostgreSqlLexer.VOCABULARY.maxTokenType).forEach { idx ->
val name = PostgreSqlLexer.VOCABULARY.getLiteralName(idx)
if (name != null) {
val matchResult = CommonUtils.KEYWORD_REGEX.find(name)
if (matchResult != null) {
keywords.add(matchResult.groupValues.get(1))
}
}
}
return keywords.sorted()
}
@JvmStatic
fun parseStatement(command: String): Statement {
val statements = this.parseMultiStatement(command)
if (statements.size != 1) {
throw IllegalStateException("only parser one sql, sql count: " + statements.size)
} else {
return statements.get(0)
}
}
@JvmStatic
fun parseMultiStatement(command: String): List {
val trimCmd = StringUtils.trim(command)
val sqlVisitor = PostgreSqlAntlr4Visitor(false, trimCmd)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSqlStatements()
}
@JvmStatic
fun splitSql(command: String): List {
val trimCmd = StringUtils.trim(command)
val sqlVisitor = PostgreSqlAntlr4Visitor(true, trimCmd)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSplitSqls()
}
@JvmStatic
fun checkSqlSyntax(command: String) {
val sqlVisitor = PostgreSqlParserBaseVisitor()
innerParseStatement(command, sqlVisitor)
}
private fun innerParseStatement(command: String, sqlVisitor: PostgreSqlParserBaseVisitor) {
val charStream = UpperCaseCharStream(CharStreams.fromString(command))
val lexer = PostgreSqlLexer(charStream)
lexer.removeErrorListeners()
lexer.addErrorListener(ParseErrorListener())
val tokenStream = CommonTokenStream(lexer)
val parser = PostgreSqlParser(tokenStream)
AbstractSqlParser.installCaches(parser)
parser.removeErrorListeners()
parser.addErrorListener(ParseErrorListener())
// parser.interpreter.predictionMode = PredictionMode.SLL
try {
try {
// first, try parsing with potentially faster SLL mode
sqlVisitor.visit(parser.root())
} catch (e: ParseCancellationException) {
tokenStream.seek(0) // rewind input stream
parser.reset()
// Try Again.
parser.interpreter.predictionMode = PredictionMode.LL
sqlVisitor.visit(parser.root())
}
} catch (e: ParseException) {
if (StringUtils.isNotBlank(e.command)) {
throw e
} else {
throw e.withCommand(command)
}
} finally {
val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)
if (releaseAntlrCache == null || "true".equals(releaseAntlrCache)) {
AbstractSqlParser.refreshParserCaches()
}
}
}
}
================================================
FILE: superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/relational/CreatePartitionTable.kt
================================================
package io.github.melin.superior.parser.postgre.relational
import io.github.melin.superior.common.PrivilegeType
import io.github.melin.superior.common.SqlType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.abs.AbsTableStatement
data class CreatePartitionTable(override val tableId: TableId, val partitionTableId: TableId) :
AbsTableStatement() { // 是否存在 if exists 关键字
override val statementType = StatementType.CREATE_TABLE
override val privilegeType = PrivilegeType.CREATE
override val sqlType = SqlType.DDL
}
================================================
FILE: superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/BooleanType.kt
================================================
package io.github.melin.superior.parser.postgre.type
import io.github.melin.superior.common.type.AbsType
class BooleanType : AbsType() {
override val name: String = "boolean"
override val alias: String = "bool"
}
================================================
FILE: superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/JsonType.kt
================================================
package io.github.melin.superior.parser.postgre.type
import io.github.melin.superior.common.type.AbsType
class JsonType : AbsType() {
override val name: String = "json"
}
================================================
FILE: superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/datetime.kt
================================================
package io.github.melin.superior.parser.postgre.type
import io.github.melin.superior.common.type.AbsDataTimeType
class DateType : AbsDataTimeType() {
override val name: String = "date"
}
data class TimeType(val precision: Int = 0, val timezone: Boolean = false) : AbsDataTimeType() {
override val name: String = "time"
override val alias: String = "timez"
}
data class TimeStampType(val precision: Int = 0, val timezone: Boolean = false) : AbsDataTimeType() {
override val name: String = "timestamp"
override val alias: String = "timestampz"
}
class IntervalType : AbsDataTimeType() {
override val name: String = "interval"
}
================================================
FILE: superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/numeric.kt
================================================
package io.github.melin.superior.parser.postgre.type
import io.github.melin.superior.common.type.AbsNumericType
data class SmallIntType(val length: Int) : AbsNumericType() {
override val name: String = "smallint"
override val alias: String = "int2"
companion object {
const val MIN_VALUE: Int = -32768
const val MAX_VALUE: Int = 32767
}
}
data class IntegerType(val length: Int) : AbsNumericType() {
override val name: String = "integer"
override val alias: String = "int"
override val alias2: String = "int4"
companion object {
const val MIN_VALUE: Long = -2147483648L
const val MAX_VALUE: Long = 2147483647L
}
}
data class BigIntType(val length: Int) : AbsNumericType() {
override val name: String = "bigint"
override val alias: String = "int8"
}
data class NumericType(val precision: Int = 10, val scale: Int = 0) : AbsNumericType() {
override val name: String = "numeric"
override val alias: String = "decimal"
}
data class FloatType(val precision: Int, val scale: Int = 0) : AbsNumericType() {
override val name: String = "float"
}
data class DoubleType(val precision: Int, val scale: Int = 0) : AbsNumericType() {
override val name: String = "double precision"
override val alias: String = "float8"
}
data class RealType(val precision: Int, val scale: Int = 0) : AbsNumericType() {
override val name: String = "real"
override val alias: String = "float4"
}
data class SmallserialType(val length: Int) : AbsNumericType() {
override val name: String = "smallserial"
override val alias: String = "serial2"
companion object {
const val MIN_VALUE: Int = 1
const val MAX_VALUE: Int = 32767
}
}
data class SerialType(val length: Int) : AbsNumericType() {
override val name: String = "serial"
override val alias: String = "serial4"
companion object {
const val MIN_VALUE: Long = 1
const val MAX_VALUE: Long = 2147483647L
}
}
data class BigserialType(val length: Int) : AbsNumericType() {
override val name: String = "bigserial"
override val alias: String = "serial8"
}
data class BitType(val length: Int) : AbsNumericType() {
override val name: String = "bit"
}
data class VarbitType(val length: Int) : AbsNumericType() {
override val name: String = "bit varying"
override val alias: String = "varbit"
}
================================================
FILE: superior-postgres-parser/src/main/kotlin/io/github/melin/superior/parser/postgre/type/string.kt
================================================
package io.github.melin.superior.parser.postgre.type
import io.github.melin.superior.common.type.AbsStringType
data class CharType(val length: Int) : AbsStringType() {
override val name: String = "char"
override val alias: String = "character"
companion object {
const val MAX_LENGTH: Int = 255
}
}
data class VarcharType(val length: Int) : AbsStringType() {
override val name: String = "varchar"
override val alias: String = "character varying"
companion object {
const val MAX_LENGTH: Int = 65535
}
}
class TextType : AbsStringType() {
override val name: String = "text"
}
class ByteaType : AbsStringType() {
override val name: String = "bytea"
}
data class EnumType(val typeName: String, val values: List) : AbsStringType() {
override val name: String = "enum"
}
================================================
FILE: superior-postgres-parser/src/test/java/io/github/melin/superior/parser/postgre/PostgreSqlParserDdlTest.kt
================================================
package io.github.melin.superior.parser.postgre
import io.github.melin.superior.common.AlterActionType
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.*
import io.github.melin.superior.common.relational.alter.*
import io.github.melin.superior.common.relational.common.CommentStatement
import io.github.melin.superior.common.relational.common.RefreshMaterializedView
import io.github.melin.superior.common.relational.create.*
import io.github.melin.superior.common.relational.drop.DropDatabase
import io.github.melin.superior.common.relational.drop.DropMaterializedView
import io.github.melin.superior.common.relational.drop.DropTable
import io.github.melin.superior.parser.postgre.relational.CreatePartitionTable
import org.junit.Assert
import org.junit.Test
/**
* Created by libinsong on 2020/6/30 11:04 上午
*/
class PostgreSqlParserDdlTest {
@Test
fun createDatabaseTest() {
val sql = """
CREATE DATABASE bigdata1;
drop DATABASE bigdata2
""".trimIndent()
val statements = PostgreSqlHelper.parseMultiStatement(sql)
val createDatabse = statements.get(0)
val dropDatabase = statements.get(1)
if (createDatabse is CreateDatabase) {
Assert.assertEquals("bigdata1", createDatabse.databaseName)
} else {
Assert.fail()
}
if (dropDatabase is DropDatabase) {
Assert.assertEquals("bigdata2", dropDatabase.databaseName)
} else {
Assert.fail()
}
}
@Test
fun createSchemaTest() {
val sql = """
CREATE schema bigdata1;
CREATE schema bigdata2;
""".trimIndent()
val statements = PostgreSqlHelper.parseMultiStatement(sql)
val createSchema1 = statements.get(0)
val createSchema2 = statements.get(1)
if (createSchema1 is CreateSchema) {
Assert.assertEquals("bigdata1", createSchema1.schemaName)
} else {
Assert.fail()
}
if (createSchema2 is CreateSchema) {
Assert.assertEquals("bigdata2", createSchema2.schemaName)
} else {
Assert.fail()
}
}
@Test
fun createTable0() {
val sql = """
CREATE TEMPORARY TABLE test.public.authors (
id INTEGER NOT NULL PRIMARY KEY,
last_name TEXT,
first_name TEXT,
age int not null
) PARTITION BY RANGE (age);
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateTable) {
Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)
Assert.assertTrue(statement.temporary)
Assert.assertEquals(TableId("test", "public", "authors"), statement.tableId)
Assert.assertEquals(4, statement.columnRels?.size)
Assert.assertTrue(statement.columnRels?.get(0)?.primaryKey!!)
Assert.assertEquals(PartitionType.RANGE, statement.partitionType)
Assert.assertEquals(1, statement.partitionColumnNames.size)
} else {
Assert.fail()
}
}
@Test
fun createTable1() {
val sql = """
CREATE TABLE IF NOT EXISTS sales_range_partitioned3 (
id INT,
sales_date DATE,
amount DECIMAL(10, 2)
)
PARTITION BY RANGE (sales_date) (
PARTITION p2022 VALUES LESS THAN ('2023-01-01'),
PARTITION p2023 VALUES LESS THAN ('2024-01-01'),
PARTITION p2024 VALUES LESS THAN ('2025-01-01')
);
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateTable) {
Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)
Assert.assertEquals(TableId("sales_range_partitioned3"), statement.tableId)
Assert.assertEquals(3, statement.columnRels?.size)
Assert.assertEquals(PartitionType.RANGE, statement.partitionType)
Assert.assertEquals(1, statement.partitionColumnNames.size)
} else {
Assert.fail()
}
}
@Test
fun createView0() {
val sql = """
CREATE OR REPLACE VIEW comedies AS
SELECT f.*,
country_code_to_name(f.country_code) AS country,
(SELECT avg(r.rating)
FROM user_ratings r
WHERE r.film_id = f.id) AS avg_rating
FROM films f
WHERE f.kind = 'Comedy'
WITH CASCADED CHECK OPTION;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateView) {
Assert.assertEquals(StatementType.CREATE_VIEW, statement.statementType)
Assert.assertEquals("comedies", statement.tableId.tableName)
Assert.assertEquals(2, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun createMatView0() {
val sql = """
CREATE MATERIALIZED VIEW sales_summary AS
SELECT
seller_no,
invoice_date,
sum(invoice_amt)::numeric(13,2) as sales_amt
FROM invoice
WHERE invoice_date < CURRENT_DATE
GROUP BY
seller_no,
invoice_date;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateMaterializedView) {
Assert.assertEquals(StatementType.CREATE_MATERIALIZED_VIEW, statement.statementType)
Assert.assertEquals("sales_summary", statement.tableId.tableName)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun dropMvTest() {
val sql = """
DROP MATERIALIZED VIEW tickets_mv;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is DropMaterializedView) {
Assert.assertEquals(StatementType.DROP_MATERIALIZED_VIEW, statement.statementType)
Assert.assertEquals(TableId("tickets_mv"), statement.tableId)
} else {
Assert.fail()
}
}
@Test
fun refreshMvTest() {
val sql = """
REFRESH MATERIALIZED VIEW tickets_mv;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is RefreshMaterializedView) {
Assert.assertEquals(StatementType.REFRESH_MV, statement.statementType)
Assert.assertEquals(TableId("tickets_mv"), statement.tableId)
} else {
Assert.fail()
}
}
@Test
fun renameMvTest() {
val sql = """
ALTER MATERIALIZED VIEW tickets_mv RENAME TO tickets_mv_1;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is AlterMaterializedView) {
Assert.assertEquals(StatementType.ALTER_MATERIALIZED_VIEW, statement.statementType)
Assert.assertEquals(TableId("tickets_mv"), statement.tableId)
Assert.assertEquals(AlterActionType.RENAME, statement.firstAction().alterType)
} else {
Assert.fail()
}
}
@Test
fun dropTable0() {
val sql = """
drop TABLE test.public.authors
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is DropTable) {
Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)
Assert.assertEquals(TableId("test", "public", "authors"), statement.tableId)
} else {
Assert.fail()
}
}
@Test
fun dropTable1() {
val sql = """
drop TABLE authors, tests
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is DropTable) {
Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)
Assert.assertEquals(TableId("authors"), statement.tableId)
Assert.assertEquals(2, statement.tableIds.size)
} else {
Assert.fail()
}
}
@Test
fun createIndexTest() {
val sql = "CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating);\n"
val statement = PostgreSqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
if (statement is AlterTable) {
Assert.assertEquals(TableId("films"), statement.tableId)
val createIndex = statement.firstAction() as CreateIndex
Assert.assertEquals(AlterActionType.ADD_INDEX, createIndex.alterType)
Assert.assertEquals("title_idx", createIndex.indexName)
} else {
Assert.fail()
}
}
@Test
fun dropIndexTest() {
val sql = "DROP INDEX title_idx"
val statement = PostgreSqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.ALTER_TABLE, statement.statementType)
if (statement is AlterTable) {
val dropIndex = statement.firstAction() as DropIndex
Assert.assertEquals(AlterActionType.DROP_INDEX, dropIndex.alterType)
Assert.assertEquals("title_idx", dropIndex.indexName)
} else {
Assert.fail()
}
}
@Test
fun createPartitonTableTest() {
val sql = "create table pkslow_person_r1 partition of pkslow_person_r for values from (MINVALUE) to (10); \n"
val statement = PostgreSqlHelper.parseStatement(sql)
Assert.assertEquals(StatementType.CREATE_TABLE, statement.statementType)
if (statement is CreatePartitionTable) {
Assert.assertEquals("pkslow_person_r", statement.tableId.tableName)
Assert.assertEquals("pkslow_person_r1", statement.partitionTableId.tableName)
} else {
Assert.fail()
}
}
@Test
fun commentTest0() {
val sql = """
COMMENT ON TABLE my_schema.my_table IS 'Employee Information';
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CommentStatement) {
Assert.assertEquals(StatementType.COMMENT, statement.statementType)
Assert.assertEquals("Employee Information", statement.comment)
Assert.assertFalse(statement.isNull)
} else {
Assert.fail()
}
}
@Test
fun alterTableTest() {
val sql = """
ALTER TABLE distributors ADD COLUMN address varchar(30),
ALTER COLUMN status SET default 'current';
""".trimIndent()
val statements = PostgreSqlHelper.parseMultiStatement(sql)
val alterTable1 = statements.get(0) as AlterTable
Assert.assertEquals("distributors", alterTable1.tableId.tableName)
var action = alterTable1.actions.get(0) as AlterColumnAction
Assert.assertEquals(AlterActionType.ADD_COLUMN, action.alterType)
Assert.assertEquals("address", action.columName)
Assert.assertEquals("varchar(30)", action.dataType)
action = alterTable1.actions.get(1) as AlterColumnAction
Assert.assertEquals(AlterActionType.SET_COLUMN_DEFAULT, action.alterType)
Assert.assertEquals("status", action.columName)
Assert.assertEquals("current", action.defaultExpression)
}
}
================================================
FILE: superior-postgres-parser/src/test/java/io/github/melin/superior/parser/postgre/PostgreSqlParserDmlTest.kt
================================================
package io.github.melin.superior.parser.postgre
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.create.CreateTableAsSelect
import io.github.melin.superior.common.relational.dml.*
import io.github.melin.superior.common.relational.table.TruncateTable
import org.junit.Assert
import org.junit.Test
/**
* Created by libinsong on 2020/6/30 11:04 上午
*/
class PostgreSqlParserDmlTest {
@Test
fun queryTest0() {
val sql = """
select a.* from datacompute1.datacompute.dc_job a left join datacompute1.datacompute.dc_job_scheduler b on a.id=b.job_id
LIMIT 3, 2
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(2, statement.inputTables.size)
Assert.assertEquals(3, statement.limit)
Assert.assertEquals(2, statement.offset)
} else {
Assert.fail()
}
}
@Test
fun queryTest1() {
val sql = """
SELECT * FROM public.usertest LIMIT 3 OFFSET 2;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(1, statement.inputTables.size)
Assert.assertEquals(3, statement.limit)
Assert.assertEquals(2, statement.offset)
Assert.assertEquals(TableId("public", "usertest"), statement.inputTables.get(0))
} else {
Assert.fail()
}
}
@Test
fun queryTest2() {
val sql = """
SELECT * FROM public.usertest FETCH FIRST 5 ROWS ONLY;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(1, statement.inputTables.size)
Assert.assertEquals(5, statement.limit)
Assert.assertEquals(TableId("public", "usertest"), statement.inputTables.get(0))
} else {
Assert.fail()
}
}
@Test
fun queryTest3() {
val sql = """
SELECT * FROM public.usertest
OFFSET 10
FETCH FIRST 10 ROWS ONLY;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(1, statement.inputTables.size)
Assert.assertEquals(10, statement.limit)
Assert.assertEquals(10, statement.offset)
Assert.assertEquals(TableId("public", "usertest"), statement.inputTables.get(0))
} else {
Assert.fail()
}
}
@Test
fun cteSqlTest0() {
val sql = """
WITH regional_sales AS (
SELECT region, SUM(amount) AS total_sales
FROM orders
GROUP BY region
),
top_regions AS (
SELECT region
FROM regional_sales
WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
)
SELECT region,
product,
SUM(quantity) AS product_units,
SUM(amount) AS product_sales
FROM orders
WHERE region IN (SELECT region FROM top_regions)
GROUP BY region, product;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(1, statement.inputTables.size)
Assert.assertEquals(TableId("orders"), statement.inputTables.get(0))
} else {
Assert.fail()
}
}
@Test
fun createAsQueryTest0() {
val sql = """
CREATE TABLE films_recent AS
SELECT * FROM films WHERE date_prod >= '2002-01-01';
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateTableAsSelect) {
Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)
Assert.assertEquals("films_recent", statement.tableId.tableName)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
Assert.assertEquals("films", statement.queryStmt.inputTables.get(0).tableName)
} else {
Assert.fail()
}
}
@Test
fun deleteTest0() {
val sql = """
DELETE FROM films
WHERE producer_id IN (SELECT id FROM producers WHERE name = 'foo');
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is DeleteTable) {
Assert.assertEquals(StatementType.DELETE, statement.statementType)
Assert.assertEquals("films", statement.tableId?.tableName)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun deleteTest1() {
val sql = """
DELETE FROM films USING producers
WHERE producer_id = producers.id AND producers.name = 'foo';
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is DeleteTable) {
Assert.assertEquals(StatementType.DELETE, statement.statementType)
Assert.assertEquals("films", statement.tableId?.tableName)
Assert.assertEquals(1, statement.inputTables.size)
Assert.assertEquals("producers", statement.inputTables.get(0).tableName)
} else {
Assert.fail()
}
}
@Test
fun updateTest0() {
val sql = """
UPDATE employees SET sales_count = sales_count + 1 WHERE id =
(SELECT sales_person FROM accounts WHERE name = 'Acme Corporation');
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is UpdateTable) {
Assert.assertEquals(StatementType.UPDATE, statement.statementType)
Assert.assertEquals("employees", statement.tableId?.tableName)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun updateTest1() {
val sql = """
UPDATE product p
SET net_price = price - price * discount
FROM product_segment s
WHERE p.segment_id = s.id;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is UpdateTable) {
Assert.assertEquals(StatementType.UPDATE, statement.statementType)
Assert.assertEquals("product", statement.tableId?.tableName)
Assert.assertEquals(1, statement.inputTables.size)
Assert.assertEquals("product_segment", statement.inputTables.get(0).tableName)
} else {
Assert.fail()
}
}
@Test
fun insertTest0() {
val sql = """
INSERT INTO films (code, title, did, date_prod, kind) VALUES
('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("films", statement.tableId?.tableName)
Assert.assertEquals(0, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest1() {
val sql = """
WITH upd AS (
UPDATE employees SET sales_count = sales_count + 1 WHERE id =
(SELECT sales_person FROM accounts WHERE name = 'Acme Corporation')
RETURNING *
)
INSERT INTO employees_log SELECT *, current_timestamp FROM upd;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("employees_log", statement.tableId?.tableName)
Assert.assertEquals(2, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun insertTest2() {
val sql = """
truncate table films
INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';
""".trimIndent()
val statements = PostgreSqlHelper.parseMultiStatement(sql)
var statement = statements.get(0)
if (statement is TruncateTable) {
Assert.assertEquals(StatementType.TRUNCATE_TABLE, statement.statementType)
Assert.assertEquals("films", statement.tableId.tableName)
} else {
Assert.fail()
}
statement = statements.get(1)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("films", statement.tableId?.tableName)
Assert.assertEquals(1, statement.outputTables.size)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun deltaMergeTest() {
val sql = """
MERGE INTO wines w
USING wine_stock_changes s
ON s.winename = w.winename
WHEN NOT MATCHED AND s.stock_delta > 0 THEN
INSERT VALUES(s.winename, s.stock_delta)
WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN
UPDATE SET stock = w.stock + s.stock_delta
WHEN MATCHED THEN
DELETE;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is MergeTable) {
Assert.assertEquals(StatementType.MERGE, statement.statementType)
Assert.assertEquals("wines", statement.targetTable.tableName)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-postgres-parser/src/test/java/io/github/melin/superior/parser/postgre/PostgreSqlProcessParserTest.kt
================================================
package io.github.melin.superior.parser.postgre
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.FunctionId
import io.github.melin.superior.common.relational.ProcedureId
import io.github.melin.superior.common.relational.create.CreateFunction
import io.github.melin.superior.common.relational.create.CreateProcedure
import org.junit.Assert
import org.junit.Test
class PostgreSqlProcessParserTest {
@Test
fun createFunctionTest() {
val sql = """
CREATE FUNCTION public.myadd(integer, integer) RETURNS integer
AS 'select ${'$'}1 + ${'$'}2;'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateFunction) {
Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)
Assert.assertEquals(FunctionId("public", "myadd"), statement.functionId)
Assert.assertEquals("myadd", statement.functionId.functionName)
} else {
Assert.fail()
}
}
@Test
fun createFunctionTest1() {
val sql = """
CREATE FUNCTION myadd(integer, integer) RETURNS integer
AS 'select ${'$'}1 + ${'$'}2;'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateFunction) {
Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)
Assert.assertEquals(FunctionId("myadd"), statement.functionId)
Assert.assertEquals("myadd", statement.functionId.functionName)
} else {
Assert.fail()
}
}
@Test
fun createFunctionTest2() {
val sql = """
CREATE FUNCTION check_password(uname TEXT, pass TEXT)
RETURNS BOOLEAN AS ${'$'}${'$'}
DECLARE passed BOOLEAN;
BEGIN
SELECT (pwd = ${'$'}2) INTO passed
FROM pwds
WHERE username = ${'$'}1;
RETURN passed;
update accounts_2
set balance = balance + amount
where id = receiver;
END;
${'$'}${'$'} LANGUAGE plpgsql
SECURITY DEFINER
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateFunction) {
Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)
Assert.assertEquals(FunctionId( "check_password"), statement.functionId)
Assert.assertEquals(2, statement.childStatements.size)
} else {
Assert.fail()
}
}
@Test
fun createFunctionTest3() {
val sql = """
create or replace procedure prac_transfer(
sender int,
receiver int,
amount dec
)
LANGUAGE plpgsql
as ${'$'}${'$'}
DECLARE
max_rk int;
max_trade_time_length int;
max_trade_time character varying;
BEGIN
update accounts_1
set balance = balance - amount
where id = sender;
update accounts_2
set balance = balance + amount
where id = receiver;
commit;
END;${'$'}${'$'};
create or replace procedure prac_transfer1(
sender int,
receiver int,
amount dec
)
LANGUAGE plpgsql
as ${'$'}${'$'}
DECLARE
max_rk int;
max_trade_time_length int;
max_trade_time character varying;
BEGIN
update accounts_1
set balance = balance - amount
where id = sender;
update accounts_2
set balance = balance + amount
where id = receiver;
commit;
END;${'$'}${'$'};
""".trimIndent()
val statements = PostgreSqlHelper.parseMultiStatement(sql)
val statement = statements.get(0)
if (statement is CreateProcedure) {
Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)
Assert.assertEquals(ProcedureId( "prac_transfer"), statement.procedureId)
Assert.assertEquals(2, statement.childStatements.size)
} else {
Assert.fail()
}
}
@Test
fun createFunctionTest4() {
val sql = """
create or replace procedure prac_transfer(
sender int,
receiver int,
amount dec
)
RETURNS SETOF record
LANGUAGE plpgsql
NOT FENCED NOT SHIPPABLE
as ${'$'}${'$'}
BEGIN
update accounts
set balance = balance - amount
where id = sender;
update accounts
set balance = balance + amount
where id = receiver;
commit;
END;${'$'}${'$'};
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateProcedure) {
Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)
Assert.assertEquals(ProcedureId( "prac_transfer"), statement.procedureId)
Assert.assertEquals(2, statement.childStatements.size)
} else {
Assert.fail()
}
}
@Test
fun createFunctionTest5() {
val sql = """
CREATE OR REPLACE FUNCTION fetch_film_titles_and_years(
OUT p_title VARCHAR(255),
OUT p_release_year INTEGER
)
RETURNS SETOF RECORD
LANGUAGE plpgsql
AS ${'$'}${'$'}
DECLARE
film_cursor CURSOR FOR
SELECT title, release_year
FROM film;
film_record RECORD;
BEGIN
-- Open cursor
OPEN film_cursor;
-- Fetch rows and return
LOOP
FETCH NEXT FROM film_cursor INTO film_record;
EXIT WHEN NOT FOUND;
p_title = film_record.title;
p_release_year = film_record.release_year;
RETURN NEXT;
END LOOP;
-- Close cursor
CLOSE film_cursor;
update accounts
set balance = balance + amount
where id = receiver;
END;
${'$'}${'$'}
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateFunction) {
Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)
Assert.assertEquals(FunctionId( "fetch_film_titles_and_years"), statement.functionId)
Assert.assertEquals(2, statement.childStatements.size)
} else {
Assert.fail()
}
}
@Test
fun createFunctionTest6() {
val sql = """
create or replace procedure prac_transfer(
sender int,
receiver int,
amount dec
)
RETURNS SETOF record
LANGUAGE plpgsql
NOT FENCED NOT SHIPPABLE
as ${'$'}${'$'}
BEGIN
update accounts
set balance = balance - amount
where id = sender;
commit;
END;${'$'}${'$'};
create or replace procedure prac_transfer1(
sender int,
receiver int,
amount dec
)
RETURNS SETOF record
LANGUAGE plpgsql
NOT FENCED NOT SHIPPABLE
as ${'$'}${'$'}
BEGIN
update accounts_1
set balance = balance - amount
where id = sender;
commit;
END;${'$'}${'$'};
""".trimIndent()
val statements = PostgreSqlHelper.parseMultiStatement(sql)
Assert.assertEquals(2, statements.size)
var statement = statements.get(0)
if (statement is CreateProcedure) {
Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)
Assert.assertEquals(ProcedureId( "prac_transfer"), statement.procedureId)
Assert.assertEquals(1, statement.childStatements.size)
} else {
Assert.fail()
}
statement = statements.get(1)
if (statement is CreateProcedure) {
Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)
Assert.assertEquals(ProcedureId( "prac_transfer1"), statement.procedureId)
Assert.assertEquals(1, statement.childStatements.size)
Assert.assertEquals("update accounts_1\n" +
" set balance = balance - amount \n" +
" where id = sender", statement.childStatements.get(0).getSql())
} else {
Assert.fail()
}
}
@Test
fun processTest5() {
val sql = """
CREATE FUNCTION get_bal(acc_no IN NUMBER)
RETURNS SETOF record
LANGUAGE plpgsql
NOT FENCED NOT SHIPPABLE
as ${'$'}${'$'}
BEGIN
INSERT INTO widgets(map_id,widget_name)
SELECT mt.map_id, 'Bupo'
FROM map_tags mt
WHERE mt.map_license = '12345';
END ${'$'}${'$'};
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateFunction) {
Assert.assertEquals(StatementType.CREATE_FUNCTION, statement.statementType)
Assert.assertEquals(FunctionId("get_bal"), statement.functionId)
Assert.assertEquals(1, statement.childStatements.size)
Assert.assertEquals(StatementType.INSERT, statement.childStatements.get(0).statementType)
} else {
Assert.fail()
}
}
@Test
fun processTest6() {
val sql = """
create or replace procedure prac_transfer(
sender int,
receiver int,
amount dec
)
LANGUAGE plpgsql
as ${'$'}${'$'}
BEGIN
EXECUTE IMMEDIATE '
CREATE TABLE schema1.test_table_s1 (
id NUMBER PRIMARY KEY,
name VARCHAR2(100)
)
';
EXECUTE IMMEDIATE 'INSERT INTO schema1.test_table_s1 (id, name) VALUES (1, ''Alice'')';
END ${'$'}${'$'};
""".trimIndent()
val statement = PostgreSqlHelper.parseStatement(sql)
if (statement is CreateProcedure) {
Assert.assertEquals(StatementType.CREATE_PROCEDURE, statement.statementType)
Assert.assertEquals(ProcedureId("prac_transfer"), statement.procedureId)
Assert.assertEquals(2, statement.childStatements.size)
Assert.assertEquals(StatementType.CREATE_TABLE, statement.childStatements.get(0).statementType)
Assert.assertEquals(StatementType.INSERT, statement.childStatements.get(1).statementType)
Assert.assertEquals("INSERT INTO schema1.test_table_s1 (id, name) VALUES (1, 'Alice')", statement.childStatements.get(1).getSql())
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-postgres-parser/src/test/resources/log4j2.xml
================================================
================================================
FILE: superior-presto-parser/pom.xml
================================================
4.0.0
io.github.melin.superior
superior-sql-parser
4.0.23
superior-presto-parser
superior-presto-parser
io.github.melin.superior
superior-common-parser
${project.version}
================================================
FILE: superior-presto-parser/src/main/antlr4/io/github/melin/superior/parser/presto/antlr4/PrestoSqlBase.g4
================================================
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
grammar PrestoSqlBase;
tokens {
DELIMITER
}
sqlStatements
: singleStatement* EOF
;
singleStatement
: statement ';'?
;
standaloneExpression
: expression EOF
;
standaloneRoutineBody
: routineBody EOF
;
statement
: query #statementDefault
| USE schema=identifier #use
| USE catalog=identifier '.' schema=identifier #use
| CREATE SCHEMA (IF NOT EXISTS)? qualifiedName
(WITH properties)? #createSchema
| DROP SCHEMA (IF EXISTS)? qualifiedName (CASCADE | RESTRICT)? #dropSchema
| ALTER SCHEMA qualifiedName RENAME TO identifier #renameSchema
| CREATE TABLE (IF NOT EXISTS)? qualifiedName columnAliases?
(COMMENT string)?
(WITH properties)? AS (query | '('query')')
(WITH (NO)? DATA)? #createTableAsSelect
| CREATE TABLE (IF NOT EXISTS)? qualifiedName
'(' tableElement (',' tableElement)* ')'
(COMMENT string)?
(WITH properties)? #createTable
| DROP TABLE (IF EXISTS)? qualifiedName #dropTable
| INSERT INTO qualifiedName columnAliases? query #insertInto
| DELETE FROM qualifiedName whereClause? #delete
| TRUNCATE TABLE qualifiedName #truncateTable
| ALTER TABLE (IF EXISTS)? from=qualifiedName
RENAME TO to=qualifiedName #renameTable
| ALTER TABLE (IF EXISTS)? tableName=qualifiedName
RENAME COLUMN (IF EXISTS)? from=identifier TO to=identifier #renameColumn
| ALTER TABLE (IF EXISTS)? tableName=qualifiedName
DROP COLUMN (IF EXISTS)? column=qualifiedName #dropColumn
| ALTER TABLE (IF EXISTS)? tableName=qualifiedName
ADD COLUMN (IF NOT EXISTS)? column=columnDefinition #addColumn
| ANALYZE qualifiedName (WITH properties)? #analyze
| CREATE TYPE qualifiedName AS (
'(' sqlParameterDeclaration (',' sqlParameterDeclaration)* ')'
| type) #createType
| CREATE (OR REPLACE)? VIEW qualifiedName
(SECURITY (DEFINER | INVOKER))? AS query #createView
| DROP VIEW (IF EXISTS)? qualifiedName #dropView
| CREATE MATERIALIZED VIEW (IF NOT EXISTS)? qualifiedName
(COMMENT string)?
(WITH properties)? AS (query | '('query')') #createMaterializedView
| DROP MATERIALIZED VIEW (IF EXISTS)? qualifiedName #dropMaterializedView
| REFRESH MATERIALIZED VIEW qualifiedName WHERE booleanExpression #refreshMaterializedView
| CREATE (OR REPLACE)? TEMPORARY? FUNCTION functionName=qualifiedName
'(' (sqlParameterDeclaration (',' sqlParameterDeclaration)*)? ')'
RETURNS returnType=type
(COMMENT string)?
routineCharacteristics routineBody #createFunction
| ALTER FUNCTION qualifiedName types?
alterRoutineCharacteristics #alterFunction
| DROP TEMPORARY? FUNCTION (IF EXISTS)? qualifiedName types? #dropFunction
| CALL qualifiedName '(' (callArgument (',' callArgument)*)? ')' #call
| CREATE ROLE name=identifier
(WITH ADMIN grantor)? #createRole
| DROP ROLE name=identifier #dropRole
| GRANT
roles
TO principal (',' principal)*
(WITH ADMIN OPTION)?
(GRANTED BY grantor)? #grantRoles
| REVOKE
(ADMIN OPTION FOR)?
roles
FROM principal (',' principal)*
(GRANTED BY grantor)? #revokeRoles
| SET ROLE (ALL | NONE | role=identifier) #setRole
| GRANT
(privilege (',' privilege)* | ALL PRIVILEGES)
ON TABLE? qualifiedName TO grantee=principal
(WITH GRANT OPTION)? #grant
| REVOKE
(GRANT OPTION FOR)?
(privilege (',' privilege)* | ALL PRIVILEGES)
ON TABLE? qualifiedName FROM grantee=principal #revoke
| SHOW GRANTS
(ON TABLE? qualifiedName)? #showGrants
| EXPLAIN ANALYZE? VERBOSE?
('(' explainOption (',' explainOption)* ')')? statement #explain
| SHOW CREATE TABLE qualifiedName #showCreateTable
| SHOW CREATE VIEW qualifiedName #showCreateView
| SHOW CREATE MATERIALIZED VIEW qualifiedName #showCreateMaterializedView
| SHOW CREATE FUNCTION qualifiedName types? #showCreateFunction
| SHOW TABLES ((FROM | IN) qualifiedName)?
(LIKE pattern=string (ESCAPE escape=string)?)? #showTables
| SHOW SCHEMAS ((FROM | IN) identifier)?
(LIKE pattern=string (ESCAPE escape=string)?)? #showSchemas
| SHOW CATALOGS
(LIKE pattern=string (ESCAPE escape=string)?)? #showCatalogs
| SHOW COLUMNS (FROM | IN) qualifiedName #showColumns
| SHOW STATS FOR qualifiedName #showStats
| SHOW STATS FOR '(' querySpecification ')' #showStatsForQuery
| SHOW CURRENT? ROLES ((FROM | IN) identifier)? #showRoles
| SHOW ROLE GRANTS ((FROM | IN) identifier)? #showRoleGrants
| DESCRIBE qualifiedName #showColumns
| DESC qualifiedName #showColumns
| SHOW FUNCTIONS
(LIKE pattern=string (ESCAPE escape=string)?)? #showFunctions
| SHOW SESSION
(LIKE pattern=string (ESCAPE escape=string)?)? #showSession
| SET SESSION qualifiedName EQ expression #setSession
| RESET SESSION qualifiedName #resetSession
| START TRANSACTION (transactionMode (',' transactionMode)*)? #startTransaction
| COMMIT WORK? #commit
| ROLLBACK WORK? #rollback
| PREPARE identifier FROM statement #prepare
| DEALLOCATE PREPARE identifier #deallocate
| EXECUTE identifier (USING expression (',' expression)*)? #execute
| DESCRIBE INPUT identifier #describeInput
| DESCRIBE OUTPUT identifier #describeOutput
;
query
: with? queryNoWith
;
with
: WITH RECURSIVE? namedQuery (',' namedQuery)*
;
tableElement
: columnDefinition
| likeClause
;
columnDefinition
: identifier type (NOT NULL)? (COMMENT string)? (WITH properties)?
;
likeClause
: LIKE qualifiedName (optionType=(INCLUDING | EXCLUDING) PROPERTIES)?
;
properties
: '(' property (',' property)* ')'
;
property
: identifier EQ expression
;
sqlParameterDeclaration
: identifier type
;
routineCharacteristics
: routineCharacteristic*
;
routineCharacteristic
: LANGUAGE language
| determinism
| nullCallClause
;
alterRoutineCharacteristics
: alterRoutineCharacteristic*
;
alterRoutineCharacteristic
: nullCallClause
;
routineBody
: returnStatement
| externalBodyReference
;
returnStatement
: RETURN expression
;
externalBodyReference
: EXTERNAL (NAME externalRoutineName)?
;
language
: SQL
| identifier
;
determinism
: DETERMINISTIC
| NOT DETERMINISTIC;
nullCallClause
: RETURNS NULL ON NULL INPUT
| CALLED ON NULL INPUT
;
externalRoutineName
: identifier
;
queryNoWith:
queryTerm
(ORDER BY sortItem (',' sortItem)*)?
(OFFSET offset=INTEGER_VALUE (ROW | ROWS)?)?
((LIMIT limit=(INTEGER_VALUE | ALL) | (FETCH FIRST fetchFirstNRows=INTEGER_VALUE ROWS ONLY))?)?
;
queryTerm
: queryPrimary #queryTermDefault
| left=queryTerm operator=INTERSECT setQuantifier? right=queryTerm #setOperation
| left=queryTerm operator=(UNION | EXCEPT) setQuantifier? right=queryTerm #setOperation
;
queryPrimary
: querySpecification #queryPrimaryDefault
| TABLE qualifiedName #table
| VALUES expression (',' expression)* #inlineTable
| '(' queryNoWith ')' #subquery
;
sortItem
: expression ordering=(ASC | DESC)? (NULLS nullOrdering=(FIRST | LAST))?
;
querySpecification
: SELECT setQuantifier? selectItem (',' selectItem)*
(FROM relation (',' relation)*)?
(WHERE where=booleanExpression)?
(GROUP BY groupBy)?
(HAVING having=booleanExpression)?
;
groupBy
: setQuantifier? groupingElement (',' groupingElement)*
;
groupingElement
: groupingSet #singleGroupingSet
| ROLLUP '(' (expression (',' expression)*)? ')' #rollup
| CUBE '(' (expression (',' expression)*)? ')' #cube
| GROUPING SETS '(' groupingSet (',' groupingSet)* ')' #multipleGroupingSets
;
groupingSet
: '(' (expression (',' expression)*)? ')'
| expression
;
namedQuery
: name=identifier (columnAliases)? AS '(' query ')'
;
setQuantifier
: DISTINCT
| ALL
;
selectItem
: expression (AS? identifier)? #selectSingle
| qualifiedName '.' ASTERISK #selectAll
| ASTERISK #selectAll
;
relation
: left=relation
( CROSS JOIN right=sampledRelation
| joinType JOIN rightRelation=relation joinCriteria
| NATURAL joinType JOIN right=sampledRelation
) #joinRelation
| sampledRelation #relationDefault
;
joinType
: INNER?
| LEFT OUTER?
| RIGHT OUTER?
| FULL OUTER?
;
joinCriteria
: ON booleanExpression
| USING '(' identifier (',' identifier)* ')'
;
sampledRelation
: aliasedRelation (
TABLESAMPLE sampleType '(' percentage=expression ')'
)?
;
sampleType
: BERNOULLI
| SYSTEM
;
aliasedRelation
: relationPrimary (AS? identifier columnAliases?)?
;
columnAliases
: '(' identifier (',' identifier)* ')'
;
relationPrimary
: qualifiedName #tableName
| '(' query ')' #subqueryRelation
| UNNEST '(' expression (',' expression)* ')' (WITH ORDINALITY)? #unnest
| LATERAL '(' query ')' #lateral
| '(' relation ')' #parenthesizedRelation
;
expression
: booleanExpression
;
whereClause
: WHERE booleanExpression
;
booleanExpression
: valueExpression predicate[$valueExpression.ctx]? #predicated
| NOT booleanExpression #logicalNot
| left=booleanExpression operator=AND right=booleanExpression #logicalBinary
| left=booleanExpression operator=OR right=booleanExpression #logicalBinary
;
// workaround for https://github.com/antlr/antlr4/issues/780
predicate[ParserRuleContext value]
: comparisonOperator right=valueExpression #comparison
| comparisonOperator comparisonQuantifier '(' query ')' #quantifiedComparison
| NOT? BETWEEN lower=valueExpression AND upper=valueExpression #between
| NOT? IN '(' expression (',' expression)* ')' #inList
| NOT? IN '(' query ')' #inSubquery
| NOT? LIKE pattern=valueExpression (ESCAPE escape=valueExpression)? #like
| IS NOT? NULL #nullPredicate
| IS NOT? DISTINCT FROM right=valueExpression #distinctFrom
;
valueExpression
: primaryExpression #valueExpressionDefault
| valueExpression AT timeZoneSpecifier #atTimeZone
| operator=(MINUS | PLUS) valueExpression #arithmeticUnary
| left=valueExpression operator=(ASTERISK | SLASH | PERCENT) right=valueExpression #arithmeticBinary
| left=valueExpression operator=(PLUS | MINUS) right=valueExpression #arithmeticBinary
| left=valueExpression CONCAT right=valueExpression #concatenation
;
primaryExpression
: NULL #nullLiteral
| interval #intervalLiteral
| identifier string #typeConstructor
| DOUBLE_PRECISION string #typeConstructor
| number #numericLiteral
| booleanValue #booleanLiteral
| string #stringLiteral
| BINARY_LITERAL #binaryLiteral
| '?' #parameter
| POSITION '(' valueExpression IN valueExpression ')' #position
| '(' expression (',' expression)+ ')' #rowConstructor
| ROW '(' expression (',' expression)* ')' #rowConstructor
| qualifiedName '(' ASTERISK ')' filter? over? #functionCall
| qualifiedName '(' (setQuantifier? expression (',' expression)*)?
(ORDER BY sortItem (',' sortItem)*)? ')' filter? (nullTreatment? over)? #functionCall
| identifier '->' expression #lambda
| '(' (identifier (',' identifier)*)? ')' '->' expression #lambda
| '(' query ')' #subqueryExpression
// This is an extension to ANSI SQL, which considers EXISTS to be a
| EXISTS '(' query ')' #exists
| CASE valueExpression whenClause+ (ELSE elseExpression=expression)? END #simpleCase
| CASE whenClause+ (ELSE elseExpression=expression)? END #searchedCase
| CAST '(' expression AS type ')' #cast
| TRY_CAST '(' expression AS type ')' #cast
| ARRAY '[' (expression (',' expression)*)? ']' #arrayConstructor
| value=primaryExpression '[' index=valueExpression ']' #subscript
| identifier #columnReference
| base=primaryExpression '.' fieldName=identifier #dereference
| name=CURRENT_DATE #specialDateTimeFunction
| name=CURRENT_TIME ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction
| name=CURRENT_TIMESTAMP ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction
| name=LOCALTIME ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction
| name=LOCALTIMESTAMP ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction
| name=CURRENT_USER #currentUser
| SUBSTRING '(' valueExpression FROM valueExpression (FOR valueExpression)? ')' #substring
| NORMALIZE '(' valueExpression (',' normalForm)? ')' #normalize
| EXTRACT '(' identifier FROM valueExpression ')' #extract
| '(' expression ')' #parenthesizedExpression
| GROUPING '(' (qualifiedName (',' qualifiedName)*)? ')' #groupingOperation
;
string
: STRING #basicStringLiteral
| UNICODE_STRING (UESCAPE STRING)? #unicodeStringLiteral
;
nullTreatment
: IGNORE NULLS
| RESPECT NULLS
;
timeZoneSpecifier
: TIME ZONE interval #timeZoneInterval
| TIME ZONE string #timeZoneString
;
comparisonOperator
: EQ | NEQ | LT | LTE | GT | GTE
;
comparisonQuantifier
: ALL | SOME | ANY
;
booleanValue
: TRUE | FALSE
;
interval
: INTERVAL sign=(PLUS | MINUS)? string from=intervalField (TO to=intervalField)?
;
intervalField
: YEAR | MONTH | DAY | HOUR | MINUTE | SECOND
;
normalForm
: NFD | NFC | NFKD | NFKC
;
types
: '(' (type (',' type)*)? ')'
;
type
: type ARRAY
| ARRAY '<' type '>'
| MAP '<' type ',' type '>'
| ROW '(' identifier type (',' identifier type)* ')'
| baseType ('(' typeParameter (',' typeParameter)* ')')?
| INTERVAL from=intervalField TO to=intervalField
;
typeParameter
: INTEGER_VALUE | type
;
baseType
: TIME_WITH_TIME_ZONE
| TIMESTAMP_WITH_TIME_ZONE
| DOUBLE_PRECISION
| qualifiedName
;
whenClause
: WHEN condition=expression THEN result=expression
;
filter
: FILTER '(' WHERE booleanExpression ')'
;
over
: OVER '('
(PARTITION BY partition+=expression (',' partition+=expression)*)?
(ORDER BY sortItem (',' sortItem)*)?
windowFrame?
')'
;
windowFrame
: frameType=RANGE start=frameBound
| frameType=ROWS start=frameBound
| frameType=GROUPS start=frameBound
| frameType=RANGE BETWEEN start=frameBound AND end=frameBound
| frameType=ROWS BETWEEN start=frameBound AND end=frameBound
| frameType=GROUPS BETWEEN start=frameBound AND end=frameBound
;
frameBound
: UNBOUNDED boundType=PRECEDING #unboundedFrame
| UNBOUNDED boundType=FOLLOWING #unboundedFrame
| CURRENT ROW #currentRowBound
| expression boundType=(PRECEDING | FOLLOWING) #boundedFrame // expression should be unsignedLiteral
;
explainOption
: FORMAT value=(TEXT | GRAPHVIZ | JSON) #explainFormat
| TYPE value=(LOGICAL | DISTRIBUTED | VALIDATE | IO) #explainType
;
transactionMode
: ISOLATION LEVEL levelOfIsolation #isolationLevel
| READ accessMode=(ONLY | WRITE) #transactionAccessMode
;
levelOfIsolation
: READ UNCOMMITTED #readUncommitted
| READ COMMITTED #readCommitted
| REPEATABLE READ #repeatableRead
| SERIALIZABLE #serializable
;
callArgument
: expression #positionalArgument
| identifier '=>' expression #namedArgument
;
privilege
: SELECT | DELETE | INSERT | identifier
;
qualifiedName
: identifier ('.' identifier)*
;
grantor
: CURRENT_USER #currentUserGrantor
| CURRENT_ROLE #currentRoleGrantor
| principal #specifiedPrincipal
;
principal
: USER identifier #userPrincipal
| ROLE identifier #rolePrincipal
| identifier #unspecifiedPrincipal
;
roles
: identifier (',' identifier)*
;
identifier
: IDENTIFIER #unquotedIdentifier
| QUOTED_IDENTIFIER #quotedIdentifier
| nonReserved #unquotedIdentifier
| BACKQUOTED_IDENTIFIER #backQuotedIdentifier
| DIGIT_IDENTIFIER #digitIdentifier
;
number
: DECIMAL_VALUE #decimalLiteral
| DOUBLE_VALUE #doubleLiteral
| INTEGER_VALUE #integerLiteral
;
nonReserved
// IMPORTANT: this rule must only contain tokens. Nested rules are not supported. See SqlParser.exitNonReserved
: ADD | ADMIN | ALL | ANALYZE | ANY | ARRAY | ASC | AT
| BERNOULLI
| CALL | CALLED | CASCADE | CATALOGS | COLUMN | COLUMNS | COMMENT | COMMIT | COMMITTED | CURRENT | CURRENT_ROLE
| DATA | DATE | DAY | DEFINER | DESC | DETERMINISTIC | DISTRIBUTED
| EXCLUDING | EXPLAIN | EXTERNAL
| FETCH | FILTER | FIRST | FOLLOWING | FORMAT | FUNCTION | FUNCTIONS
| GRANT | GRANTED | GRANTS | GRAPHVIZ | GROUPS
| HOUR
| IF | IGNORE | INCLUDING | INPUT | INTERVAL | INVOKER | IO | ISOLATION
| JSON
| LANGUAGE | LAST | LATERAL | LEVEL | LIMIT | LOGICAL
| MAP | MATERIALIZED | MINUTE | MONTH
| NAME | NFC | NFD | NFKC | NFKD | NO | NONE | NULLIF | NULLS
| OFFSET | ONLY | OPTION | ORDINALITY | OUTPUT | OVER
| PARTITION | PARTITIONS | POSITION | PRECEDING | PRIVILEGES | PROPERTIES
| RANGE | READ | REFRESH | RENAME | REPEATABLE | REPLACE | RESET | RESPECT | RESTRICT | RETURN | RETURNS | REVOKE | ROLE | ROLES | ROLLBACK | ROW | ROWS
| SCHEMA | SCHEMAS | SECOND | SECURITY | SERIALIZABLE | SESSION | SET | SETS | SQL
| SHOW | SOME | START | STATS | SUBSTRING | SYSTEM
| TABLES | TABLESAMPLE | TEMPORARY | TEXT | TIME | TIMESTAMP | TO | TRANSACTION | TRUNCATE | TRY_CAST | TYPE
| UNBOUNDED | UNCOMMITTED | USE | USER
| VALIDATE | VERBOSE | VIEW
| WORK | WRITE
| YEAR
| ZONE
;
ADD: 'ADD';
ADMIN: 'ADMIN';
ALL: 'ALL';
ALTER: 'ALTER';
ANALYZE: 'ANALYZE';
AND: 'AND';
ANY: 'ANY';
ARRAY: 'ARRAY';
AS: 'AS';
ASC: 'ASC';
AT: 'AT';
BERNOULLI: 'BERNOULLI';
BETWEEN: 'BETWEEN';
BY: 'BY';
CALL: 'CALL';
CALLED: 'CALLED';
CASCADE: 'CASCADE';
CASE: 'CASE';
CAST: 'CAST';
CATALOGS: 'CATALOGS';
COLUMN: 'COLUMN';
COLUMNS: 'COLUMNS';
COMMENT: 'COMMENT';
COMMIT: 'COMMIT';
COMMITTED: 'COMMITTED';
CONSTRAINT: 'CONSTRAINT';
CREATE: 'CREATE';
CROSS: 'CROSS';
CUBE: 'CUBE';
CURRENT: 'CURRENT';
CURRENT_DATE: 'CURRENT_DATE';
CURRENT_ROLE: 'CURRENT_ROLE';
CURRENT_TIME: 'CURRENT_TIME';
CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP';
CURRENT_USER: 'CURRENT_USER';
DATA: 'DATA';
DATE: 'DATE';
DAY: 'DAY';
DEALLOCATE: 'DEALLOCATE';
DEFINER: 'DEFINER';
DELETE: 'DELETE';
DESC: 'DESC';
DESCRIBE: 'DESCRIBE';
DETERMINISTIC: 'DETERMINISTIC';
DISTINCT: 'DISTINCT';
DISTRIBUTED: 'DISTRIBUTED';
DROP: 'DROP';
ELSE: 'ELSE';
END: 'END';
ESCAPE: 'ESCAPE';
EXCEPT: 'EXCEPT';
EXCLUDING: 'EXCLUDING';
EXECUTE: 'EXECUTE';
EXISTS: 'EXISTS';
EXPLAIN: 'EXPLAIN';
EXTRACT: 'EXTRACT';
EXTERNAL: 'EXTERNAL';
FALSE: 'FALSE';
FETCH: 'FETCH';
FILTER: 'FILTER';
FIRST: 'FIRST';
FOLLOWING: 'FOLLOWING';
FOR: 'FOR';
FORMAT: 'FORMAT';
FROM: 'FROM';
FULL: 'FULL';
FUNCTION: 'FUNCTION';
FUNCTIONS: 'FUNCTIONS';
GRANT: 'GRANT';
GRANTED: 'GRANTED';
GRANTS: 'GRANTS';
GRAPHVIZ: 'GRAPHVIZ';
GROUP: 'GROUP';
GROUPING: 'GROUPING';
GROUPS: 'GROUPS';
HAVING: 'HAVING';
HOUR: 'HOUR';
IF: 'IF';
IGNORE: 'IGNORE';
IN: 'IN';
INCLUDING: 'INCLUDING';
INNER: 'INNER';
INPUT: 'INPUT';
INSERT: 'INSERT';
INTERSECT: 'INTERSECT';
INTERVAL: 'INTERVAL';
INTO: 'INTO';
INVOKER: 'INVOKER';
IO: 'IO';
IS: 'IS';
ISOLATION: 'ISOLATION';
JSON: 'JSON';
JOIN: 'JOIN';
LANGUAGE: 'LANGUAGE';
LAST: 'LAST';
LATERAL: 'LATERAL';
LEFT: 'LEFT';
LEVEL: 'LEVEL';
LIKE: 'LIKE';
LIMIT: 'LIMIT';
LOCALTIME: 'LOCALTIME';
LOCALTIMESTAMP: 'LOCALTIMESTAMP';
LOGICAL: 'LOGICAL';
MAP: 'MAP';
MATERIALIZED: 'MATERIALIZED';
MINUTE: 'MINUTE';
MONTH: 'MONTH';
NAME: 'NAME';
NATURAL: 'NATURAL';
NFC : 'NFC';
NFD : 'NFD';
NFKC : 'NFKC';
NFKD : 'NFKD';
NO: 'NO';
NONE: 'NONE';
NORMALIZE: 'NORMALIZE';
NOT: 'NOT';
NULL: 'NULL';
NULLIF: 'NULLIF';
NULLS: 'NULLS';
OFFSET: 'OFFSET';
ON: 'ON';
ONLY: 'ONLY';
OPTION: 'OPTION';
OR: 'OR';
ORDER: 'ORDER';
ORDINALITY: 'ORDINALITY';
OUTER: 'OUTER';
OUTPUT: 'OUTPUT';
OVER: 'OVER';
PARTITION: 'PARTITION';
PARTITIONS: 'PARTITIONS';
POSITION: 'POSITION';
PRECEDING: 'PRECEDING';
PREPARE: 'PREPARE';
PRIVILEGES: 'PRIVILEGES';
PROPERTIES: 'PROPERTIES';
RANGE: 'RANGE';
READ: 'READ';
RECURSIVE: 'RECURSIVE';
REFRESH: 'REFRESH';
RENAME: 'RENAME';
REPEATABLE: 'REPEATABLE';
REPLACE: 'REPLACE';
RESET: 'RESET';
RESPECT: 'RESPECT';
RESTRICT: 'RESTRICT';
RETURN: 'RETURN';
RETURNS: 'RETURNS';
REVOKE: 'REVOKE';
RIGHT: 'RIGHT';
ROLE: 'ROLE';
ROLES: 'ROLES';
ROLLBACK: 'ROLLBACK';
ROLLUP: 'ROLLUP';
ROW: 'ROW';
ROWS: 'ROWS';
SCHEMA: 'SCHEMA';
SCHEMAS: 'SCHEMAS';
SECOND: 'SECOND';
SECURITY: 'SECURITY';
SELECT: 'SELECT';
SERIALIZABLE: 'SERIALIZABLE';
SESSION: 'SESSION';
SET: 'SET';
SETS: 'SETS';
SHOW: 'SHOW';
SOME: 'SOME';
SQL: 'SQL';
START: 'START';
STATS: 'STATS';
SUBSTRING: 'SUBSTRING';
SYSTEM: 'SYSTEM';
TABLE: 'TABLE';
TABLES: 'TABLES';
TABLESAMPLE: 'TABLESAMPLE';
TEMPORARY: 'TEMPORARY';
TEXT: 'TEXT';
THEN: 'THEN';
TIME: 'TIME';
TIMESTAMP: 'TIMESTAMP';
TO: 'TO';
TRANSACTION: 'TRANSACTION';
TRUE: 'TRUE';
TRUNCATE: 'TRUNCATE';
TRY_CAST: 'TRY_CAST';
TYPE: 'TYPE';
UESCAPE: 'UESCAPE';
UNBOUNDED: 'UNBOUNDED';
UNCOMMITTED: 'UNCOMMITTED';
UNION: 'UNION';
UNNEST: 'UNNEST';
USE: 'USE';
USER: 'USER';
USING: 'USING';
VALIDATE: 'VALIDATE';
VALUES: 'VALUES';
VERBOSE: 'VERBOSE';
VIEW: 'VIEW';
WHEN: 'WHEN';
WHERE: 'WHERE';
WITH: 'WITH';
WORK: 'WORK';
WRITE: 'WRITE';
YEAR: 'YEAR';
ZONE: 'ZONE';
EQ : '=';
NEQ : '<>' | '!=';
LT : '<';
LTE : '<=';
GT : '>';
GTE : '>=';
PLUS: '+';
MINUS: '-';
ASTERISK: '*';
SLASH: '/';
PERCENT: '%';
CONCAT: '||';
STRING
: '\'' ( ~'\'' | '\'\'' )* '\''
;
UNICODE_STRING
: 'U&\'' ( ~'\'' | '\'\'' )* '\''
;
// Note: we allow any character inside the binary literal and validate
// its a correct literal when the AST is being constructed. This
// allows us to provide more meaningful error messages to the user
BINARY_LITERAL
: 'X\'' (~'\'')* '\''
;
INTEGER_VALUE
: DIGIT+
;
DECIMAL_VALUE
: DIGIT+ '.' DIGIT*
| '.' DIGIT+
;
DOUBLE_VALUE
: DIGIT+ ('.' DIGIT*)? EXPONENT
| '.' DIGIT+ EXPONENT
;
IDENTIFIER
: (LETTER | '_') (LETTER | DIGIT | '_' | '@' | ':')*
;
DIGIT_IDENTIFIER
: DIGIT (LETTER | DIGIT | '_' | '@' | ':')+
;
QUOTED_IDENTIFIER
: '"' ( ~'"' | '""' )* '"'
;
BACKQUOTED_IDENTIFIER
: '`' ( ~'`' | '``' )* '`'
;
TIME_WITH_TIME_ZONE
: 'TIME' WS 'WITH' WS 'TIME' WS 'ZONE'
;
TIMESTAMP_WITH_TIME_ZONE
: 'TIMESTAMP' WS 'WITH' WS 'TIME' WS 'ZONE'
;
DOUBLE_PRECISION
: 'DOUBLE' WS 'PRECISION'
;
fragment EXPONENT
: 'E' [+-]? DIGIT+
;
fragment DIGIT
: [0-9]
;
fragment LETTER
: [A-Z]
;
SIMPLE_COMMENT
: '--' ~[\r\n]* '\r'? '\n'? -> channel(HIDDEN)
;
BRACKETED_COMMENT
: '/*' .*? '*/' -> channel(HIDDEN)
;
WS
: [ \r\n\t]+ -> channel(HIDDEN)
;
// Catch-all for anything we can't recognize.
// We use this to be able to ignore and recover all the text
// when splitting statements with DelimiterLexer
UNRECOGNIZED
: .
;
================================================
FILE: superior-presto-parser/src/main/java/io/github/melin/superior/parser/presto/CaseInsensitiveStream.java
================================================
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.github.melin.superior.parser.presto;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.IntStream;
import org.antlr.v4.runtime.misc.Interval;
public class CaseInsensitiveStream implements CharStream {
private final CharStream stream;
public CaseInsensitiveStream(CharStream stream) {
this.stream = stream;
}
@Override
public String getText(Interval interval) {
return stream.getText(interval);
}
@Override
public void consume() {
stream.consume();
}
@Override
public int LA(int i) {
int result = stream.LA(i);
switch (result) {
case 0:
case IntStream.EOF:
return result;
default:
return Character.toUpperCase(result);
}
}
@Override
public int mark() {
return stream.mark();
}
@Override
public void release(int marker) {
stream.release(marker);
}
@Override
public int index() {
return stream.index();
}
@Override
public void seek(int index) {
stream.seek(index);
}
@Override
public int size() {
return stream.size();
}
@Override
public String getSourceName() {
return stream.getSourceName();
}
}
================================================
FILE: superior-presto-parser/src/main/kotlin/io/github/melin/superior/parser/presto/AbstractSqlParser.kt
================================================
package io.github.melin.superior.parser.presto
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseParser
import java.util.concurrent.atomic.AtomicReference
object AbstractSqlParser {
private val parserCaches = AtomicReference(AntlrCaches(PrestoSqlBaseParser._ATN))
/**
* Install the parser caches into the given parser.
*
* This method should be called before parsing any input.
*/
fun installCaches(parser: PrestoSqlBaseParser): Unit = parserCaches.get().installCaches(parser)
/**
* Drop the existing parser caches and create a new one.
*
* ANTLR retains caches in its parser that are never released. This speeds up parsing of future input, but it can
* consume a lot of memory depending on the input seen so far.
*
* This method provides a mechanism to free the retained caches, which can be useful after parsing very large SQL
* inputs, especially if those large inputs are unlikely to be similar to future inputs seen by the driver.
*/
fun refreshParserCaches() {
parserCaches.set(AntlrCaches(PrestoSqlBaseParser._ATN))
}
}
================================================
FILE: superior-presto-parser/src/main/kotlin/io/github/melin/superior/parser/presto/PrestoSqlAntlr4Visitor.kt
================================================
package io.github.melin.superior.parser.presto
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.*
import io.github.melin.superior.common.antlr4.ParserUtils.source
import io.github.melin.superior.common.relational.DefaultStatement
import io.github.melin.superior.common.relational.FunctionId
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.common.relational.TableId
import io.github.melin.superior.common.relational.common.ShowStatement
import io.github.melin.superior.common.relational.create.CreateTableAsSelect
import io.github.melin.superior.common.relational.dml.DeleteTable
import io.github.melin.superior.common.relational.dml.InsertMode
import io.github.melin.superior.common.relational.dml.InsertTable
import io.github.melin.superior.common.relational.dml.QueryStmt
import io.github.melin.superior.common.relational.drop.DropTable
import io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseBaseVisitor
import io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseParser
import org.antlr.v4.runtime.tree.RuleNode
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2018/1/10. */
class PrestoSqlAntlr4Visitor(val splitSql: Boolean = false, val command: String?) :
PrestoSqlBaseBaseVisitor() {
private var currentOptType: StatementType = StatementType.UNKOWN
private var limit: Int? = null
private var offset: Int? = null
private var inputTables: ArrayList = arrayListOf()
private var cteTempTables: ArrayList = arrayListOf()
private var functionNames: HashSet = hashSetOf()
private var statements: ArrayList = arrayListOf()
private val sqls: ArrayList = arrayListOf()
fun getSqlStatements(): List {
return statements
}
fun getSplitSqls(): List {
return sqls
}
override fun shouldVisitNextChild(node: RuleNode, currentResult: Statement?): Boolean {
return if (currentResult == null) true else false
}
override fun visitSqlStatements(ctx: PrestoSqlBaseParser.SqlStatementsContext): Statement? {
ctx.singleStatement().forEach {
var sql = source(it)
if (splitSql) {
if (StringUtils.endsWith(sql, ";")) {
sql = StringUtils.substringBeforeLast(sql, ";")
}
sqls.add(sql)
} else {
val startNode = it.start.text
val statement =
if (StringUtils.equalsIgnoreCase("show", startNode)) {
val keyWords: ArrayList = arrayListOf()
CommonUtils.findShowStatementKeyWord(keyWords, it)
ShowStatement(*keyWords.toTypedArray())
} else {
var statement = this.visitSingleStatement(it)
if (statement == null) {
statement = DefaultStatement(StatementType.UNKOWN)
}
statement
}
statement.setSql(sql)
statements.add(statement)
clean()
}
}
return null
}
private fun clean() {
currentOptType = StatementType.UNKOWN
limit = null
offset = null
inputTables = arrayListOf()
cteTempTables = arrayListOf()
}
override fun visitStatementDefault(ctx: PrestoSqlBaseParser.StatementDefaultContext): Statement? {
if (StringUtils.equalsIgnoreCase("select", ctx.start.text)) {
currentOptType = StatementType.SELECT
super.visitQuery(ctx.query())
val limit = ctx.query()?.queryNoWith()?.limit?.text?.toInt()
return QueryStmt(inputTables, limit)
} else {
return null
}
}
private fun parseQuery(ctx: PrestoSqlBaseParser.QueryContext): QueryStmt {
currentOptType = StatementType.SELECT
this.visitQuery(ctx)
val queryStmt = QueryStmt(inputTables, limit, offset)
queryStmt.functionNames.addAll(functionNames)
val querySql = source(ctx)
queryStmt.setSql(querySql)
return queryStmt
}
override fun visitCreateTableAsSelect(ctx: PrestoSqlBaseParser.CreateTableAsSelectContext): Statement? {
currentOptType = StatementType.CREATE_TABLE_AS_SELECT
val tableId = parseTableName(ctx.qualifiedName())
val queryStmt = parseQuery(ctx.query())
val createTable = CreateTableAsSelect(tableId, queryStmt)
createTable.lifeCycle = 7
return createTable
}
override fun visitInsertInto(ctx: PrestoSqlBaseParser.InsertIntoContext): Statement {
val tableId = parseTableName(ctx.qualifiedName())
val queryStmt = parseQuery(ctx.query())
val stmt = InsertTable(InsertMode.INTO, queryStmt, tableId)
return stmt
}
override fun visitDelete(ctx: PrestoSqlBaseParser.DeleteContext): Statement {
currentOptType = StatementType.DELETE
val tableId = parseTableName(ctx.qualifiedName())
if (ctx.whereClause() != null) {
super.visitWhereClause(ctx.whereClause())
}
return DeleteTable(tableId, inputTables)
}
override fun visitDropTable(ctx: PrestoSqlBaseParser.DropTableContext): Statement? {
val tableId = parseTableName(ctx.qualifiedName())
val dropTable = DropTable(tableId)
dropTable.ifExists = ctx.EXISTS() != null
return dropTable
}
override fun visitExplain(ctx: PrestoSqlBaseParser.ExplainContext): Statement? {
return DefaultStatement(StatementType.EXPLAIN)
}
override fun visitQualifiedName(ctx: PrestoSqlBaseParser.QualifiedNameContext): Statement? {
if (!(ctx.parent is PrestoSqlBaseParser.TableNameContext)) {
return null
}
if (
currentOptType == StatementType.SELECT ||
currentOptType == StatementType.INSERT ||
currentOptType == StatementType.UPDATE ||
currentOptType == StatementType.DELETE ||
currentOptType == StatementType.CREATE_TABLE_AS_SELECT
) {
val tableName = parseTableName(ctx)
inputTables.add(tableName)
}
return null
}
private fun parseTableName(ctx: PrestoSqlBaseParser.QualifiedNameContext): TableId {
val list = ctx.identifier()
var catalogName: String? = null
var databaseName: String? = null
val tableName =
if (list.size == 1) {
ctx.text
} else if (list.size == 2) {
val index = StringUtils.lastIndexOf(ctx.text, ".")
databaseName = StringUtils.substring(ctx.text, 0, index)
StringUtils.substring(ctx.text, index + 1)
} else {
val items = StringUtils.split(ctx.text, ".")
catalogName = items[0]
databaseName = items[1]
items[2]
}
return TableId(catalogName, databaseName, tableName)
}
}
================================================
FILE: superior-presto-parser/src/main/kotlin/io/github/melin/superior/parser/presto/PrestoSqlHelper.kt
================================================
package io.github.melin.superior.parser.presto
import com.github.melin.superior.sql.parser.util.CommonUtils
import io.github.melin.superior.common.antlr4.AntlrCaches
import io.github.melin.superior.common.antlr4.ParseErrorListener
import io.github.melin.superior.common.antlr4.ParseException
import io.github.melin.superior.common.relational.Statement
import io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseBaseVisitor
import io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseLexer
import io.github.melin.superior.parser.presto.antlr4.PrestoSqlBaseParser
import org.antlr.v4.runtime.CharStreams
import org.antlr.v4.runtime.CommonTokenStream
import org.antlr.v4.runtime.atn.PredictionMode
import org.antlr.v4.runtime.misc.ParseCancellationException
import org.apache.commons.lang3.StringUtils
/** Created by libinsong on 2018/1/10. */
object PrestoSqlHelper {
@JvmStatic
fun sqlKeywords(): List {
val keywords = hashSetOf()
(0 until PrestoSqlBaseLexer.VOCABULARY.maxTokenType).forEach { idx ->
val name = PrestoSqlBaseLexer.VOCABULARY.getLiteralName(idx)
if (name != null) {
val matchResult = CommonUtils.KEYWORD_REGEX.find(name)
if (matchResult != null) {
keywords.add(matchResult.groupValues.get(1))
}
}
}
return keywords.sorted()
}
@JvmStatic
fun parseStatement(command: String): Statement {
val statements = this.parseMultiStatement(command)
if (statements.size != 1) {
throw IllegalStateException("only parser one sql, sql count: " + statements.size)
} else {
return statements.get(0)
}
}
@JvmStatic
fun parseMultiStatement(command: String): List {
val trimCmd = StringUtils.trim(command)
val sqlVisitor = PrestoSqlAntlr4Visitor(false, trimCmd)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSqlStatements()
}
@JvmStatic
fun splitSql(command: String): List {
val trimCmd = StringUtils.trim(command)
val sqlVisitor = PrestoSqlAntlr4Visitor(true, trimCmd)
innerParseStatement(trimCmd, sqlVisitor)
return sqlVisitor.getSplitSqls()
}
@JvmStatic
fun checkSqlSyntax(command: String) {
val sqlVisitor = PrestoSqlBaseBaseVisitor()
innerParseStatement(command, sqlVisitor)
}
private fun innerParseStatement(command: String, sqlVisitor: PrestoSqlBaseBaseVisitor) {
val charStream = CaseInsensitiveStream(CharStreams.fromString(command))
val lexer = PrestoSqlBaseLexer(charStream)
lexer.removeErrorListeners()
lexer.addErrorListener(ParseErrorListener())
val tokenStream = CommonTokenStream(lexer)
val parser = PrestoSqlBaseParser(tokenStream)
AbstractSqlParser.installCaches(parser)
parser.removeErrorListeners()
parser.addErrorListener(ParseErrorListener())
parser.interpreter.predictionMode = PredictionMode.SLL
try {
try {
// first, try parsing with potentially faster SLL mode
sqlVisitor.visit(parser.sqlStatements())
} catch (e: ParseCancellationException) {
tokenStream.seek(0) // rewind input stream
parser.reset()
// Try Again.
parser.interpreter.predictionMode = PredictionMode.LL
sqlVisitor.visit(parser.sqlStatements())
}
} catch (e: ParseException) {
if (StringUtils.isNotBlank(e.command)) {
throw e
} else {
throw e.withCommand(command)
}
} finally {
val releaseAntlrCache = System.getenv(AntlrCaches.RELEASE_ANTLR_CACHE_AFTER_PARSING)
if (releaseAntlrCache == null || "true".equals(releaseAntlrCache)) {
AbstractSqlParser.refreshParserCaches()
}
}
}
}
================================================
FILE: superior-presto-parser/src/test/kotlin/io/github/melin/superior/parser/presto/PrestoSqlParserTest.kt
================================================
package io.github.melin.superior.parser.presto
import io.github.melin.superior.common.StatementType
import io.github.melin.superior.common.relational.create.CreateTableAsSelect
import io.github.melin.superior.common.relational.dml.DeleteTable
import io.github.melin.superior.common.relational.dml.InsertTable
import io.github.melin.superior.common.relational.dml.QueryStmt
import io.github.melin.superior.common.relational.drop.DropTable
import org.junit.Assert
import org.junit.Test
/** Created by libinsong on 2018/1/10. */
class PrestoSqlParserTest {
@Test
fun queryTest0() {
val sql =
"""
select a.* from datacompute1.datacompute.dc_job a left join datacompute1.datacompute.dc_job_scheduler b on a.id=b.job_id
"""
.trimIndent()
val statement = PrestoSqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(2, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun queryTest1() {
val sql =
"""
SELECT COUNT(app_name) AS "应用名" FROM (SELECT * FROM ops.dwd_app_to_container_wt
WHERE ds=date_format(CURRENT_DATE - interval '1' DAY, "%Y%m%d") ) tdbi_view
"""
.trimIndent()
val statement = PrestoSqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun queryLimitTest() {
val sql =
"""
select * from preso_table limit 10
"""
.trimIndent()
val statement = PrestoSqlHelper.parseStatement(sql)
if (statement is QueryStmt) {
Assert.assertEquals(StatementType.SELECT, statement.statementType)
Assert.assertEquals(1, statement.inputTables.size)
Assert.assertEquals(10, statement.limit)
} else {
Assert.fail()
}
}
@Test
fun createTableSelectTest() {
val sql =
"""
create table dd_s_s as select * from bigdata.test_demo_test limit 1
"""
.trimIndent()
val statement = PrestoSqlHelper.parseStatement(sql)
if (statement is CreateTableAsSelect) {
Assert.assertEquals(StatementType.CREATE_TABLE_AS_SELECT, statement.statementType)
Assert.assertEquals("dd_s_s", statement.tableId.tableName)
Assert.assertEquals(1, statement.queryStmt.inputTables.size)
} else {
Assert.fail()
}
}
@Test
fun dropTableTest() {
val sql =
"""
drop table if exists bigdata.tdl_small_files_2
"""
.trimIndent()
val statement = PrestoSqlHelper.parseStatement(sql)
if (statement is DropTable) {
Assert.assertEquals(StatementType.DROP_TABLE, statement.statementType)
Assert.assertEquals("bigdata", statement.tableId.schemaName)
Assert.assertEquals("tdl_small_files_2", statement.tableId.tableName)
} else {
Assert.fail()
}
}
@Test
fun insertTest() {
val sql =
"""
insert into orders select * from new_orders;
"""
.trimIndent()
val statement = PrestoSqlHelper.parseStatement(sql)
if (statement is InsertTable) {
Assert.assertEquals(StatementType.INSERT, statement.statementType)
Assert.assertEquals("orders", statement.tableId.tableName)
} else {
Assert.fail()
}
}
@Test
fun deleteTest() {
val sql =
"""
DELETE FROM lineitem WHERE orderkey IN (SELECT orderkey FROM orders WHERE priority = 'LOW');
"""
.trimIndent()
val statement = PrestoSqlHelper.parseStatement(sql)
if (statement is DeleteTable) {
Assert.assertEquals(StatementType.DELETE, statement.statementType)
Assert.assertEquals("lineitem", statement.tableId.tableName)
Assert.assertEquals(1, statement.inputTables.size)
} else {
Assert.fail()
}
}
}
================================================
FILE: superior-presto-parser/src/test/resources/log4j2.xml
================================================